---
# System prepended metadata

title: ERC721 precompile

---

# ERC721 precompile 

Using address at 'nft', it works well. Find more [here](https://github.com/cennznet/wiki/blob/spike/precompileERC721/EVM/ERC721-precompile.md)

Test contract to use ERC721 precompile on CENNZnet chain.


```
pragma solidity ^0.8.13;
import "@openzeppelin/contracts/interfaces/IERC721.sol";
import "@openzeppelin/contracts/interfaces/IERC165.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";


contract Test {

    address nft = 0xaAAAaaAA00000000000000000000000000000000;

    function balanceOfProxy(address who) public view returns (uint256) {
        return IERC721(nft).balanceOf(who);
    }

    function ownerOfProxy(uint256 tokenId) public view returns (address) {
        return IERC721(nft).ownerOf(tokenId);
    }

    function nameOfNFT() public view returns (string memory) {
        return IERC721Metadata(nft).name();
    }

    function symbolOfNFT() public view returns (string memory) {
        return IERC721Metadata(nft).symbol();
    }

    function tokenURIOfNFT(uint256 serial_number) public view returns (string memory) {
        return IERC721Metadata(nft).tokenURI(serial_number);
    }
    
    
    function transferFromProxy(
        uint256 serial_number
    ) external {
        IERC721(nft).transferFrom(0x89A1421e1482FA467F6E2FBC4decBaE8a4A6A065, msg.sender, serial_number);
    }

     function approveFromProxy(
        uint256 serial_number
    ) external {
       IERC721(nft).approve(address(this), serial_number);
    }
}
```

Calling within a smart contract transaction, fails with error 
***VM Exception while processing transaction: revert***

Investigation till now

Revert is due to invalid opcode while executing the transaction.

https://medium.com/@cpluser/how-evm-opcodes-run-in-sputnikvm-rust-part-1-6dbe74fd0190 provides more information on how opcodes run in rust 

The compiled EVM byte code for NFT contract looks like

```
solc --bin --asm test-ts/contracts/NFT.sol

======= test-ts/contracts/NFT.sol:IERC721 =======
EVM assembly:

Binary:


======= test-ts/contracts/NFT.sol:NFT =======
EVM assembly:
    /* "test-ts/contracts/NFT.sol":335:852  contract NFT {... */
  mstore(0x40, 0x80)
    /* "test-ts/contracts/NFT.sol":491:533  0xaAAAaaAA00000000000000000000000000000000 */
  0xaaaaaaaa00000000000000000000000000000000
    /* "test-ts/contracts/NFT.sol":477:533  address nft = 0xaAAAaaAA00000000000000000000000000000000 */
  0x00
  dup1
  0x0100
  exp
  dup2
  sload
  dup2
  0xffffffffffffffffffffffffffffffffffffffff
  mul
  not
  and
  swap1
  dup4
  0xffffffffffffffffffffffffffffffffffffffff
  and
  mul
  or
  swap1
  sstore
  pop
    /* "test-ts/contracts/NFT.sol":335:852  contract NFT {... */
  callvalue
  dup1
  iszero
  tag_1
  jumpi
  0x00
  dup1
  revert
tag_1:
  pop
  dataSize(sub_0)
  dup1
  dataOffset(sub_0)
  0x00
  codecopy
  0x00
  return
stop

sub_0: assembly {
        /* "test-ts/contracts/NFT.sol":335:852  contract NFT {... */
      mstore(0x40, 0x80)
      callvalue
      dup1
      iszero
      tag_1
      jumpi
      0x00
      dup1
      revert
    tag_1:
      pop
      jumpi(tag_2, lt(calldatasize, 0x04))
      shr(0xe0, calldataload(0x00))
      dup1
      0x2b2cf0df
      eq
      tag_3
      jumpi
      dup1
      0x382904fa
      eq
      tag_4
      jumpi
    tag_2:
      0x00
      dup1
      revert
        /* "test-ts/contracts/NFT.sol":711:850  function approveFromProxy(address to,... */
    tag_3:
      tag_5
      0x04
      dup1
      calldatasize
      sub
      dup2
      add
      swap1
      tag_6
      swap2
      swap1
      tag_7
      jump      // in
    tag_6:
      tag_8
      jump      // in
    tag_5:
      stop
        /* "test-ts/contracts/NFT.sol":540:705  function transferFromProxy(address to, address from,... */
    tag_4:
      tag_9
      0x04
      dup1
      calldatasize
      sub
      dup2
      add
      swap1
      tag_10
      swap2
      swap1
      tag_11
      jump      // in
    tag_10:
      tag_12
      jump      // in
    tag_9:
      stop
        /* "test-ts/contracts/NFT.sol":711:850  function approveFromProxy(address to,... */
    tag_8:
        /* "test-ts/contracts/NFT.sol":812:815  nft */
      0x00
      dup1
      sload
      swap1
      0x0100
      exp
      swap1
      div
      0xffffffffffffffffffffffffffffffffffffffff
      and
        /* "test-ts/contracts/NFT.sol":804:824  IERC721(nft).approve */
      0xffffffffffffffffffffffffffffffffffffffff
      and
      0x095ea7b3
        /* "test-ts/contracts/NFT.sol":825:827  to */
      dup4
        /* "test-ts/contracts/NFT.sol":829:842  serial_number */
      dup4
        /* "test-ts/contracts/NFT.sol":804:843  IERC721(nft).approve(to, serial_number) */
      mload(0x40)
      dup4
      0xffffffff
      and
      0xe0
      shl
      dup2
      mstore
      0x04
      add
      tag_14
      swap3
      swap2
      swap1
      tag_15
      jump      // in
    tag_14:
      0x00
      mload(0x40)
      dup1
      dup4
      sub
      dup2
      0x00
      dup8
      dup1
      extcodesize
      iszero
      dup1
      iszero
      tag_16
      jumpi
      0x00
      dup1
      revert
    tag_16:
      pop
      gas
      call
      iszero
      dup1
      iszero
      tag_18
      jumpi
      returndatasize
      0x00
      dup1
      returndatacopy
      revert(0x00, returndatasize)
    tag_18:
      pop
      pop
      pop
      pop
        /* "test-ts/contracts/NFT.sol":711:850  function approveFromProxy(address to,... */
      pop
      pop
      jump      // out
        /* "test-ts/contracts/NFT.sol":540:705  function transferFromProxy(address to, address from,... */
    tag_12:
        /* "test-ts/contracts/NFT.sol":656:659  nft */
      0x00
      dup1
      sload
      swap1
      0x0100
      exp
      swap1
      div
      0xffffffffffffffffffffffffffffffffffffffff
      and
        /* "test-ts/contracts/NFT.sol":648:673  IERC721(nft).transferFrom */
      0xffffffffffffffffffffffffffffffffffffffff
      and
      0x23b872dd
        /* "test-ts/contracts/NFT.sol":674:676  to */
      dup5
        /* "test-ts/contracts/NFT.sol":678:682  from */
      dup5
        /* "test-ts/contracts/NFT.sol":684:697  serial_number */
      dup5
        /* "test-ts/contracts/NFT.sol":648:698  IERC721(nft).transferFrom(to, from, serial_number) */
      mload(0x40)
      dup5
      0xffffffff
      and
      0xe0
      shl
      dup2
      mstore
      0x04
      add
      tag_20
      swap4
      swap3
      swap2
      swap1
      tag_21
      jump      // in
    tag_20:
      0x00
      mload(0x40)
      dup1
      dup4
      sub
      dup2
      0x00
      dup8
      dup1
      extcodesize
      iszero
      dup1
      iszero
      tag_22
      jumpi
      0x00
      dup1
      revert
    tag_22:
      pop
      gas
      call
      iszero
      dup1
      iszero
      tag_24
      jumpi
      returndatasize
      0x00
      dup1
      returndatacopy
      revert(0x00, returndatasize)
    tag_24:
      pop
      pop
      pop
      pop
        /* "test-ts/contracts/NFT.sol":540:705  function transferFromProxy(address to, address from,... */
      pop
      pop
      pop
      jump      // out
        /* "#utility.yul":88:205   */
    tag_26:
        /* "#utility.yul":197:198   */
      0x00
        /* "#utility.yul":194:195   */
      dup1
        /* "#utility.yul":187:199   */
      revert
        /* "#utility.yul":334:460   */
    tag_28:
        /* "#utility.yul":371:378   */
      0x00
        /* "#utility.yul":411:453   */
      0xffffffffffffffffffffffffffffffffffffffff
        /* "#utility.yul":404:409   */
      dup3
        /* "#utility.yul":400:454   */
      and
        /* "#utility.yul":389:454   */
      swap1
      pop
        /* "#utility.yul":334:460   */
      swap2
      swap1
      pop
      jump      // out
        /* "#utility.yul":466:562   */
    tag_29:
        /* "#utility.yul":503:510   */
      0x00
        /* "#utility.yul":532:556   */
      tag_43
        /* "#utility.yul":550:555   */
      dup3
        /* "#utility.yul":532:556   */
      tag_28
      jump      // in
    tag_43:
        /* "#utility.yul":521:556   */
      swap1
      pop
        /* "#utility.yul":466:562   */
      swap2
      swap1
      pop
      jump      // out
        /* "#utility.yul":568:690   */
    tag_30:
        /* "#utility.yul":641:665   */
      tag_45
        /* "#utility.yul":659:664   */
      dup2
        /* "#utility.yul":641:665   */
      tag_29
      jump      // in
    tag_45:
        /* "#utility.yul":634:639   */
      dup2
        /* "#utility.yul":631:666   */
      eq
        /* "#utility.yul":621:684   */
      tag_46
      jumpi
        /* "#utility.yul":680:681   */
      0x00
        /* "#utility.yul":677:678   */
      dup1
        /* "#utility.yul":670:682   */
      revert
        /* "#utility.yul":621:684   */
    tag_46:
        /* "#utility.yul":568:690   */
      pop
      jump      // out
        /* "#utility.yul":696:835   */
    tag_31:
        /* "#utility.yul":742:747   */
      0x00
        /* "#utility.yul":780:786   */
      dup2
        /* "#utility.yul":767:787   */
      calldataload
        /* "#utility.yul":758:787   */
      swap1
      pop
        /* "#utility.yul":796:829   */
      tag_48
        /* "#utility.yul":823:828   */
      dup2
        /* "#utility.yul":796:829   */
      tag_30
      jump      // in
    tag_48:
        /* "#utility.yul":696:835   */
      swap3
      swap2
      pop
      pop
      jump      // out
        /* "#utility.yul":841:918   */
    tag_32:
        /* "#utility.yul":878:885   */
      0x00
        /* "#utility.yul":907:912   */
      dup2
        /* "#utility.yul":896:912   */
      swap1
      pop
        /* "#utility.yul":841:918   */
      swap2
      swap1
      pop
      jump      // out
        /* "#utility.yul":924:1046   */
    tag_33:
        /* "#utility.yul":997:1021   */
      tag_51
        /* "#utility.yul":1015:1020   */
      dup2
        /* "#utility.yul":997:1021   */
      tag_32
      jump      // in
    tag_51:
        /* "#utility.yul":990:995   */
      dup2
        /* "#utility.yul":987:1022   */
      eq
        /* "#utility.yul":977:1040   */
      tag_52
      jumpi
        /* "#utility.yul":1036:1037   */
      0x00
        /* "#utility.yul":1033:1034   */
      dup1
        /* "#utility.yul":1026:1038   */
      revert
        /* "#utility.yul":977:1040   */
    tag_52:
        /* "#utility.yul":924:1046   */
      pop
      jump      // out
        /* "#utility.yul":1052:1191   */
    tag_34:
        /* "#utility.yul":1098:1103   */
      0x00
        /* "#utility.yul":1136:1142   */
      dup2
        /* "#utility.yul":1123:1143   */
      calldataload
        /* "#utility.yul":1114:1143   */
      swap1
      pop
        /* "#utility.yul":1152:1185   */
      tag_54
        /* "#utility.yul":1179:1184   */
      dup2
        /* "#utility.yul":1152:1185   */
      tag_33
      jump      // in
    tag_54:
        /* "#utility.yul":1052:1191   */
      swap3
      swap2
      pop
      pop
      jump      // out
        /* "#utility.yul":1197:1671   */
    tag_7:
        /* "#utility.yul":1265:1271   */
      0x00
        /* "#utility.yul":1273:1279   */
      dup1
        /* "#utility.yul":1322:1324   */
      0x40
        /* "#utility.yul":1310:1319   */
      dup4
        /* "#utility.yul":1301:1308   */
      dup6
        /* "#utility.yul":1297:1320   */
      sub
        /* "#utility.yul":1293:1325   */
      slt
        /* "#utility.yul":1290:1409   */
      iszero
      tag_56
      jumpi
        /* "#utility.yul":1328:1407   */
      tag_57
      tag_26
      jump      // in
    tag_57:
        /* "#utility.yul":1290:1409   */
    tag_56:
        /* "#utility.yul":1448:1449   */
      0x00
        /* "#utility.yul":1473:1526   */
      tag_58
        /* "#utility.yul":1518:1525   */
      dup6
        /* "#utility.yul":1509:1515   */
      dup3
        /* "#utility.yul":1498:1507   */
      dup7
        /* "#utility.yul":1494:1516   */
      add
        /* "#utility.yul":1473:1526   */
      tag_31
      jump      // in
    tag_58:
        /* "#utility.yul":1463:1526   */
      swap3
      pop
        /* "#utility.yul":1419:1536   */
      pop
        /* "#utility.yul":1575:1577   */
      0x20
        /* "#utility.yul":1601:1654   */
      tag_59
        /* "#utility.yul":1646:1653   */
      dup6
        /* "#utility.yul":1637:1643   */
      dup3
        /* "#utility.yul":1626:1635   */
      dup7
        /* "#utility.yul":1622:1644   */
      add
        /* "#utility.yul":1601:1654   */
      tag_34
      jump      // in
    tag_59:
        /* "#utility.yul":1591:1654   */
      swap2
      pop
        /* "#utility.yul":1546:1664   */
      pop
        /* "#utility.yul":1197:1671   */
      swap3
      pop
      swap3
      swap1
      pop
      jump      // out
        /* "#utility.yul":1677:2296   */
    tag_11:
        /* "#utility.yul":1754:1760   */
      0x00
        /* "#utility.yul":1762:1768   */
      dup1
        /* "#utility.yul":1770:1776   */
      0x00
        /* "#utility.yul":1819:1821   */
      0x60
        /* "#utility.yul":1807:1816   */
      dup5
        /* "#utility.yul":1798:1805   */
      dup7
        /* "#utility.yul":1794:1817   */
      sub
        /* "#utility.yul":1790:1822   */
      slt
        /* "#utility.yul":1787:1906   */
      iszero
      tag_61
      jumpi
        /* "#utility.yul":1825:1904   */
      tag_62
      tag_26
      jump      // in
    tag_62:
        /* "#utility.yul":1787:1906   */
    tag_61:
        /* "#utility.yul":1945:1946   */
      0x00
        /* "#utility.yul":1970:2023   */
      tag_63
        /* "#utility.yul":2015:2022   */
      dup7
        /* "#utility.yul":2006:2012   */
      dup3
        /* "#utility.yul":1995:2004   */
      dup8
        /* "#utility.yul":1991:2013   */
      add
        /* "#utility.yul":1970:2023   */
      tag_31
      jump      // in
    tag_63:
        /* "#utility.yul":1960:2023   */
      swap4
      pop
        /* "#utility.yul":1916:2033   */
      pop
        /* "#utility.yul":2072:2074   */
      0x20
        /* "#utility.yul":2098:2151   */
      tag_64
        /* "#utility.yul":2143:2150   */
      dup7
        /* "#utility.yul":2134:2140   */
      dup3
        /* "#utility.yul":2123:2132   */
      dup8
        /* "#utility.yul":2119:2141   */
      add
        /* "#utility.yul":2098:2151   */
      tag_31
      jump      // in
    tag_64:
        /* "#utility.yul":2088:2151   */
      swap3
      pop
        /* "#utility.yul":2043:2161   */
      pop
        /* "#utility.yul":2200:2202   */
      0x40
        /* "#utility.yul":2226:2279   */
      tag_65
        /* "#utility.yul":2271:2278   */
      dup7
        /* "#utility.yul":2262:2268   */
      dup3
        /* "#utility.yul":2251:2260   */
      dup8
        /* "#utility.yul":2247:2269   */
      add
        /* "#utility.yul":2226:2279   */
      tag_34
      jump      // in
    tag_65:
        /* "#utility.yul":2216:2279   */
      swap2
      pop
        /* "#utility.yul":2171:2289   */
      pop
        /* "#utility.yul":1677:2296   */
      swap3
      pop
      swap3
      pop
      swap3
      jump      // out
        /* "#utility.yul":2302:2420   */
    tag_35:
        /* "#utility.yul":2389:2413   */
      tag_67
        /* "#utility.yul":2407:2412   */
      dup2
        /* "#utility.yul":2389:2413   */
      tag_29
      jump      // in
    tag_67:
        /* "#utility.yul":2384:2387   */
      dup3
        /* "#utility.yul":2377:2414   */
      mstore
        /* "#utility.yul":2302:2420   */
      pop
      pop
      jump      // out
        /* "#utility.yul":2426:2544   */
    tag_36:
        /* "#utility.yul":2513:2537   */
      tag_69
        /* "#utility.yul":2531:2536   */
      dup2
        /* "#utility.yul":2513:2537   */
      tag_32
      jump      // in
    tag_69:
        /* "#utility.yul":2508:2511   */
      dup3
        /* "#utility.yul":2501:2538   */
      mstore
        /* "#utility.yul":2426:2544   */
      pop
      pop
      jump      // out
        /* "#utility.yul":2550:2882   */
    tag_15:
        /* "#utility.yul":2671:2675   */
      0x00
        /* "#utility.yul":2709:2711   */
      0x40
        /* "#utility.yul":2698:2707   */
      dup3
        /* "#utility.yul":2694:2712   */
      add
        /* "#utility.yul":2686:2712   */
      swap1
      pop
        /* "#utility.yul":2722:2793   */
      tag_71
        /* "#utility.yul":2790:2791   */
      0x00
        /* "#utility.yul":2779:2788   */
      dup4
        /* "#utility.yul":2775:2792   */
      add
        /* "#utility.yul":2766:2772   */
      dup6
        /* "#utility.yul":2722:2793   */
      tag_35
      jump      // in
    tag_71:
        /* "#utility.yul":2803:2875   */
      tag_72
        /* "#utility.yul":2871:2873   */
      0x20
        /* "#utility.yul":2860:2869   */
      dup4
        /* "#utility.yul":2856:2874   */
      add
        /* "#utility.yul":2847:2853   */
      dup5
        /* "#utility.yul":2803:2875   */
      tag_36
      jump      // in
    tag_72:
        /* "#utility.yul":2550:2882   */
      swap4
      swap3
      pop
      pop
      pop
      jump      // out
        /* "#utility.yul":2888:3330   */
    tag_21:
        /* "#utility.yul":3037:3041   */
      0x00
        /* "#utility.yul":3075:3077   */
      0x60
        /* "#utility.yul":3064:3073   */
      dup3
        /* "#utility.yul":3060:3078   */
      add
        /* "#utility.yul":3052:3078   */
      swap1
      pop
        /* "#utility.yul":3088:3159   */
      tag_74
        /* "#utility.yul":3156:3157   */
      0x00
        /* "#utility.yul":3145:3154   */
      dup4
        /* "#utility.yul":3141:3158   */
      add
        /* "#utility.yul":3132:3138   */
      dup7
        /* "#utility.yul":3088:3159   */
      tag_35
      jump      // in
    tag_74:
        /* "#utility.yul":3169:3241   */
      tag_75
        /* "#utility.yul":3237:3239   */
      0x20
        /* "#utility.yul":3226:3235   */
      dup4
        /* "#utility.yul":3222:3240   */
      add
        /* "#utility.yul":3213:3219   */
      dup6
        /* "#utility.yul":3169:3241   */
      tag_35
      jump      // in
    tag_75:
        /* "#utility.yul":3251:3323   */
      tag_76
        /* "#utility.yul":3319:3321   */
      0x40
        /* "#utility.yul":3308:3317   */
      dup4
        /* "#utility.yul":3304:3322   */
      add
        /* "#utility.yul":3295:3301   */
      dup5
        /* "#utility.yul":3251:3323   */
      tag_36
      jump      // in
    tag_76:
        /* "#utility.yul":2888:3330   */
      swap5
      swap4
      pop
      pop
      pop
      pop
      jump      // out

    auxdata: 0xa2646970667358221220b35361bce10e8d50efb46995825ff7c586989d5f73c6eb8776f6d2154c6ba39764736f6c63430008100033
}

Binary:
608060405273aaaaaaaa000000000000000000000000000000006000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561006457600080fd5b50610378806100746000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632b2cf0df1461003b578063382904fa14610057575b600080fd5b61005560048036038101906100509190610231565b610073565b005b610071600480360381019061006c9190610271565b610104565b005b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b383836040518363ffffffff1660e01b81526004016100ce9291906102e2565b600060405180830381600087803b1580156100e857600080fd5b505af11580156100fc573d6000803e3d6000fd5b505050505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8484846040518463ffffffff1660e01b81526004016101619392919061030b565b600060405180830381600087803b15801561017b57600080fd5b505af115801561018f573d6000803e3d6000fd5b50505050505050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101c88261019d565b9050919050565b6101d8816101bd565b81146101e357600080fd5b50565b6000813590506101f5816101cf565b92915050565b6000819050919050565b61020e816101fb565b811461021957600080fd5b50565b60008135905061022b81610205565b92915050565b6000806040838503121561024857610247610198565b5b6000610256858286016101e6565b92505060206102678582860161021c565b9150509250929050565b60008060006060848603121561028a57610289610198565b5b6000610298868287016101e6565b93505060206102a9868287016101e6565b92505060406102ba8682870161021c565b9150509250925092565b6102cd816101bd565b82525050565b6102dc816101fb565b82525050565b60006040820190506102f760008301856102c4565b61030460208301846102d3565b9392505050565b600060608201905061032060008301866102c4565b61032d60208301856102c4565b61033a60408301846102d3565b94935050505056fea2646970667358221220b35361bce10e8d50efb46995825ff7c586989d5f73c6eb8776f6d2154c6ba39764736f6c63430008100033

```

And for erc20 contract
```
pragma solidity ^0.8.13;
import "@openzeppelin/contracts/interfaces/IERC20.sol";
// import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
// import "@openzeppelin/contracts/interfaces/IERC165.sol";

contract abc {
// CENNZ testnet address with assetId 16000
address cennz = 0xcCccccCc00003E80000000000000000000000000;

function balanceOfProxy(address who) public view returns (uint256) {
    return IERC20(cennz).balanceOf(who);
}

function transferFromProxy(uint256 amount) external {
    IERC20(cennz).transferFrom(msg.sender, address(this), amount);
}
}
```

Bytecode is 

```
======= test-ts/contracts/ERC20.sol:abc =======
EVM assembly:
    /* "test-ts/contracts/ERC20.sol":233:622  contract abc {... */
  mstore(0x40, 0x80)
    /* "test-ts/contracts/ERC20.sol":316:358  0xcCccccCc00003E80000000000000000000000000 */
  0xcccccccc00003e80000000000000000000000000
    /* "test-ts/contracts/ERC20.sol":300:358  address cennz = 0xcCccccCc00003E80000000000000000000000000 */
  0x00
  dup1
  0x0100
  exp
  dup2
  sload
  dup2
  0xffffffffffffffffffffffffffffffffffffffff
  mul
  not
  and
  swap1
  dup4
  0xffffffffffffffffffffffffffffffffffffffff
  and
  mul
  or
  swap1
  sstore
  pop
    /* "test-ts/contracts/ERC20.sol":233:622  contract abc {... */
  callvalue
  dup1
  iszero
  tag_1
  jumpi
  0x00
  dup1
  revert
tag_1:
  pop
  dataSize(sub_0)
  dup1
  dataOffset(sub_0)
  0x00
  codecopy
  0x00
  return
stop

sub_0: assembly {
        /* "test-ts/contracts/ERC20.sol":233:622  contract abc {... */
      mstore(0x40, 0x80)
      callvalue
      dup1
      iszero
      tag_1
      jumpi
      0x00
      dup1
      revert
    tag_1:
      pop
      jumpi(tag_2, lt(calldatasize, 0x04))
      shr(0xe0, calldataload(0x00))
      dup1
      0x671ef26c
      eq
      tag_3
      jumpi
      dup1
      0x95c5fc03
      eq
      tag_4
      jumpi
    tag_2:
      0x00
      dup1
      revert
        /* "test-ts/contracts/ERC20.sol":490:620  function transferFromProxy(uint256 amount) external {... */
    tag_3:
      tag_5
      0x04
      dup1
      calldatasize
      sub
      dup2
      add
      swap1
      tag_6
      swap2
      swap1
      tag_7
      jump      // in
    tag_6:
      tag_8
      jump      // in
    tag_5:
      stop
        /* "test-ts/contracts/ERC20.sol":365:484  function balanceOfProxy(address who) public view returns (uint256) {... */
    tag_4:
      tag_9
      0x04
      dup1
      calldatasize
      sub
      dup2
      add
      swap1
      tag_10
      swap2
      swap1
      tag_11
      jump      // in
    tag_10:
      tag_12
      jump      // in
    tag_9:
      mload(0x40)
      tag_13
      swap2
      swap1
      tag_14
      jump      // in
    tag_13:
      mload(0x40)
      dup1
      swap2
      sub
      swap1
      return
        /* "test-ts/contracts/ERC20.sol":490:620  function transferFromProxy(uint256 amount) external {... */
    tag_8:
        /* "test-ts/contracts/ERC20.sol":559:564  cennz */
      0x00
      dup1
      sload
      swap1
      0x0100
      exp
      swap1
      div
      0xffffffffffffffffffffffffffffffffffffffff
      and
        /* "test-ts/contracts/ERC20.sol":552:578  IERC20(cennz).transferFrom */
      0xffffffffffffffffffffffffffffffffffffffff
      and
      0x23b872dd
        /* "test-ts/contracts/ERC20.sol":579:589  msg.sender */
      caller
        /* "test-ts/contracts/ERC20.sol":599:603  this */
      address
        /* "test-ts/contracts/ERC20.sol":606:612  amount */
      dup5
        /* "test-ts/contracts/ERC20.sol":552:613  IERC20(cennz).transferFrom(msg.sender, address(this), amount) */
      mload(0x40)
      dup5
      0xffffffff
      and
      0xe0
      shl
      dup2
      mstore
      0x04
      add
      tag_16
      swap4
      swap3
      swap2
      swap1
      tag_17
      jump      // in
    tag_16:
      0x00
      mload(0x40)
      dup1
      dup4
      sub
      dup2
      0x00
      dup8
      dup1
      extcodesize
      iszero
      dup1
      iszero
      tag_18
      jumpi
      0x00
      dup1
      revert
    tag_18:
      pop
      gas
      call
      iszero
      dup1
      iszero
      tag_20
      jumpi
      returndatasize
      0x00
      dup1
      returndatacopy
      revert(0x00, returndatasize)
    tag_20:
      pop
      pop
      pop
      pop
        /* "test-ts/contracts/ERC20.sol":490:620  function transferFromProxy(uint256 amount) external {... */
      pop
      jump      // out
        /* "test-ts/contracts/ERC20.sol":365:484  function balanceOfProxy(address who) public view returns (uint256) {... */
    tag_12:
        /* "test-ts/contracts/ERC20.sol":423:430  uint256 */
      0x00
        /* "test-ts/contracts/ERC20.sol":456:461  cennz */
      dup1
      0x00
      swap1
      sload
      swap1
      0x0100
      exp
      swap1
      div
      0xffffffffffffffffffffffffffffffffffffffff
      and
        /* "test-ts/contracts/ERC20.sol":449:472  IERC20(cennz).balanceOf */
      0xffffffffffffffffffffffffffffffffffffffff
      and
      0x70a08231
        /* "test-ts/contracts/ERC20.sol":473:476  who */
      dup4
        /* "test-ts/contracts/ERC20.sol":449:477  IERC20(cennz).balanceOf(who) */
      mload(0x40)
      dup3
      0xffffffff
      and
      0xe0
      shl
      dup2
      mstore
      0x04
      add
      tag_22
      swap2
      swap1
      tag_23
      jump      // in
    tag_22:
      0x20
      mload(0x40)
      dup1
      dup4
      sub
      dup2
      dup7
      gas
      staticcall
      iszero
      dup1
      iszero
      tag_25
      jumpi
      returndatasize
      0x00
      dup1
      returndatacopy
      revert(0x00, returndatasize)
    tag_25:
      pop
      pop
      pop
      pop
      mload(0x40)
      returndatasize
      not(0x1f)
      0x1f
      dup3
      add
      and
      dup3
      add
      dup1
      0x40
      mstore
      pop
      dup2
      add
      swap1
      tag_26
      swap2
      swap1
      tag_27
      jump      // in
    tag_26:
        /* "test-ts/contracts/ERC20.sol":442:477  return IERC20(cennz).balanceOf(who) */
      swap1
      pop
        /* "test-ts/contracts/ERC20.sol":365:484  function balanceOfProxy(address who) public view returns (uint256) {... */
      swap2
      swap1
      pop
      jump      // out
        /* "#utility.yul":88:205   */
    tag_29:
        /* "#utility.yul":197:198   */
      0x00
        /* "#utility.yul":194:195   */
      dup1
        /* "#utility.yul":187:199   */
      revert
        /* "#utility.yul":334:411   */
    tag_31:
        /* "#utility.yul":371:378   */
      0x00
        /* "#utility.yul":400:405   */
      dup2
        /* "#utility.yul":389:405   */
      swap1
      pop
        /* "#utility.yul":334:411   */
      swap2
      swap1
      pop
      jump      // out
        /* "#utility.yul":417:539   */
    tag_32:
        /* "#utility.yul":490:514   */
      tag_47
        /* "#utility.yul":508:513   */
      dup2
        /* "#utility.yul":490:514   */
      tag_31
      jump      // in
    tag_47:
        /* "#utility.yul":483:488   */
      dup2
        /* "#utility.yul":480:515   */
      eq
        /* "#utility.yul":470:533   */
      tag_48
      jumpi
        /* "#utility.yul":529:530   */
      0x00
        /* "#utility.yul":526:527   */
      dup1
        /* "#utility.yul":519:531   */
      revert
        /* "#utility.yul":470:533   */
    tag_48:
        /* "#utility.yul":417:539   */
      pop
      jump      // out
        /* "#utility.yul":545:684   */
    tag_33:
        /* "#utility.yul":591:596   */
      0x00
        /* "#utility.yul":629:635   */
      dup2
        /* "#utility.yul":616:636   */
      calldataload
        /* "#utility.yul":607:636   */
      swap1
      pop
        /* "#utility.yul":645:678   */
      tag_50
        /* "#utility.yul":672:677   */
      dup2
        /* "#utility.yul":645:678   */
      tag_32
      jump      // in
    tag_50:
        /* "#utility.yul":545:684   */
      swap3
      swap2
      pop
      pop
      jump      // out
        /* "#utility.yul":690:1019   */
    tag_7:
        /* "#utility.yul":749:755   */
      0x00
        /* "#utility.yul":798:800   */
      0x20
        /* "#utility.yul":786:795   */
      dup3
        /* "#utility.yul":777:784   */
      dup5
        /* "#utility.yul":773:796   */
      sub
        /* "#utility.yul":769:801   */
      slt
        /* "#utility.yul":766:885   */
      iszero
      tag_52
      jumpi
        /* "#utility.yul":804:883   */
      tag_53
      tag_29
      jump      // in
    tag_53:
        /* "#utility.yul":766:885   */
    tag_52:
        /* "#utility.yul":924:925   */
      0x00
        /* "#utility.yul":949:1002   */
      tag_54
        /* "#utility.yul":994:1001   */
      dup5
        /* "#utility.yul":985:991   */
      dup3
        /* "#utility.yul":974:983   */
      dup6
        /* "#utility.yul":970:992   */
      add
        /* "#utility.yul":949:1002   */
      tag_33
      jump      // in
    tag_54:
        /* "#utility.yul":939:1002   */
      swap2
      pop
        /* "#utility.yul":895:1012   */
      pop
        /* "#utility.yul":690:1019   */
      swap3
      swap2
      pop
      pop
      jump      // out
        /* "#utility.yul":1025:1151   */
    tag_34:
        /* "#utility.yul":1062:1069   */
      0x00
        /* "#utility.yul":1102:1144   */
      0xffffffffffffffffffffffffffffffffffffffff
        /* "#utility.yul":1095:1100   */
      dup3
        /* "#utility.yul":1091:1145   */
      and
        /* "#utility.yul":1080:1145   */
      swap1
      pop
        /* "#utility.yul":1025:1151   */
      swap2
      swap1
      pop
      jump      // out
        /* "#utility.yul":1157:1253   */
    tag_35:
        /* "#utility.yul":1194:1201   */
      0x00
        /* "#utility.yul":1223:1247   */
      tag_57
        /* "#utility.yul":1241:1246   */
      dup3
        /* "#utility.yul":1223:1247   */
      tag_34
      jump      // in
    tag_57:
        /* "#utility.yul":1212:1247   */
      swap1
      pop
        /* "#utility.yul":1157:1253   */
      swap2
      swap1
      pop
      jump      // out
        /* "#utility.yul":1259:1381   */
    tag_36:
        /* "#utility.yul":1332:1356   */
      tag_59
        /* "#utility.yul":1350:1355   */
      dup2
        /* "#utility.yul":1332:1356   */
      tag_35
      jump      // in
    tag_59:
        /* "#utility.yul":1325:1330   */
      dup2
        /* "#utility.yul":1322:1357   */
      eq
        /* "#utility.yul":1312:1375   */
      tag_60
      jumpi
        /* "#utility.yul":1371:1372   */
      0x00
        /* "#utility.yul":1368:1369   */
      dup1
        /* "#utility.yul":1361:1373   */
      revert
        /* "#utility.yul":1312:1375   */
    tag_60:
        /* "#utility.yul":1259:1381   */
      pop
      jump      // out
        /* "#utility.yul":1387:1526   */
    tag_37:
        /* "#utility.yul":1433:1438   */
      0x00
        /* "#utility.yul":1471:1477   */
      dup2
        /* "#utility.yul":1458:1478   */
      calldataload
        /* "#utility.yul":1449:1478   */
      swap1
      pop
        /* "#utility.yul":1487:1520   */
      tag_62
        /* "#utility.yul":1514:1519   */
      dup2
        /* "#utility.yul":1487:1520   */
      tag_36
      jump      // in
    tag_62:
        /* "#utility.yul":1387:1526   */
      swap3
      swap2
      pop
      pop
      jump      // out
        /* "#utility.yul":1532:1861   */
    tag_11:
        /* "#utility.yul":1591:1597   */
      0x00
        /* "#utility.yul":1640:1642   */
      0x20
        /* "#utility.yul":1628:1637   */
      dup3
        /* "#utility.yul":1619:1626   */
      dup5
        /* "#utility.yul":1615:1638   */
      sub
        /* "#utility.yul":1611:1643   */
      slt
        /* "#utility.yul":1608:1727   */
      iszero
      tag_64
      jumpi
        /* "#utility.yul":1646:1725   */
      tag_65
      tag_29
      jump      // in
    tag_65:
        /* "#utility.yul":1608:1727   */
    tag_64:
        /* "#utility.yul":1766:1767   */
      0x00
        /* "#utility.yul":1791:1844   */
      tag_66
        /* "#utility.yul":1836:1843   */
      dup5
        /* "#utility.yul":1827:1833   */
      dup3
        /* "#utility.yul":1816:1825   */
      dup6
        /* "#utility.yul":1812:1834   */
      add
        /* "#utility.yul":1791:1844   */
      tag_37
      jump      // in
    tag_66:
        /* "#utility.yul":1781:1844   */
      swap2
      pop
        /* "#utility.yul":1737:1854   */
      pop
        /* "#utility.yul":1532:1861   */
      swap3
      swap2
      pop
      pop
      jump      // out
        /* "#utility.yul":1867:1985   */
    tag_38:
        /* "#utility.yul":1954:1978   */
      tag_68
        /* "#utility.yul":1972:1977   */
      dup2
        /* "#utility.yul":1954:1978   */
      tag_31
      jump      // in
    tag_68:
        /* "#utility.yul":1949:1952   */
      dup3
        /* "#utility.yul":1942:1979   */
      mstore
        /* "#utility.yul":1867:1985   */
      pop
      pop
      jump      // out
        /* "#utility.yul":1991:2213   */
    tag_14:
        /* "#utility.yul":2084:2088   */
      0x00
        /* "#utility.yul":2122:2124   */
      0x20
        /* "#utility.yul":2111:2120   */
      dup3
        /* "#utility.yul":2107:2125   */
      add
        /* "#utility.yul":2099:2125   */
      swap1
      pop
        /* "#utility.yul":2135:2206   */
      tag_70
        /* "#utility.yul":2203:2204   */
      0x00
        /* "#utility.yul":2192:2201   */
      dup4
        /* "#utility.yul":2188:2205   */
      add
        /* "#utility.yul":2179:2185   */
      dup5
        /* "#utility.yul":2135:2206   */
      tag_38
      jump      // in
    tag_70:
        /* "#utility.yul":1991:2213   */
      swap3
      swap2
      pop
      pop
      jump      // out
        /* "#utility.yul":2219:2337   */
    tag_39:
        /* "#utility.yul":2306:2330   */
      tag_72
        /* "#utility.yul":2324:2329   */
      dup2
        /* "#utility.yul":2306:2330   */
      tag_35
      jump      // in
    tag_72:
        /* "#utility.yul":2301:2304   */
      dup3
        /* "#utility.yul":2294:2331   */
      mstore
        /* "#utility.yul":2219:2337   */
      pop
      pop
      jump      // out
        /* "#utility.yul":2343:2785   */
    tag_17:
        /* "#utility.yul":2492:2496   */
      0x00
        /* "#utility.yul":2530:2532   */
      0x60
        /* "#utility.yul":2519:2528   */
      dup3
        /* "#utility.yul":2515:2533   */
      add
        /* "#utility.yul":2507:2533   */
      swap1
      pop
        /* "#utility.yul":2543:2614   */
      tag_74
        /* "#utility.yul":2611:2612   */
      0x00
        /* "#utility.yul":2600:2609   */
      dup4
        /* "#utility.yul":2596:2613   */
      add
        /* "#utility.yul":2587:2593   */
      dup7
        /* "#utility.yul":2543:2614   */
      tag_39
      jump      // in
    tag_74:
        /* "#utility.yul":2624:2696   */
      tag_75
        /* "#utility.yul":2692:2694   */
      0x20
        /* "#utility.yul":2681:2690   */
      dup4
        /* "#utility.yul":2677:2695   */
      add
        /* "#utility.yul":2668:2674   */
      dup6
        /* "#utility.yul":2624:2696   */
      tag_39
      jump      // in
    tag_75:
        /* "#utility.yul":2706:2778   */
      tag_76
        /* "#utility.yul":2774:2776   */
      0x40
        /* "#utility.yul":2763:2772   */
      dup4
        /* "#utility.yul":2759:2777   */
      add
        /* "#utility.yul":2750:2756   */
      dup5
        /* "#utility.yul":2706:2778   */
      tag_38
      jump      // in
    tag_76:
        /* "#utility.yul":2343:2785   */
      swap5
      swap4
      pop
      pop
      pop
      pop
      jump      // out
        /* "#utility.yul":2791:3013   */
    tag_23:
        /* "#utility.yul":2884:2888   */
      0x00
        /* "#utility.yul":2922:2924   */
      0x20
        /* "#utility.yul":2911:2920   */
      dup3
        /* "#utility.yul":2907:2925   */
      add
        /* "#utility.yul":2899:2925   */
      swap1
      pop
        /* "#utility.yul":2935:3006   */
      tag_78
        /* "#utility.yul":3003:3004   */
      0x00
        /* "#utility.yul":2992:3001   */
      dup4
        /* "#utility.yul":2988:3005   */
      add
        /* "#utility.yul":2979:2985   */
      dup5
        /* "#utility.yul":2935:3006   */
      tag_39
      jump      // in
    tag_78:
        /* "#utility.yul":2791:3013   */
      swap3
      swap2
      pop
      pop
      jump      // out
        /* "#utility.yul":3019:3162   */
    tag_40:
        /* "#utility.yul":3076:3081   */
      0x00
        /* "#utility.yul":3107:3113   */
      dup2
        /* "#utility.yul":3101:3114   */
      mload
        /* "#utility.yul":3092:3114   */
      swap1
      pop
        /* "#utility.yul":3123:3156   */
      tag_80
        /* "#utility.yul":3150:3155   */
      dup2
        /* "#utility.yul":3123:3156   */
      tag_32
      jump      // in
    tag_80:
        /* "#utility.yul":3019:3162   */
      swap3
      swap2
      pop
      pop
      jump      // out
        /* "#utility.yul":3168:3519   */
    tag_27:
        /* "#utility.yul":3238:3244   */
      0x00
        /* "#utility.yul":3287:3289   */
      0x20
        /* "#utility.yul":3275:3284   */
      dup3
        /* "#utility.yul":3266:3273   */
      dup5
        /* "#utility.yul":3262:3285   */
      sub
        /* "#utility.yul":3258:3290   */
      slt
        /* "#utility.yul":3255:3374   */
      iszero
      tag_82
      jumpi
        /* "#utility.yul":3293:3372   */
      tag_83
      tag_29
      jump      // in
    tag_83:
        /* "#utility.yul":3255:3374   */
    tag_82:
        /* "#utility.yul":3413:3414   */
      0x00
        /* "#utility.yul":3438:3502   */
      tag_84
        /* "#utility.yul":3494:3501   */
      dup5
        /* "#utility.yul":3485:3491   */
      dup3
        /* "#utility.yul":3474:3483   */
      dup6
        /* "#utility.yul":3470:3492   */
      add
        /* "#utility.yul":3438:3502   */
      tag_40
      jump      // in
    tag_84:
        /* "#utility.yul":3428:3502   */
      swap2
      pop
        /* "#utility.yul":3384:3512   */
      pop
        /* "#utility.yul":3168:3519   */
      swap3
      swap2
      pop
      pop
      jump      // out

    auxdata: 0xa2646970667358221220926b02fcdc9a5b2e602324be771e1ebae7f55654d2717c9828e5c76db6ec544064736f6c63430008100033
}

Binary:
608060405273cccccccc00003e800000000000000000000000006000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561006457600080fd5b506103b3806100746000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063671ef26c1461003b57806395c5fc0314610057575b600080fd5b610055600480360381019061005091906101f8565b610087565b005b610071600480360381019061006c9190610283565b610119565b60405161007e91906102bf565b60405180910390f35b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b81526004016100e4939291906102e9565b600060405180830381600087803b1580156100fe57600080fd5b505af1158015610112573d6000803e3d6000fd5b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b81526004016101759190610320565b602060405180830381865afa158015610192573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101b69190610350565b9050919050565b600080fd5b6000819050919050565b6101d5816101c2565b81146101e057600080fd5b50565b6000813590506101f2816101cc565b92915050565b60006020828403121561020e5761020d6101bd565b5b600061021c848285016101e3565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061025082610225565b9050919050565b61026081610245565b811461026b57600080fd5b50565b60008135905061027d81610257565b92915050565b600060208284031215610299576102986101bd565b5b60006102a78482850161026e565b91505092915050565b6102b9816101c2565b82525050565b60006020820190506102d460008301846102b0565b92915050565b6102e381610245565b82525050565b60006060820190506102fe60008301866102da565b61030b60208301856102da565b61031860408301846102b0565b949350505050565b600060208201905061033560008301846102da565b92915050565b60008151905061034a816101cc565b92915050565b600060208284031215610366576103656101bd565b5b60006103748482850161033b565b9150509291505056fea2646970667358221220926b02fcdc9a5b2e602324be771e1ebae7f55654d2717c9828e5c76db6ec544064736f6c63430008100033

```

