code4rena-2022-08-nounsdao-g21

[G‑21] require() or revert() statements that check input arguments should be at the top of the function

보고서

Summary

storage 를 불러오는 등의 작업을 하기 전에 constant 와의 비교(require)를 가장 먼저 하여 revert 시에도 gas를 낭비하지 않도록 하자 제안했다.

Keyword

gas optimization, storage, constant

Vulnerability

File: contracts/governance/NounsDAOLogicV1.sol
 
/// @audit expensive op on line 501
501:          require(state(proposalId) == ProposalState.Active, 'NounsDAO::castVoteInternal: voting is closed');
502:          require(support <= 2, 'NounsDAO::castVoteInternal: invalid vote type');
File: contracts/governance/NounsDAOLogicV2.sol
 
/// @audit expensive op on line 593
593:          require(state(proposalId) == ProposalState.Active, 'NounsDAO::castVoteInternal: voting is closed');
594:          require(support <= 2, 'NounsDAO::castVoteInternal: invalid vote type');
 
/// @audit expensive op on line 703
703:          require(msg.sender == admin, 'NounsDAO::_setMaxQuorumVotesBPS: admin only');
704:          DynamicQuorumParams memory params = getDynamicQuorumParamsAt(block.number);
705           require(
706               newMaxQuorumVotesBPS <= MAX_QUORUM_VOTES_BPS_UPPER_BOUND,
707               'NounsDAO::_setMaxQuorumVotesBPS: invalid max quorum votes bps'
708:          );

require문, 특히 constant 를 이용하여 input validation을 체크하는 require문은 가장 먼저 하는 게 좋다. storage 변수를 불러와서 비교하는 등의 더 큰 작업을 하기 전에 체크하면 실패시에도 gas를 절약할 수 있기 때문이다.

Impact

storage를 불러온 뒤 require문을 비교하여 실패시에 gas를 낭비한다.

Mitigation

constant 와의 비교(require)를 가장 먼저 한다.


tags: bughunting, nouns dao, smart contract, solidity, gas optimization, severity gas