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: 18/101
Findings: 1
Award: $34.50
π 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
34.5035 USDC - $34.50
User can rewrite the signature stored any number of times.
That's a violation of the desired system logic with no immediate loss of funds, so placing severity to be medium.
signAndClaim() don't control the signing status, so it can be run multiple times:
function signAndClaim( bytes calldata signature, address[] calldata cTokens, uint256[] calldata amounts, bytes32[][] calldata merkleProofs ) external override nonReentrant { // both sign and claim/multiclaim will revert on invalid signatures/proofs _sign(signature); _multiClaim(cTokens, amounts, merkleProofs); }
I.e. a user can rerun signAndClaim
many times for example with empty cTokens
and amounts
arrays as _multiClaim() will be a noop in this case:
// User provides the cTokens & the amounts they should get, and it is verified against the merkle root for that cToken (for each cToken provided) // Should set the user's claim amount in the claims mapping for each cToken provided function _multiClaim( address[] calldata _cTokens, uint256[] calldata _amounts, bytes32[][] calldata _merkleProofs ) internal virtual { require(_cTokens.length == _amounts.length, "Number of cTokens and amounts must match"); require(_cTokens.length == _merkleProofs.length, "Number of cTokens and merkle proofs must match"); for (uint256 i = 0; i < _cTokens.length; i++) { _claim(_cTokens[i], _amounts[i], _merkleProofs[i]); } // no events needed here, they happen in _claim }
Consider adding the hasNotSigned
modifier:
function signAndClaim( bytes calldata signature, address[] calldata cTokens, uint256[] calldata amounts, bytes32[][] calldata merkleProofs - ) external override nonReentrant { + ) external override hasNotSigned nonReentrant { // both sign and claim/multiclaim will revert on invalid signatures/proofs _sign(signature); _multiClaim(cTokens, amounts, merkleProofs); }
This way the behavior will be aligned with all other helper functions
#0 - kryptoklob
2022-09-13T06:55:33Z
This is low, as there are only two possible signatures that a user can provide, and both will still be valid, and it does not affect contract state or normal operation otherwise.
#1 - HickupHH3
2022-09-26T03:15:36Z
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-26T03:16:31Z
warden's primary QA