Platform: Code4rena
Start Date: 03/05/2022
Pot Size: $75,000 USDC
Total HM: 6
Participants: 55
Period: 7 days
Judge: Albert Chon
Total Solo HM: 2
Id: 116
League: COSMOS
Rank: 28/55
Findings: 2
Award: $204.33
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0x1337, 0x1f8b, 0xDjango, 0xkatana, AmitN, CertoraInc, Dravee, Funen, GermanKuber, GimelSec, Hawkeye, JC, MaratCerby, WatchPug, Waze, broccolirob, cccz, ch13fd357r0y3r, cryptphi, danb, defsec, delfin454000, dipp, dirk_y, ellahi, gzeon, hake, hubble, ilan, jah, jayjonah8, kebabsec, kirk-baird, m9800, orion, oyc_109, robee, shenwilly, simon135, sorrynotsorry
138.0099 USDC - $138.01
cumulativePower can overflow such that total powers is more than cumulativePower
cumulativePower = cumulativePower + _powers[i];
ecrecover return 0 for invalid signature
function verifySig( address _signer, bytes32 _theHash, uint8 _v, bytes32 _r, bytes32 _s ) private pure returns (bool) { bytes32 messageDigest = keccak256( abi.encodePacked("\x19Ethereum Signed Message:\n32", _theHash) ); return _signer == ecrecover(messageDigest, _v, _r, _s); }
pragma solidity ^0.6.6;
pragma solidity ^0.6.6;
pragma solidity 0.6.12;
#0 - V-Staykov
2022-05-10T14:55:20Z
Unsafe cumulativePower math - on the cosmos side the comulative total power will never pass 10B, so we don't fear overflow here.
🌟 Selected for report: GermanKuber
Also found by: 0v3rf10w, 0x1f8b, 0xDjango, 0xNazgul, 0xf15ers, 0xkatana, AlleyCat, CertoraInc, Dravee, Funen, GimelSec, IllIllI, JC, MaratCerby, WatchPug, Waze, defsec, delfin454000, ellahi, gzeon, hake, hansfriese, ilan, jonatascm, nahnah, oyc_109, peritoflores, rfa, robee, simon135, slywaters, sorrynotsorry
66.3179 USDC - $66.32
uint256 MAX_UINT = 2**256 - 1;
// These are set once at initialization bytes32 public state_gravityId; uint256 public state_powerThreshold; CudosAccessControls public cudosAccessControls;
Here is an example but there are multiple occurrence https://github.com/code-423n4/2022-05-cudos/blob/de39cf3cd1f1e1cf211819b06d4acf6a043acda0/solidity/contracts/Gravity.sol#L583-L592
Change the code into
// LOGS scoped to reduce stack depth { uint 256 _state_lastEventNonce = state_lastEventNonce.add(1); state_lastEventNonce = _state_lastEventNonce; emit LogicCallEvent( _args.invalidationId, _args.invalidationNonce, returnData, _state_lastEventNonce ); }
using ++i save gas against i++
contracts/Gravity.sol:128: for (uint256 i = 0; i < _users.length; i++) { contracts/Gravity.sol:233: for (uint256 i = 0; i < _currentValidators.length; i++) { contracts/Gravity.sol:263: for (uint256 i = 0; i < _newValset.validators.length; i++) { contracts/Gravity.sol:453: for (uint256 i = 0; i < _amounts.length; i++) { contracts/Gravity.sol:568: for (uint256 i = 0; i < _args.transferAmounts.length; i++) { contracts/Gravity.sol:579: for (uint256 i = 0; i < _args.feeAmounts.length; i++) { contracts/Gravity.sol:660: for (uint256 i = 0; i < _powers.length; i++) {
Cache array length to reduce MLOADs, e.g.
uint256 arrlen = _users.length; for (uint256 i = 0; i < arrlen; i++)
contracts/Gravity.sol:128: for (uint256 i = 0; i < _users.length; i++) { contracts/Gravity.sol:233: for (uint256 i = 0; i < _currentValidators.length; i++) { contracts/Gravity.sol:263: for (uint256 i = 0; i < _newValset.validators.length; i++) { contracts/Gravity.sol:453: for (uint256 i = 0; i < _amounts.length; i++) { contracts/Gravity.sol:568: for (uint256 i = 0; i < _args.transferAmounts.length; i++) { contracts/Gravity.sol:579: for (uint256 i = 0; i < _args.feeAmounts.length; i++) { contracts/Gravity.sol:660: for (uint256 i = 0; i < _powers.length; i++) {
contracts/Gravity.sol:349: state_lastEventNonce = state_lastEventNonce.add(1); contracts/Gravity.sol:465: state_lastEventNonce = state_lastEventNonce.add(1); contracts/Gravity.sol:585: state_lastEventNonce = state_lastEventNonce.add(1); contracts/Gravity.sol:601: state_lastEventNonce = state_lastEventNonce.add(1); contracts/Gravity.sol:621: state_lastEventNonce = state_lastEventNonce.add(1);
require( _currentValset.validators.length == _currentValset.powers.length && _currentValset.validators.length == _v.length && _currentValset.validators.length == _r.length && _currentValset.validators.length == _s.length, "Malformed current validator set" );
Consider upgrade to latest 0.8.12 for various gas saving