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: 40/55
Findings: 1
Award: $118.73
🌟 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
118.7259 USDC - $118.73
Unbounded iteration / Gas Drainage, block stuffing, Griefing attacks :
The gravity contract : https://github.com/code-423n4/2022-05-cudos/blob/main/solidity/contracts/Gravity.sol
Have a function "testCheckValidatorSignatures" that checks the validity of signatures of multiple signatures with the address on batch mode with no limitation,
function testCheckValidatorSignatures( address[] memory _currentValidators, uint256[] memory _currentPowers, uint8[] memory _v, bytes32[] memory _r, bytes32[] memory _s, bytes32 _theHash, uint256 _powerThreshold ) public pure { checkValidatorSignatures( _currentValidators, _currentPowers, _v, _r, _s, _theHash, _powerThreshold ); }
As you can see it acceptes an array of addresses and data with no limitation, now as a malicious actor by calling that function (since it's public) with multiple data this will makes the contract consumes more gas from its level (not from user side) and this will later makes the contract ra out of gas, and will make the current block get stuffed (in case it passes the GAS limit set)
example :
call it as : testCheckValidatorSignatures(["0x00","0x00","0x00","0x00","0x00","0x00","0x00","0x00"],[1,1,1,1,1],[1,1,1,1,1],...etc)
notice the more objects you add into arrays the more gas is being consumed from the contract
fix : make the data bounded :
function testCheckValidatorSignatures( address[] memory _currentValidators, uint256[] memory _currentPowers, uint8[] memory _v, bytes32[] memory _r, bytes32[] memory _s, bytes32 _theHash, uint256 _powerThreshold ) public pure { require(_currentValidators, _currentPowers.length < 5,"please call a lower objects" && _v.length < 5,"please call a lower objects" && _r.length < 5,"please call a lower objects" && _s.length < 5,"please call a lower objects" && _theHash.length < 5,"please call a lower objects" && _powerThreshold.length < 5,"please call a lower objects" ) checkValidatorSignatures( _currentValidators, _currentPowers, _v, _r, _s, _theHash, _powerThreshold ); }
#0 - albertchon
2022-05-17T09:56:23Z
In practice this is limited by the finite number of validators on Tendermint based chains