티스토리 뷰
첫 NFT 를 이더리움 메인넷에 배포했다.
다행히 코인값도 떨어지고 가스비도 낮아서(15그웨이 고맙다)
적은부담으로 할수 있었다.
컨트랙트도 올리고 민팅도 잘되고
디자인도 이쁘게 나오고
이더스캔에도 컨트랙도 잘 올렸는데
이게 뭐람?
느낌표가 있길래 눌러봤더니
가능한 버그가 세개나? 이럴수가
열심히 디버깅한다고 했는데 이런 참사가..
싶어서 3개를 들여다 보았다.
다행히 very low-severity 라고 떠서 사소하긴하지만 신경쓰이잖아.
(1)DataLocationChangeInInternalOverride
(2)NestedCallataArrayAbiReencodingSizeValidation
(3)SignedImmutables
3종류가 떴다.
혹시나하고 다른 nft 프로젝트의 컨트랙트를봤는데
안-심
낮은 심각성의 warning 은 괜찮은듯 하다.
심지어 2종류는 나와 같다. 나는 (3)사인드이뮤터블즈가 더 있고
그래도 간략하게 맛보기를해보면
(1)DataLocationChangeInInternalOverride
It was possible to change the data location of the parameters or return variables from ``calldata`` to ``memory`` and vice- versa while overriding internal and public functions.
This caused invalid code to be generated when calling such a function internally through virtual function calls.
어렵다. 더 긴설명을 보자...
외부 함수를 호출할 때 매개 변수의 데이터 위치가 "call data" 또는 "memory"인 경우 데이터의 인코딩은 변경되지 않습니다. 따라서 외부 기능을 재정의할 때 데이터 위치를 변경할 수 있습니다. 컴파일러는 또한 공개 및 내부 함수를 재정의하기 위해 데이터 위치의 변경을 잘못 허용하였다. 공용 함수는 내부뿐만 아니라 외부에서도 호출될 수 있기 때문에, 이렇게 잘못 재정의된 함수가 기본 계약을 통해 내부적으로 호출될 때 유효하지 않은 코드가 생성된다. 호출자는 메모리 포인터를 제공하지만 호출된 함수는 호출 데이터 포인터로 해석하거나 그 반대로 해석한다.
먼소리고? 하고 예시를봤다.
https://blog.soliditylang.org/2022/05/17/data-location-inheritance-bug/
abstract contract I {
// The base contract uses "calldata"
function f(uint[] calldata x) virtual internal;
}
contract C is I {
// The derived contract uses "memory" and the compiler
// does not complain - this is the bug in the compiler.
function f(uint[] memory x) override internal {
// If you use `x`, it will access memory
// even if `D.g` passed us a calldata pointer.
// This leads to the wrong data being accessed.
}
}
abstract contract D is I {
function g(uint[] calldata x) external {
// Since D only "knows" `I`, the signature of `f`
// uses calldata, while the virtual lookup ends
// up with `C.f`, which uses memory. This results
// in the calldata pointer `x` being passed and
// interpreted as a memory pointer.
f(x);
}
}
contract X is C, D { }
이경우 C 가 잘못된 오버라이드를 했는데,
잘못된 C 를 extend 한 X 도 해당 에러가 난다.
나의경우 상속을 하지 않았기때문에.. C 처럼 잘못된 오버라이드를 했을거란 생각이 들었다.
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
내경우 오버라이드가 이뤄진 펑션은 이거 하나뿐이었는데,
openzeplin ERC721.sol 에 들어가서 오리지널을보았더니
function _baseURI() internal view virtual returns (string memory) {
return "";
}
같은데..?
의문이다.
(2)NestedCallataArrayAbiReencodingSizeValidation
ABI-re encoding of nested dynamic calldata arrays did not always perform
proper size checks against the size of calldata and could read beyond ``calldatasize()``.
https://blog.soliditylang.org/2022/05/17/calldata-reencode-size-check-bug/
You might be affected if you pass a nested array directly to another external function call or use abi.encode on it.
원인: merkleProof 변수가 nested array 형태인데 그걸 그대로 external function call 에서 불러서..
머클트리는 양보 못한다. 패스 ㅠ
(3)SignedImmutables
Immutable variables of signed integer type shorter than 256 bits can lead to values with invalid higher order bits if inline assembly is used.
https://blog.soliditylang.org/2021/09/29/signed-immutables-bug/
황당하다.. 256보다 짧은 사인드 인티저를 써서 문제가되었다.
왜 일어났는가?: So the only way (to our knowledge) to obtain the “unclean” value of the immutable is to first assign it to a local variable and then read from that local variable inside inline assembly.
내경우엔 어샘블리를 딱히 쓰지않았기때문에 이것도 미스테리
내생각엔 rinkeby 테스트넷에도 verify 를 했다면 이 버그들이 나왔을거라고 본다.
디플로이 전 verify 하는 습관을 들이자
'dev > Solidity' 카테고리의 다른 글
interact with existing deployed contracts, raw calls (0) | 2022.06.16 |
---|---|
Hardhat vs Truffle (0) | 2022.06.02 |
Merkle Tree - 솔리디티 화이트리스트 관리하기 (0) | 2022.04.24 |
Storage, Memory and Calldata (0) | 2022.03.27 |
Events (0) | 2022.03.15 |