1

How can I accomplish the next behavior(more specific to implement callMint) in Yul? I couldn't find anything related to this

    contract Token is ERC20{
....
 function mint(address addr, uint256 amount) external {
       _mint(addr, amount);
 }
....

}

struct Param{
    address owner;
    uint256 amount;
}

contract Test{
    ....
    function callMint(address tokenAddress, Param param) external {
         Token(tokenAddress).mint(param.owner, param.amount);
    }
    ....
}
bogdy9912
  • 172
  • 1
  • 1
  • 10

1 Answers1

0

Basically you need to copy the calldata for the external function you intend to do into memory. In your case the calldata is the abi.encode of the selector (4 bytes) and the two arguments.

I haven't tested it, but it should look like this:

    function callMint(address tokenAddress, Param param) external {
        address _owner = param.owner;
        uint256 _amount = param.amount;
        bytes4 _selector = 0x40c10f19;  // bytes4(keccak('mint(address,uint256)'))
        assembly {
            // We need 0x44 bytes for the calldata in memory.
            // We use the free memory pointer to find where to save it.
            let calldataOffset := mload(0x40)
            
            // We move the free memory pointer, but if this function is
            // 'external' we don't really need to
            mstore(0x40, add(calldataOffset, 0x44))
            
            // Store salldata to memory
            mstore(calldataOffset, _selector)
            mstore(add(calldataOffset, 0x04), _owner)
            mstore(add(calldataOffset, 0x24), _amount)
            
            let result := call(
                gas(),
                tokenAddress,
                0,               // msg.value
                calldataOffset,
                0x44,
                0,               // return data offset
                0                // return data length
            )
            
            // Revert if call failed
            if eq(result, 0) {
                // Forward the error
                returndatacopy(0, 0, returndatasize())
                revert(0, returndatasize())
            }
        }
    }
0xSanson
  • 718
  • 1
  • 2
  • 11