code4rena-2022-08-nounsdao-g11
[G‑11] ++i/i++ should be unchecked{++i}/unchecked{i++} when it is not possible for them to overflow, as is the case when used in for- and while-loops
Summary
오버플로우 날 가능성이 없는 반복문 인덱스 연산은 unchecked 하여 가스를 줄일 수 있다 제안했다.
Keyword
gas optimization, safemath, unchecked
Vulnerability
File: contracts/governance/NounsDAOLogicV1.sol
281: for (uint256 i = 0; i < proposal.targets.length; i++) {
319: for (uint256 i = 0; i < proposal.targets.length; i++) {
346: for (uint256 i = 0; i < proposal.targets.length; i++) {
371: for (uint256 i = 0; i < proposal.targets.length; i++) {
File: contracts/governance/NounsDAOLogicV2.sol
292: for (uint256 i = 0; i < proposal.targets.length; i++) {
330: for (uint256 i = 0; i < proposal.targets.length; i++) {
357: for (uint256 i = 0; i < proposal.targets.length; i++) {
382: for (uint256 i = 0; i < proposal.targets.length; i++) {일반적으로 반복문은 for (uint256 i = 0; i < length; i++) 와 같이 이용된다. length의 타입이 동일하거나 i보다 작다면 i는 length보다 항상 작다. 따라서 대부분의 상황에서 i++ 나 ++i 연산 시 오버플로우가 발생하지 않는다.
solidity 0.8.0 부터는 기본적으로 연산에 safeMath가 적용된다. 이는 30~40 gas를 추가로 소모한다. 이는 unchecked를 이용하여 해제할 수 있다.
다음과 같이 unchecked로 인덱스를 업데이트 하면 가스를 절약할 수 있다. 아직 루프문에 바로 unchecked 문을 사용할 수 없어 함수로 빼거나 다음과 같이 해야 한다.
for (uint i ; i < length;) {
// do something that doesn't change the value of i
unchecked{
++i;
}
}Impact
for 루프를 돌 때마다 SafeMath를 체크하느라 30~40 gas가 낭비된다.
Mitigation
unchecked 를 이용하여 인덱스를 업데이트 한다.
tags: bughunting, nouns dao, smart contract, solidity, gas optimization, gas, solidity unchecked, solidity safemath, severity gas