packages feed

hevm-0.50.0: test/contracts/pass/constantinople.sol

import "ds-test/test.sol";

contract DeadCode{
    function dummy() external returns (uint256) {}
}

contract ConstantinopleTests is DSTest {
    DeadCode notmuch;
    function setUp() public {
      notmuch = new DeadCode();
    }

    // this 5 byte-long initcode simply returns nothing
    // PUSH1  00     PUSH1  00     RETURN
    // 60     00     60     00     f3
    bytes32 zerocode        = 0x60006000f3000000000000000000000000000000000000000000000000000000;
    // this 13 byte-long initcode simply returns 0xdeadbeef:
    // PUSH4  de     ad     be     ef     PUSH1  00     MSTORE PUSH1  32     PUSH1  00     RETURN
    // 63     de     ad     be     ef     60     00     52     60     20     60     00     f3
    bytes32 deadcode        = 0x63deadbeef60005260206000f300000000000000000000000000000000000000;
    // this 25 byte-long initcode returns deadcode (but without the padding)
    // PUSH1  0d     PUSH1  0c     PUSH1  00     CODECO PUSH1  0d     PUSH1  00     RETURN deadcode
    // 60     0d     60     0c     60     00     39     60     0d     60     00     f3
    bytes32 deploysdeadcode = 0x600d600c600039600d6000f363deadbeef60005260206000f300000000000000;

    // EXTCODEHASH of non-existent account is 0
    function test_extcodehash_1() public {
        uint256 h;
        assembly {
            h := extcodehash(0x10)
        }
        assertEq(h, 0);
    }
    // EXTCODEHASH of account with no code is keccak256("")
    function test_extcodehash_2() public {
        address a;
        uint256 h;
        assembly {
            let top := mload(0x40)
            mstore(top, sload(zerocode.slot))
            a := create(0, top, 5)
            h := extcodehash(a)
        }
        assertEq(h, 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470);
    }
    // EXTCODEHASH of account with code 0xdeadbeef is keccak256(0xdeadbeef)
    function test_extcodehash_3() public {
        address a;
        uint256 h;

        assembly {
          let top := mload(0x40)
          mstore(top, sload(deadcode.slot))
          a := create(0, top, 13)
          h := extcodehash(a)
        }

        uint256 expected_h;
        assembly {
            let top := mload(0x40)
            mstore(top, 0xdeadbeef)
            expected_h := keccak256(top, 32)
        }
        assertEq(h, expected_h);
    }
    // EXTCODEHASH of the notmuch contract should be same as
    // doing EXTCODECOPY and then keccak256
    function test_extcodehash_4() public {
        address a = address(notmuch);
        uint256 h;

        assembly {
            h := extcodehash(a)
        }

        uint256 expected_h;
        assembly {
            let top := mload(0x40)
            let size := extcodesize(a)
            extcodecopy(a, top, 0, size)
            expected_h := keccak256(top, size)
        }
        assertEq(h, expected_h);
    }

    // address of account created by CREATE2 is
    // keccak256(0xff + address + salt + keccak256(init_code))[12:]
    function test_create2_1() public {
        address a;
        uint256 salt = 0xfacefeed;
        assembly {
          let top := mload(0x40)
          mstore(top, sload(deadcode.slot))
          a := create2(0, top, 13, salt)
        }

        address expected_a;

        assembly {
          let top := mload(0x40)
          mstore(top, sload(deadcode.slot))
          let inithash := keccak256(top, 13)
          mstore(sub(top, 11), address())
          mstore8(top, 0xff)
          mstore(add(top, 21), salt)
          mstore(add(top, 53), inithash)
          expected_a := and(keccak256(top, 85), 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff)
        }

        assertEq(a, expected_a);
    }
    // calling a CREATE2 contract works as expected
    function test_create2_2() public {
        address a;
        uint256 salt = 0xfacefeed;
        assembly {
          let top := mload(0x40)
          mstore(top, sload(deploysdeadcode.slot))
          a := create2(0, top, 25, salt)
        }

        assertEq(DeadCode(a).dummy(), 0xdeadbeef);
    }
    // TODO: test some SELFDESTRUCT properties of CREATE2
    // TODO: test EXTCODEHASH on self-destructed contract
    // TODO: test EXTCODEHASH on precompiled contracts

    // SHL, SHR and SAR tests taken from
    // https://github.com/ethereum/EIPs/blob/fde32dfd6b24bac7bfabf6c1ebe3f5a603d5ff4c/EIPS/eip-145.md
    function test_shl() public {
        uint z;

        assembly {
            z := shl(0x00, 0x0000000000000000000000000000000000000000000000000000000000000001)
        }
        assertEq(z, 0x0000000000000000000000000000000000000000000000000000000000000001);

        assembly {
            z := shl(0x01, 0x0000000000000000000000000000000000000000000000000000000000000001)
        }
        assertEq(z, 0x0000000000000000000000000000000000000000000000000000000000000002);

        assembly {
            z := shl(0xff, 0x0000000000000000000000000000000000000000000000000000000000000001)
        }
        assertEq(z, 0x8000000000000000000000000000000000000000000000000000000000000000);

        assembly {
            z := shl(0x0100, 0x0000000000000000000000000000000000000000000000000000000000000001)
        }
        assertEq(z, 0x0000000000000000000000000000000000000000000000000000000000000000);

        assembly {
            z := shl(0x0101, 0x0000000000000000000000000000000000000000000000000000000000000001)
        }
        assertEq(z, 0x0000000000000000000000000000000000000000000000000000000000000000);

        assembly {
            z := shl(0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(z, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);

        assembly {
            z := shl(0x01, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(z, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe);

        assembly {
            z := shl(0xff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(z, 0x8000000000000000000000000000000000000000000000000000000000000000);

        assembly {
            z := shl(0x0100, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(z, 0x0000000000000000000000000000000000000000000000000000000000000000);

        assembly {
            z := shl(0x01, 0x0000000000000000000000000000000000000000000000000000000000000000)
        }
        assertEq(z, 0x0000000000000000000000000000000000000000000000000000000000000000);

        assembly {
            z := shl(0x01, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(z, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe);
    }

    function test_shr() public {
        uint z;

        assembly {
            z := shr(0x00, 0x0000000000000000000000000000000000000000000000000000000000000001)
        }
        assertEq(z, 0x0000000000000000000000000000000000000000000000000000000000000001);

        assembly {
            z := shr(0x01, 0x0000000000000000000000000000000000000000000000000000000000000001)
        }
        assertEq(z, 0x0000000000000000000000000000000000000000000000000000000000000000);

        assembly {
            z := shr(0x01, 0x8000000000000000000000000000000000000000000000000000000000000000)
        }
        assertEq(z, 0x4000000000000000000000000000000000000000000000000000000000000000);

        assembly {
            z := shr(0xff, 0x8000000000000000000000000000000000000000000000000000000000000000)
        }
        assertEq(z, 0x0000000000000000000000000000000000000000000000000000000000000001);

        assembly {
            z := shr(0x0100, 0x8000000000000000000000000000000000000000000000000000000000000000)
        }
        assertEq(z, 0x0000000000000000000000000000000000000000000000000000000000000000);

        assembly {
            z := shr(0x0101, 0x8000000000000000000000000000000000000000000000000000000000000000)
        }
        assertEq(z, 0x0000000000000000000000000000000000000000000000000000000000000000);

        assembly {
            z := shr(0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(z, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);

        assembly {
            z := shr(0x01, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(z, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);

        assembly {
            z := shr(0xff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(z, 0x0000000000000000000000000000000000000000000000000000000000000001);

        assembly {
            z := shr(0x0100, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(z, 0x0000000000000000000000000000000000000000000000000000000000000000);

        assembly {
            z := shr(0x01, 0x0000000000000000000000000000000000000000000000000000000000000000)
        }
        assertEq(z, 0x0000000000000000000000000000000000000000000000000000000000000000);
    }

    function test_sar() public {
        uint z;

        assembly {
            z := sar(0x00, 0x0000000000000000000000000000000000000000000000000000000000000001)
        }
        assertEq(bytes32(z), bytes32(0x0000000000000000000000000000000000000000000000000000000000000001));

        assembly {
            z := sar(0x01, 0x0000000000000000000000000000000000000000000000000000000000000001)
        }
        assertEq(bytes32(z), bytes32(0x0000000000000000000000000000000000000000000000000000000000000000));

        assembly {
            z := sar(0x01, 0x8000000000000000000000000000000000000000000000000000000000000000)
        }
        assertEq(bytes32(z), bytes32(0xc000000000000000000000000000000000000000000000000000000000000000));

        assembly {
            z := sar(0xff, 0x8000000000000000000000000000000000000000000000000000000000000000)
        }
        assertEq(bytes32(z), bytes32(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff));

        assembly {
            z := sar(0x0100, 0x8000000000000000000000000000000000000000000000000000000000000000)
        }
        assertEq(bytes32(z), bytes32(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff));

        assembly {
            z := sar(0x0101, 0x8000000000000000000000000000000000000000000000000000000000000000)
        }
        assertEq(bytes32(z), bytes32(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff));

        assembly {
            z := sar(0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(bytes32(z), bytes32(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff));

        assembly {
            z := sar(0x01, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(bytes32(z), bytes32(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff));

        assembly {
            z := sar(0xff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(bytes32(z), bytes32(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff));

        assembly {
            z := sar(0x0100, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(bytes32(z), bytes32(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff));

        assembly {
            z := sar(0x01, 0x0000000000000000000000000000000000000000000000000000000000000000)
        }
        assertEq(bytes32(z), bytes32(0x0000000000000000000000000000000000000000000000000000000000000000));

        assembly {
            z := sar(0xfe, 0x4000000000000000000000000000000000000000000000000000000000000000)
        }
        assertEq(bytes32(z), bytes32(0x0000000000000000000000000000000000000000000000000000000000000001));

        assembly {
            z := sar(0xf8, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(bytes32(z), bytes32(0x000000000000000000000000000000000000000000000000000000000000007f));

        assembly {
            z := sar(0xfe, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(bytes32(z), bytes32(0x0000000000000000000000000000000000000000000000000000000000000001));

        assembly {
            z := sar(0xff, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(bytes32(z), bytes32(0x0000000000000000000000000000000000000000000000000000000000000000));

        assembly {
            z := sar(0x0100, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
        }
        assertEq(bytes32(z), bytes32(0x0000000000000000000000000000000000000000000000000000000000000000));
    }
}