code4rena-2022-08-nounsdao-g16

[G‑16] Splitting require() statements that use && saves gas

보고서

Summary

가능한 경우 require 문의 && 연산을 쪼개서 require문을 분리하면 런타임에 gas를 절약할 수 있다.

Keyword

gas optimization, require

Vulnerability

File: contracts/governance/NounsDAOLogicV1.sol
 
126           require(
127               votingPeriod_ >= MIN_VOTING_PERIOD && votingPeriod_ <= MAX_VOTING_PERIOD,
128               'NounsDAO::initialize: invalid voting period'
129:          );
 
130           require(
131               votingDelay_ >= MIN_VOTING_DELAY && votingDelay_ <= MAX_VOTING_DELAY,
132               'NounsDAO::initialize: invalid voting delay'
133:          );
 
134           require(
135               proposalThresholdBPS_ >= MIN_PROPOSAL_THRESHOLD_BPS && proposalThresholdBPS_ <= MAX_PROPOSAL_THRESHOLD_BPS,
136               'NounsDAO::initialize: invalid proposal threshold'
137:          );
 
138           require(
139               quorumVotesBPS_ >= MIN_QUORUM_VOTES_BPS && quorumVotesBPS_ <= MAX_QUORUM_VOTES_BPS,
140               'NounsDAO::initialize: invalid proposal threshold'
141:          );
 
191           require(
192               targets.length == values.length &&
193                   targets.length == signatures.length &&
194                   targets.length == calldatas.length,
195               'NounsDAO::propose: proposal function information arity mismatch'
196:          );
 
531           require(
532               newVotingDelay >= MIN_VOTING_DELAY && newVotingDelay <= MAX_VOTING_DELAY,
533               'NounsDAO::_setVotingDelay: invalid voting delay'
534:          );
 
547           require(
548               newVotingPeriod >= MIN_VOTING_PERIOD && newVotingPeriod <= MAX_VOTING_PERIOD,
549               'NounsDAO::_setVotingPeriod: invalid voting period'
550:          );
 
564           require(
565               newProposalThresholdBPS >= MIN_PROPOSAL_THRESHOLD_BPS &&
566                   newProposalThresholdBPS <= MAX_PROPOSAL_THRESHOLD_BPS,
567               'NounsDAO::_setProposalThreshold: invalid proposal threshold'
568:          );
 
582           require(
583               newQuorumVotesBPS >= MIN_QUORUM_VOTES_BPS && newQuorumVotesBPS <= MAX_QUORUM_VOTES_BPS,
584               'NounsDAO::_setProposalThreshold: invalid proposal threshold'
585:          );
 
617:          require(msg.sender == pendingAdmin && msg.sender != address(0), 'NounsDAO::_acceptAdmin: pending admin only');
File: contracts/governance/NounsDAOLogicV2.sol
 
137           require(
138               votingPeriod_ >= MIN_VOTING_PERIOD && votingPeriod_ <= MAX_VOTING_PERIOD,
139               'NounsDAO::initialize: invalid voting period'
140:          );
 
141           require(
142               votingDelay_ >= MIN_VOTING_DELAY && votingDelay_ <= MAX_VOTING_DELAY,
143               'NounsDAO::initialize: invalid voting delay'
144:          );
 
145           require(
146               proposalThresholdBPS_ >= MIN_PROPOSAL_THRESHOLD_BPS && proposalThresholdBPS_ <= MAX_PROPOSAL_THRESHOLD_BPS,
147               'NounsDAO::initialize: invalid proposal threshold bps'
148:          );
 
201           require(
202               targets.length == values.length &&
203                   targets.length == signatures.length &&
204                   targets.length == calldatas.length,
205               'NounsDAO::propose: proposal function information arity mismatch'
206:          );
 
623           require(
624               newVotingDelay >= MIN_VOTING_DELAY && newVotingDelay <= MAX_VOTING_DELAY,
625               'NounsDAO::_setVotingDelay: invalid voting delay'
626:          );
 
639           require(
640               newVotingPeriod >= MIN_VOTING_PERIOD && newVotingPeriod <= MAX_VOTING_PERIOD,
641               'NounsDAO::_setVotingPeriod: invalid voting period'
642:          );
 
656           require(
657               newProposalThresholdBPS >= MIN_PROPOSAL_THRESHOLD_BPS &&
658                   newProposalThresholdBPS <= MAX_PROPOSAL_THRESHOLD_BPS,
659               'NounsDAO::_setProposalThreshold: invalid proposal threshold bps'
660:          );
 
677           require(
678               newMinQuorumVotesBPS >= MIN_QUORUM_VOTES_BPS_LOWER_BOUND &&
679                   newMinQuorumVotesBPS <= MIN_QUORUM_VOTES_BPS_UPPER_BOUND,
680               'NounsDAO::_setMinQuorumVotesBPS: invalid min quorum votes bps'
681:          );
 
819:          require(msg.sender == pendingAdmin && msg.sender != address(0), 'NounsDAO::_acceptAdmin: pending admin only');

&& 연산자로 여러 조건을 묶어서 require 문을 작성하는 것보다 이를 쪼개서 각각 작성하는 게 배포시에는 gas가 더 들지만, 런타임에는 gas 효율적이라고 한다. && 를 이용하는 경우 연산자 당 3 gas가 더 든다고 한다.

Impact

require문 실행시 gas가 더 든다.

Mitigation

가능한 경우 require 문의 && 연산을 쪼개서 require문을 분리한다.


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