Platform: Code4rena
Start Date: 31/10/2023
Pot Size: $60,500 USDC
Total HM: 9
Participants: 65
Period: 10 days
Judge: gzeon
Total Solo HM: 2
Id: 301
League: ETH
Rank: 59/65
Findings: 1
Award: $23.81
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xVolcano
Also found by: 0x11singh99, 0xAnah, 0xhacksmithh, 0xhex, 0xta, DavidGiladi, K42, Topmark, arjun16, dharma09, hunter_w3b, lsaudit, pavankv, tabriz, tala7985, ybansal2403
23.8054 USDC - $23.81
uint256 private constant _STORAGE_SLOT = uint256(keccak256("ProposalExecutionEngine.Storage"));
uint256 private constant SHARED_STORAGE_SLOT = uint256(keccak256("ProposalStorage.SharedProposalStorage"));
uint256 private constant _SET_SIGNATURE_VALIDATOR_PROPOSAL_STORAGE_SLOT = uint256(keccak256("SetSignatureValidatorProposal.Storage"));
The risk of for loops getting overflowed is extremely low. Because it always increments by 1 and is limited to the arrays length. Even if the arrays are extremely long, it will take a massive amount of time and gas to let the for loop overflow.
for (uint256 i; i < numContributions; ++i) { ethAvailable -= args.values[i]; votingPowers[i] = _contribute( payable(msg.sender), args.delegate, args.values[i], args.tokenIds[i], args.gateDatas[i] ); }
for (uint256 i; i < args.recipients.length; ++i) { votingPowers[i] = _contribute( args.recipients[i], args.initialDelegates[i], args.values[i], args.tokenIds[i], args.gateDatas[i] ); valuesSum += args.values[i]; }
for (uint256 i; i < numRefunds; ++i) { (bool s, bytes memory r) = address(this).call( abi.encodeCall(this.refund, (tokenIds[i])) );
for (uint i = 0; i < authoritiesLength - 1; ++i) { authorities[i] = opts.authorities[i]; }
for (uint256 i; i < withdrawTokens.length; ++i) { // Check if order of tokens to transfer is valid. // Prevent null and duplicate transfers. if (prevToken >= withdrawTokens[i]) revert InvalidTokenOrderError(); prevToken = withdrawTokens[i]; // Check token's balance. uint256 balance = address(withdrawTokens[i]) == ETH_ADDRESS ? address(this).balance : withdrawTokens[i].balanceOf(address(this)); // Add fair share of tokens from the party to total. for (uint256 j; j < tokenIds.length; ++j) { // Must be retrieved before burning the token. withdrawAmounts[i] += (balance * getVotingPowerShareOf(tokenIds[j])) / 1e18; } }
preciousTokenIds is timestamp thus changing it to uint64 should be safe for around 532 years.
uint256[] preciousTokenIds; // The timestamp until which ragequit is enabled.
Caching a mapping’s value in a storage pointer when the value is accessed multiple times saves ~40 gas per access due to not having to perform the same offset calculation every time. Help the Optimizer by saving a storage variable’s reference instead of repeatedly fetching it. To achieve this, declare a storage pointer for the variable and use it instead of repeatedly fetching the reference in a map or an array.
mapping(address => VotingPowerSnapshot[]) private _votingPowerSnapshotsByVoter;
Instead of using address(this) , it is more gas-efficient to pre-calculate and use the hardcoded address . Foundry’s script.sol and solmate’s LibRlp.sol contracts can help achieve this. References: https://book.getfoundry.sh/reference/forge-std/compute-create-address https://twitter.com/transmissions11/status/1518507047943245824
(bool s, bytes memory r) = address(this).call(
authorities[authoritiesLength - 1] = address(this);
if (msg.sender != address(this)) {
Party(payable(address(this))),
if (msg.sender != address(this)) {
? address(this).balance : withdrawTokens[i].balanceOf(address(this));
constructor() { implementation = address(this); } // Reverts if the current function context is not inside of a delegatecall. modifier onlyDelegateCall() virtual { if (address(this) == implementation) { revert OnlyDelegateCallError(); }
variable == false
instead of !variable
.a bit cheapier when you replace:
if (!_gateKeeper.isAllowed(msg.sender, gateKeeperId, gateData)) {
if (!s) {
if (!completed) {
if (!success) {
if (!success) {
if (!success) {
if (!s) {
#0 - c4-pre-sort
2023-11-13T06:55:58Z
ydspa marked the issue as sufficient quality report
#1 - c4-judge
2023-11-19T18:24:52Z
gzeon-c4 marked the issue as grade-b