Platform: Code4rena
Start Date: 09/09/2022
Pot Size: $42,000 USDC
Total HM: 2
Participants: 101
Period: 3 days
Judge: hickuphh3
Total Solo HM: 2
Id: 161
League: ETH
Rank: 52/101
Findings: 1
Award: $33.58
π Selected for report: 0
π Solo Findings: 0
π Selected for report: GalloDaSballo
Also found by: 0x040, 0x1f8b, 0x4non, 0x52, 0x85102, 0xNazgul, 0xSky, 0xSmartContract, Aymen0909, Bnke0x0, CertoraInc, Chandr, Chom, CodingNameKiki, Deivitto, Diana, Funen, JC, Jeiwan, Junnon, KIntern_NA, Lambda, Mohandes, Noah3o6, Ocean_Sky, Picodes, R2, Randyyy, RaymondFam, ReyAdmirado, Rohan16, Rolezn, Samatak, Sm4rty, SnowMan, SooYa, StevenL, Tagir2003, Tointer, TomJ, Tomo, V_B, Waze, _Adam, __141345__, a12jmx, ajtra, ak1, asutorufos, bharg4v, bobirichman, brgltd, c3phas, cccz, cryptonue, cryptostellar5, cryptphi, csanuragjain, d3e4, datapunk, delfin454000, dipp, djxploit, durianSausage, erictee, fatherOfBlocks, gogo, got_targ, hansfriese, horsefacts, hyh, ignacio, innertia, izhuer, karanctf, ladboy233, leosathya, lucacez, lukris02, mics, oyc_109, pashov, pauliax, prasantgupta52, rbserver, ret2basic, rfa, robee, rokinot, rotcivegaf, rvierdiiev, sach1r0, scaraven, sikorico, simon135, smiling_heretic, sorrynotsorry, unforgiven, wagmi, yixxas
33.5809 USDC - $33.58
This comment and existence of the testCannotSignTwice
test case makes it clear that intended behavior of the protocol is to prevent users from submitting a signature of MESSAGE_HASH
twice.
However, any user can circumvent this and overwrite once provided signature with another valid one.
Add the following test case to this file and run integration tests:
function testCanSignTwice() public { vm.startPrank(addresses[0]); IERC20(cToken0).approve(address(redeemer), 100_000_000e18); (uint8 v0, bytes32 r0, bytes32 s0) = vm.sign(keys[0], redeemer.MESSAGE_HASH()); bytes memory signature0 = bytes.concat(r0, s0, bytes1(v0)); redeemer.sign(signature0); address[] memory cTokens; uint256[] memory amounts; bytes32[][] memory merkleProofs; // vm.expectRevert("User has already signed"); redeemer.signAndClaim(signature0, cTokens, amounts, merkleProofs); vm.stopPrank(); }
As we can see, signAndClaim
doesn't revert despite non-zero userSignatures[msg.sender]
because of the missing hasNotSigned
modifier. Moreover, when arguments passed to redeemer.signAndClaim
are a signature and empty lists, then this function effectively behaves just like _sign
.
Foundry
Add missing hasNotSigned
modifier to the redeemer.signAndClaim
function.
#0 - kryptoklob
2022-09-19T23:39:57Z
Good find. Marking this as the primary issue as there are several duplicates. Disagree with severity as it does not affect any state adversely on-chain, though it is unintended behavior - should be low sev.
#1 - HickupHH3
2022-09-26T06:34:24Z
Reproducing my comment in #233 here:
Agree with wardens that it is inconsistent behaviour, but I agree that the severity is low because there isn't an adverse impact apart from deviant behaviour and multiple emissions of the Signed() event.
#2 - HickupHH3
2022-09-26T06:35:23Z
Warden's primary QA