Try   HackMD

Ticket: Need a Multicall Contract for Arbitrary Contract Functions

Environment

  1. 模擬 transaction: https://dashboard.tenderly.co/
  2. 鏈:Arbitrum
  3. ABI: https://github.com/david30907d/all-weather-scaffold/blob/master/packages/react-app/src/contracts/external_contracts.js#LL5361C1-L5361C1

失敗案例(Withdraw from Radiant's Lending Pool):

  • 直接執行 Radiant 的 withdraw(成功):
    • Contract Address: 0xF4B1486DD74D07706052A33d31d7c0AAFD0659E1
    • Function: withdraw
    • Param:
      • asset: 0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f
      • amount: 115792089237316195423570985008687907853269984665640564039457584007913129639935 (這數字是0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 的 uint256)
      • to: 0x43cd745bd5fbfc8cfd79ebc855f949abc79a1e0c
    • From: 0x43cd745bd5fbfc8cfd79ebc855f949abc79a1e0c
  • Use MakerDAO's Multicall Contract with Delegate Call (transaction 有完成但是錢沒有真的領出來, 只會浪費 gas 啥都領不到):
    • Contract: 0xE5C1DB3d984458863aADbCF2b9684bA3a15123B7
    • Function: aggregate
    • Param: Aggregate吃一個 tuple, 裡面放一堆你想 multicall 的 obj
      ​​​​​​​​[
      ​​​​​​​​    {
      ​​​​​​​​        "target": "0xF4B1486DD74D07706052A33d31d7c0AAFD0659E1",
      ​​​​​​​​        "callData": "0x252dba42000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000f4b1486dd74d07706052a33d31d7c0aafd0659e10000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006469328dec0000000000000000000000002f2a2543b76a4166549f7aab2e75bef0aefc5b0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000043cd745bd5fbfc8cfd79ebc855f949abc79a1e0c00000000000000000000000000000000000000000000000000000000"
      ​​​​​​​​    }
      ​​​​​​​​]
      
      • 如何生成 calldata? 可以用 ethers 加上這份 ABI 去生
        ​​​​​​​​​​​​writeContracts.RadiantLendingPool.interface.encodeFunctionData(
        ​​​​​​​​​​​​        "withdraw(address,uint256,address)",
        ​​​​​​​​​​​​        ["0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f", BigNumber.from("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), "0x43cd745bd5fbfc8cfd79ebc855f949abc79a1e0c"],
        ​​​​​​​​​​​​    )
        ​​​​​​​​​​​​    ```
        
  • 直接寫個合約在裡面使用 Function Call(會被 revert)
    • github
    • Contract: 0xa4344cd2362425ce474cb3be5ac2a674608e5a36
    • Function: withdrawRadiantLending
    • Params:
      • radiantContract: 0x76ba3eC5f5adBf1C58c91e86502232317EeA72dE
      • radiantLendingContract: 0xF4B1486DD74D07706052A33d31d7c0AAFD0659E1
      • assets: ["0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f", "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9"]
      • amount: 115792089237316195423570985008687907853269984665640564039457584007913129639935
      • to: 0x43cd745Bd5FbFc8CfD79ebC855f949abc79a1E0C