code4rena-2022-08-nounsdao-g05

[G‑05] Using storage instead of memory for structs/arrays saves gas

보고서

Summary

struct/array의 전체 필드가 필요하지 않은 경우 굳이 memory에 복사하지 않고 storage를 그냥 이용하는 쪽이 낫다. 여러번 사용될 필드라면 그 필드만 stack variable에 캐싱하는 게 저렴하다.

Keyword

gas optimization, storage, memory

Vulnerability

File: contracts/governance/NounsDAOLogicV2.sol
 
952:              DynamicQuorumParamsCheckpoint memory cp = quorumParamsCheckpoints[center];

storage 의 데이터를 memory 변수로 가져오는 경우, struct/array에 있는 모든 필드를 읽어온다. 이 과정 중 각 struct/array 필드당 Gcoldsload(2100 gas)를 소모하게 된다. 이렇게 메모리에 복사한 변수를 이용하는 경우, 처음 읽을떄는 MLOAD를 이용하여 가스를 소모한다.

memory 변수로 복사하는 대신 storage 변수를 이용하고, 다시 읽을 필요가 있는 값의 경우 stack variable로 직접 캐싱하는 쪽이 더 저렴하다. (모든 필드를 이용할 게 아니라면)

전체 struct/array를 메모리 변수로 읽는 것이 의미가 있는 경우는 전체 struct/array를 리턴해야 하는 경우, memory로 파라미터를 넘겨받는 함수를 호출해야 하는 경우 등이 있다.

Impact

불필요한 필드까지 storagememory 복사하여 가스를 낭비한다.

Mitigation

struct/array를 복사하지 않고 storage 변수를 직접 이용한다. 여러번 사용되는 필드만 stack variable로 캐싱하여 사용한다.


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