1

I am trying to develop myself on inline-assembly. There are two contracts: CryptoDevs and Whitelist. In the assembly, i copied the whole code of whitelist contract instance into cryptodevs memory. What I am trying to achieve is to get the value of the maxWhitelistedAddresses value in the whitelist contract using inline-assembly. Thanks in advance.

contract CryptoDevs {

   // Whitelist contract instance
    Whitelist whitelist;

    // Number of tokens reserved for whitelisted members
    uint256 public reservedTokens;
    uint256 public reservedTokensClaimed = 0;


    /**
      * @dev ERC721 constructor takes in a `name` and a `symbol` to the token collection.
      * name in our case is `Crypto Devs` and symbol is `CD`.
      * Constructor for Crypto Devs takes in the baseURI to set _baseTokenURI for the collection.
      * It also initializes an instance of whitelist interface.
      */
constructor (address whitelistContract) ERC721("Crypto Devs", "CD") {
        assembly {
            // load free memory pointer
            let ptr := mload(0x40)
            // retrieve the size of the code
            let size := extcodesize(whitelistContract)
            mstore(ptr, size)
            // copy the code of whitelist contract
            extcodecopy(whitelistContract, add(ptr, 0x20), 0, size)
            // get the code from memory
            let code := mload(0x40)
            // store the code in storage
            sstore(0x02, code)
        }
    }

and this is the original code I am trying to turn into assembly.

contract CryptoDevs {

    // Whitelist contract instance
    Whitelist whitelist;

    // Number of tokens reserved for whitelisted members
    uint256 public reservedTokens;
    uint256 public reservedTokensClaimed = 0;

    /**
      * @dev ERC721 constructor takes in a `name` and a `symbol` to the token collection.
      * name in our case is `Crypto Devs` and symbol is `CD`.
      * Constructor for Crypto Devs takes in the baseURI to set _baseTokenURI for the collection.
      * It also initializes an instance of whitelist interface.
      */
    constructor (address whitelistContract) ERC721("Crypto Devs", "CD") {
        whitelist = Whitelist(whitelistContract);
        reservedTokens = whitelist.maxWhitelistedAddresses();
    }

1 Answer 1

1

There's no need to copy the code of one contract into the other like that. You can't read state variables like that.

If you already have the whitelist address, you can do:

contract CryptoDevs {

    // Whitelist contract instance
    Whitelist whitelist;

    // Number of tokens reserved for whitelisted members
    uint256 public reservedTokens;
    uint256 public reservedTokensClaimed = 0;

    constructor (address whitelistContract) ERC721("Crypto Devs", "CD") {
        bytes4 selector = bytes4(keccak256("maxWhitelistedAddresses()"));

        assembly {
            let ptr := mload(0x40)

            // store the whitelist
            sstore(whitelist.slot, whitelistContract)

            // call
            mstore(ptr, selector)
            let returnPtr := add(ptr, 0x20)
            let success := staticcall(gas(), whitelistContract, ptr, 0x4, returnPtr, 0x20)

            // revert if fail
            if iszero(success) {
                returndatacopy(0, 0, returndatasize())
                revert(0, returndatasize())
            }

            // save return value to storage
            let returnValue := mload(returnPtr)
            sstore(reservedTokens.slot, returnValue)

            // move free memory pointer
            mstore(0x40, add(ptr, 0x40))
        }
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.