code4rena-2022-08-nounsdao-g04
[G‑04] Using calldata instead of memory for read-only arguments in external functions saves gas
Summary
calldata 로 선언해도 되는 array 변수를 memory로 선언하여 가스를 낭비한다고 지적했다. 이를 calldata로 변경하라고 제안했다.
Keyword
gas optimization, memory, calldata
Vulnerability
- contracts/governance/NounsDAOLogicV1.sol#L174-L180
- contracts/governance/NounsDAOLogicV2.sol#L184-L190
File: contracts/governance/NounsDAOLogicV1.sol
/// @audit targets
/// @audit values
/// @audit signatures
/// @audit calldatas
/// @audit description
174 function propose(
175 address[] memory targets,
176 uint256[] memory values,
177 string[] memory signatures,
178 bytes[] memory calldatas,
179 string memory description
180: ) public returns (uint256) {File: contracts/governance/NounsDAOLogicV2.sol
/// @audit targets
/// @audit values
/// @audit signatures
/// @audit calldatas
/// @audit description
184 function propose(
185 address[] memory targets,
186 uint256[] memory values,
187 string[] memory signatures,
188 bytes[] memory calldatas,
189 string memory description
190: ) public returns (uint256) {memory 로 array 파라미터를 받는 external 함수의 경우 해당 array의 인덱스를 for 루프로 돌며 하나하나 메모리에 복사하는 작업이 일어난다. for 루프를 한 번 돌 때마다 60 gas가 필요하므로 60 * <mem_array>.length 만큼의 gas가 든다. 파라미터를 memory 가 아닌 calldata로 선언하면 이러한 작업이 필요 없다.
internal 함수에 파라미터를 넘겨야 하는 경우 어차피 복사가 일어나지만, 이 경우에도 external은 calldata로 받는 것이 이득이다. modifier 등으로 인해 internal 함수가 호출되지 않고 취소되는 경우 불필요한 calldata → memory 변환이 일어나지 않기 때문이다.
Impact
calldata 로 선언해도 되는 array 변수를 memory로 선언하여 가스를 낭비한다.
Mitigation
memory 로 선언된 파라미터를 calldata로 변경한다.
tags: bughunting, nouns dao, smart contract, solidity, gas optimization, gas, solidity memory, solidity calldata, severity gas