dev/Solidity

deploying contract, Compiler specific version warnings

_April 2022. 5. 20. 00:27

첫 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/

 

Bug Concerning Data Location during Inheritance

On February 5th 2021, Nicolas Venturo reported a bug that allows overriding functions to change the data location of parameters from memory to calldata. The bug was introduced in Solidity 0.6.9 together with the ability to use calldata data location for al

blog.soliditylang.org

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 하는 습관을 들이자