code4rena-2022-08-nounsdao-g17

[G‑17] Usage of uints/ints smaller than 32 bytes (256 bits) incurs overhead

보고서

Summary

메모리에서 워드보다 작은 크기의 자료형을 이용하는 경우 이점은 없고 gas만 더 나가므로, 가능하면 워드 크기의 자료형을 이용하라고 제안했다.

Keyword

gas optimization, memory

Vulnerability

File: contracts/base/ERC721Checkpointable.sol
 
/// @audit uint32 upper
191:                  upper = center - 1;

컨트랙트에서 기본 워드 크기는 32바이트(256비트)이기 때문에, uint8같이 uint256보다 작은 크기의 자료형은 uint256에 비해 22~28 gas를 더 소비할 수 있다. 워드의 상위 비트를 지워야하기 때문이다. 차라리 큰 자료형을 이용한다면 gas 소비를 줄일 수 있다.

참고로 메모리 값이나 함수 파라미터에서 작은 크기의 자료형을 이용하는 경우에는 값을 압축하지 않기 때문에(slot 공유해 쓰기 등) 이점이 없다.

하지만 storage 변수의 경우 여러 요소를 slot에 압축하여 일기 또는 쓰기를 단일 작업으로 하기 때문에 작은 크기의 자료형을 사용하는 것도 의미가 있다. 단, 슬롯을 한꺼번에 읽고 쓰지 않는 경우 (struct이 아닌 별개의 변수라든가)에는 오히려 반대 효과가 발생할 수 있다.

참고

Impact

작은 크기 자료형의 이점은 없고, gas만 더 나간다.

Mitigation

가능하다면 메모리 상에서는 작은 크기의 자료형을 사용하지 않고 워드 크기(32바이트) 자료형을 이용한다.


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