The issue is that Rewards.updateRewardsForProposalWritingAndVoting can consume too much gas if there are too much clientId used for one proposal
Vulnerability Detail
In the following POC, if there are 1000 different clientIds are used for one proposal when calls NounsDAOVotes.castRefundableVote, the Rewards.updateRewardsForProposalWritingAndVoting will revert because the function will pass the gas limit of 30000000. If such case, Rewards.updateRewardsForProposalWritingAndVoting will be DOSed for ever because according to Rewards.sol#L323-L327, we can't skip lastProposalId.
Besides the issue above, if there are if there are 1000 different clientIds are used for one proposal, the function will consume more than 10k USD worth gas.
Put the following code under packages/nouns-contracts/test/foundry/rewards/ProposalRewardsMultiple.t.sol and run forge test --mc ProposalRewardsTestMultiple --mt test_stealRefundsGas -vv --ffi
As the output shows, 31154054 gas is used, which is larger than 30000000(gas limit for one block)
And also 3081850900000000000 wei eth is used, given that 1e18 wei eth worth 4000$, 3081850900000000000*4000 / 1e18 = 12327$
Running 1 test for test/foundry/rewards/ProposalRewardsMultiple.t.sol:ProposalRewardsTestMultiple
[PASS] test_stealRefundsGas() (gas: 109000988)
Logs:
erc20Mock.balanceOf(makeAddr('caller tx.origin')) : 3081850900000000000
gasUsed : 31154054
Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 396.43ms
Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests)
jasonxiale
medium
Rewards.updateRewardsForProposalWritingAndVoting
might consume too much gasSummary
In current implementation, function Rewards.updateRewardsForProposalWritingAndVoting will loop over
maxClientId
to find the clientId that is used in a proposal.The issue is that
Rewards.updateRewardsForProposalWritingAndVoting
can consume too much gas if there are too much clientId used for one proposalVulnerability Detail
In the following POC, if there are 1000 different clientIds are used for one proposal when calls NounsDAOVotes.castRefundableVote, the
Rewards.updateRewardsForProposalWritingAndVoting
will revert because the function will pass the gas limit of 30000000. If such case,Rewards.updateRewardsForProposalWritingAndVoting
will be DOSed for ever because according to Rewards.sol#L323-L327, we can't skiplastProposalId
.Besides the issue above, if there are if there are 1000 different clientIds are used for one proposal, the function will consume more than 10k USD worth gas.
Put the following code under
packages/nouns-contracts/test/foundry/rewards/ProposalRewardsMultiple.t.sol
and runforge test --mc ProposalRewardsTestMultiple --mt test_stealRefundsGas -vv --ffi
3081850900000000000 wei
eth is used, given that 1e18 wei eth worth 4000$, 3081850900000000000*4000 / 1e18 = 12327$Impact
Rewards.updateRewardsForProposalWritingAndVoting might consume too much gas
Code Snippet
https://github.com/sherlock-audit/2024-03-nouns-dao-2/blob/8f6879efaf831eb7fc9d4a4ad2b62b5334220d87/nouns-monorepo/packages/nouns-contracts/contracts/client-incentives/Rewards.sol#L307-L448
Tool used
Manual Review
Recommendation