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

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