From c55642662dddca5c19bd238ad20408344fb0189f Mon Sep 17 00:00:00 2001 From: Peter Lee Date: Thu, 26 Sep 2024 16:39:45 -0700 Subject: [PATCH 01/14] update artillery config --- .github/actions/performance-tests/art.yaml | 288 +++++++++++---------- 1 file changed, 155 insertions(+), 133 deletions(-) diff --git a/.github/actions/performance-tests/art.yaml b/.github/actions/performance-tests/art.yaml index 806a4d6321..514d2a2cbf 100644 --- a/.github/actions/performance-tests/art.yaml +++ b/.github/actions/performance-tests/art.yaml @@ -9,11 +9,9 @@ config: http: timeout: 60 plugins: + expect: {} metrics-by-endpoint: useOnlyRequestNames: true - ensure: - - type: "failure" - threshold: 1 publish-metrics: - type: prometheus pushgateway: 'https://pushgateway-testnet.rpc.zetachain.com/-=CLOUDFLARE_UUID=-' @@ -26,6 +24,7 @@ config: - type: "html" filename: "artillery_report.html" logLevel: debug + scenarios: - name: web3_clientVersion flow: @@ -40,11 +39,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: web3_sha3 flow: @@ -60,11 +60,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: net_version flow: @@ -79,11 +80,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: net_listening flow: @@ -98,11 +100,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: net_peerCount flow: @@ -117,11 +120,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_chainId flow: @@ -136,11 +140,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getStorageAt flow: @@ -156,11 +161,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getTransactionByBlockHashAndIndex flow: @@ -176,11 +182,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getTransactionByBlockNumberAndIndex flow: @@ -197,11 +204,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getUncleByBlockHashAndIndex flow: @@ -217,11 +225,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getUncleByBlockNumberAndIndex flow: @@ -238,11 +247,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_newFilter flow: @@ -253,21 +263,20 @@ scenarios: jsonrpc: "2.0" method: "eth_newFilter" params: - - { - fromBlock: "latest", - toBlock: "latest", - address: "0x0", + - fromBlock: "latest" + toBlock: "latest" + address: "0x0" topics: [] - } capture: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getFilterChanges flow: @@ -283,11 +292,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getFilterLogs flow: @@ -303,11 +313,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_blockNumber flow: @@ -322,11 +333,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getBlockByHash flow: @@ -343,11 +355,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getBlockByNumber flow: @@ -364,11 +377,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getBlockTransactionCountByHash flow: @@ -384,11 +398,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getBlockTransactionCountByNumber flow: @@ -404,11 +419,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getCode flow: @@ -425,11 +441,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getTransactionByHash flow: @@ -445,11 +462,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getTransactionReceipt flow: @@ -465,11 +483,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getLogs flow: @@ -488,11 +507,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_getBalance flow: @@ -509,11 +529,12 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" - name: eth_estimateGas flow: @@ -529,8 +550,9 @@ scenarios: - json: "$" as: "response" ensure: - - statusCode: 200 - - statusCode: 201 - assert: - - subject: response.error - equals: null + - statusCode: + - 200 + - 201 + expect: + - type: "null" + subject: "response.error" \ No newline at end of file From 74d355f2aff722991d89f93cc1b82e521b242b5a Mon Sep 17 00:00:00 2001 From: Peter Lee Date: Tue, 1 Oct 2024 17:39:32 -0700 Subject: [PATCH 02/14] more fixes --- .github/actions/performance-tests/art.yaml | 141 +++++++++------------ 1 file changed, 59 insertions(+), 82 deletions(-) diff --git a/.github/actions/performance-tests/art.yaml b/.github/actions/performance-tests/art.yaml index 514d2a2cbf..a1ccf1418d 100644 --- a/.github/actions/performance-tests/art.yaml +++ b/.github/actions/performance-tests/art.yaml @@ -10,6 +10,7 @@ config: timeout: 60 plugins: expect: {} + ensure: {} metrics-by-endpoint: useOnlyRequestNames: true publish-metrics: @@ -37,14 +38,13 @@ scenarios: params: [] capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: web3_sha3 flow: @@ -58,14 +58,13 @@ scenarios: - "0x68656c6c6f20776f726c64" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: net_version flow: @@ -78,14 +77,13 @@ scenarios: params: [] capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: net_listening flow: @@ -98,14 +96,16 @@ scenarios: params: [] capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" + - equals: + - "true" + - "{{ response.result }}" - name: net_peerCount flow: @@ -118,14 +118,13 @@ scenarios: params: [] capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_chainId flow: @@ -138,14 +137,13 @@ scenarios: params: [] capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getStorageAt flow: @@ -159,14 +157,13 @@ scenarios: - "latest" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getTransactionByBlockHashAndIndex flow: @@ -180,14 +177,13 @@ scenarios: - "0x0" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getTransactionByBlockNumberAndIndex flow: @@ -202,14 +198,13 @@ scenarios: - "0x0" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getUncleByBlockHashAndIndex flow: @@ -223,14 +218,13 @@ scenarios: - "0x0" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getUncleByBlockNumberAndIndex flow: @@ -245,14 +239,13 @@ scenarios: - "0x0" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_newFilter flow: @@ -269,14 +262,13 @@ scenarios: topics: [] capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getFilterChanges flow: @@ -290,14 +282,13 @@ scenarios: - "0x0" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getFilterLogs flow: @@ -311,14 +302,13 @@ scenarios: - "0x0" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_blockNumber flow: @@ -331,14 +321,13 @@ scenarios: params: [] capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getBlockByHash flow: @@ -353,14 +342,13 @@ scenarios: - true capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getBlockByNumber flow: @@ -375,14 +363,13 @@ scenarios: - true capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getBlockTransactionCountByHash flow: @@ -396,14 +383,13 @@ scenarios: - "0x0" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getBlockTransactionCountByNumber flow: @@ -417,14 +403,13 @@ scenarios: - "latest" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getCode flow: @@ -435,18 +420,17 @@ scenarios: jsonrpc: "2.0" method: "eth_getCode" params: - - "0x0" + - "0x05BA149A7bd6dC1F937fA9046A9e05C05f3b18b0" - "latest" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getTransactionByHash flow: @@ -460,14 +444,13 @@ scenarios: - "0x0" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getTransactionReceipt flow: @@ -481,14 +464,13 @@ scenarios: - "0x0" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getLogs flow: @@ -499,20 +481,16 @@ scenarios: jsonrpc: "2.0" method: "eth_getLogs" params: - - fromBlock: "0x1" - toBlock: "latest" - address: "0x0" - topics: ["0x0"] + - address: "0x05BA149A7bd6dC1F937fA9046A9e05C05f3b18b0" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_getBalance flow: @@ -523,18 +501,17 @@ scenarios: jsonrpc: "2.0" method: "eth_getBalance" params: - - "0x0" + - "0x05BA149A7bd6dC1F937fA9046A9e05C05f3b18b0" - "latest" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" + - notHasProperty: "{{ response.error }}" - name: eth_estimateGas flow: @@ -545,14 +522,14 @@ scenarios: jsonrpc: "2.0" method: "eth_estimateGas" params: - - from: "0x0" + - from: "0x239e96c8f17C85c30100AC26F635Ea15f23E9c67" + to: "0x05BA149A7bd6dC1F937fA9046A9e05C05f3b18b0" capture: - json: "$" - as: "response" + as: response ensure: - statusCode: - 200 - 201 expect: - - type: "null" - subject: "response.error" \ No newline at end of file + - notHasProperty: "{{ response.error }}" \ No newline at end of file From 26640c2be5ed233be0b45d22aeb5c825476e100c Mon Sep 17 00:00:00 2001 From: skosito Date: Fri, 27 Sep 2024 12:38:40 +0100 Subject: [PATCH 03/14] feat: integrate authenticated calls smart contract functionality into protocol (#2904) * e2e tests and modifications for authenticated call * extend test with sender check and revert case * separate tests into separate files * cleanup * withdraw and call support and tests * bump protocol contracts * split tests into separate files * small cleanup * fmt * generate * lint * changelog * PR comments * fix case in proto * bump vote inbound gas limit in zetaclient * fix test * generate * fixing tests * call options non empty * generate * test fix * rename gateway caller * pr comments rename tests * PR comment * generate * tests * update tests fixes * tests fixes * fix * test fix --- changelog.md | 1 + cmd/zetae2e/local/v2.go | 4 + docs/cli/zetacored/cli.md | 2 +- docs/openapi/openapi.swagger.yaml | 11 + docs/spec/crosschain/messages.md | 1 + e2e/e2etests/e2etests.go | 34 +- ...test_v2_eth_withdraw_and_arbitrary_call.go | 40 ++ e2e/e2etests/test_v2_eth_withdraw_and_call.go | 30 +- ..._eth_withdraw_and_call_through_contract.go | 84 ++++ .../test_v2_zevm_to_evm_arbitrary_call.go | 36 ++ e2e/e2etests/test_v2_zevm_to_evm_call.go | 31 +- ...st_v2_zevm_to_evm_call_through_contract.go | 83 ++++ e2e/runner/logger.go | 1 + e2e/runner/v2_zevm.go | 99 +++- go.mod | 2 +- go.sum | 4 +- .../gatewayzevmcaller/GatewayZEVMCaller.abi | 251 ++++++++++ .../gatewayzevmcaller/GatewayZEVMCaller.bin | 1 + .../gatewayzevmcaller/GatewayZEVMCaller.go | 302 ++++++++++++ .../gatewayzevmcaller/GatewayZEVMCaller.json | 254 ++++++++++ .../gatewayzevmcaller/GatewayZEVMCaller.sol | 103 ++++ pkg/contracts/gatewayzevmcaller/bindings.go | 8 + pkg/contracts/testdappv2/TestDAppV2.abi | 76 +++ pkg/contracts/testdappv2/TestDAppV2.bin | 2 +- pkg/contracts/testdappv2/TestDAppV2.go | 113 ++++- pkg/contracts/testdappv2/TestDAppV2.json | 78 +++- pkg/contracts/testdappv2/TestDAppV2.sol | 20 + .../zetacore/crosschain/cross_chain_tx.proto | 8 + proto/zetachain/zetacore/crosschain/tx.proto | 3 + testutil/sample/crosschain.go | 40 +- .../crosschain/cross_chain_tx_pb.d.ts | 36 ++ .../zetachain/zetacore/crosschain/tx_pb.d.ts | 9 +- x/crosschain/client/cli/tx_vote_inbound.go | 8 +- x/crosschain/keeper/abci.go | 4 +- x/crosschain/keeper/abci_test.go | 54 ++- ...cctx_orchestrator_validate_inbound_test.go | 60 ++- .../cctx_orchestrator_validate_outbound.go | 2 +- x/crosschain/keeper/cctx_test.go | 14 +- x/crosschain/keeper/evm_hooks.go | 4 +- x/crosschain/keeper/gas_payment.go | 6 +- x/crosschain/keeper/gas_payment_test.go | 22 +- .../msg_server_migrate_tss_funds_test.go | 2 +- .../keeper/msg_server_vote_inbound_tx_test.go | 28 +- x/crosschain/keeper/v2_zevm_inbound.go | 19 +- x/crosschain/types/cctx.go | 32 +- x/crosschain/types/cctx_test.go | 40 +- x/crosschain/types/cmd_cctxs.go | 10 +- x/crosschain/types/cmd_cctxs_test.go | 15 +- x/crosschain/types/cross_chain_tx.pb.go | 440 ++++++++++++++---- x/crosschain/types/message_vote_inbound.go | 26 +- .../types/message_vote_inbound_test.go | 41 +- x/crosschain/types/tx.pb.go | 304 +++++++----- zetaclient/chains/bitcoin/signer/signer.go | 2 +- zetaclient/chains/evm/observer/v2_inbound.go | 2 + zetaclient/chains/evm/signer/gas.go | 6 +- zetaclient/chains/evm/signer/gas_test.go | 2 +- zetaclient/chains/evm/signer/outbound_data.go | 2 +- zetaclient/chains/evm/signer/v2_sign.go | 25 +- zetaclient/chains/evm/signer/v2_signer.go | 2 +- .../testdata/cctx/chain_1337_cctx_14.go | 24 +- zetaclient/testdata/cctx/chain_1_cctx_6270.go | 14 +- zetaclient/testdata/cctx/chain_1_cctx_7260.go | 14 +- zetaclient/testdata/cctx/chain_1_cctx_8014.go | 14 +- zetaclient/testdata/cctx/chain_1_cctx_9718.go | 14 +- ...c3b990e076e2a4bffeb616035b239b7d33843da.go | 16 +- ...e01cbdf59154fd793ea7a22c297f7c3a722c532.go | 16 +- ...71ffc40ca898e134525c42c2ae3cbc5725f9d76.go | 16 +- .../testdata/cctx/chain_56_cctx_68270.go | 14 +- .../testdata/cctx/chain_8332_cctx_148.go | 14 +- zetaclient/zetacore/constant.go | 2 +- zetaclient/zetacore/tx.go | 1 + 71 files changed, 2620 insertions(+), 478 deletions(-) create mode 100644 e2e/e2etests/test_v2_eth_withdraw_and_arbitrary_call.go create mode 100644 e2e/e2etests/test_v2_eth_withdraw_and_call_through_contract.go create mode 100644 e2e/e2etests/test_v2_zevm_to_evm_arbitrary_call.go create mode 100644 e2e/e2etests/test_v2_zevm_to_evm_call_through_contract.go create mode 100644 pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.abi create mode 100644 pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.bin create mode 100644 pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.go create mode 100644 pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.json create mode 100644 pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.sol create mode 100644 pkg/contracts/gatewayzevmcaller/bindings.go diff --git a/changelog.md b/changelog.md index ea6a525170..f7fa79185d 100644 --- a/changelog.md +++ b/changelog.md @@ -13,6 +13,7 @@ * [2883](https://github.com/zeta-chain/node/pull/2883) - add chain static information for btc signet testnet * [2907](https://github.com/zeta-chain/node/pull/2907) - derive Bitcoin tss address by chain id and added more Signet static info * [2911](https://github.com/zeta-chain/node/pull/2911) - add chain static information for btc testnet4 +* [2904](https://github.com/zeta-chain/node/pull/2904) - integrate authenticated calls smart contract functionality into protocol ### Refactor diff --git a/cmd/zetae2e/local/v2.go b/cmd/zetae2e/local/v2.go index ce193bc32e..fa98ef6677 100644 --- a/cmd/zetae2e/local/v2.go +++ b/cmd/zetae2e/local/v2.go @@ -19,8 +19,12 @@ func startV2Tests(eg *errgroup.Group, conf config.Config, deployerRunner *runner e2etests.TestV2ETHDepositName, e2etests.TestV2ETHDepositAndCallName, e2etests.TestV2ETHWithdrawName, + e2etests.TestV2ETHWithdrawAndArbitraryCallName, e2etests.TestV2ETHWithdrawAndCallName, + e2etests.TestV2ETHWithdrawAndCallThroughContractName, + e2etests.TestV2ZEVMToEVMArbitraryCallName, e2etests.TestV2ZEVMToEVMCallName, + e2etests.TestV2ZEVMToEVMCallThroughContractName, e2etests.TestV2EVMToZEVMCallName, )) diff --git a/docs/cli/zetacored/cli.md b/docs/cli/zetacored/cli.md index a8719cf83f..36440f2704 100644 --- a/docs/cli/zetacored/cli.md +++ b/docs/cli/zetacored/cli.md @@ -9441,7 +9441,7 @@ zetacored tx crosschain vote-gas-price [chain] [price] [priorityFee] [blockNumbe Broadcast message to vote an inbound ``` -zetacored tx crosschain vote-inbound [sender] [senderChainID] [txOrigin] [receiver] [receiverChainID] [amount] [message] [inboundHash] [inBlockHeight] [coinType] [asset] [eventIndex] [protocolContractVersion] [flags] +zetacored tx crosschain vote-inbound [sender] [senderChainID] [txOrigin] [receiver] [receiverChainID] [amount] [message] [inboundHash] [inBlockHeight] [coinType] [asset] [eventIndex] [protocolContractVersion] [isArbitraryCall] [flags] ``` ### Options diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 26c2c2cb9d..a8c0a2516e 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -57066,6 +57066,14 @@ definitions: - ERC20: ERC20 token - Cmd: no asset, used for admin command - NoAssetCall: no asset, used for contract call + crosschainCallOptions: + type: object + properties: + gas_limit: + type: string + format: uint64 + is_arbitrary_call: + type: boolean crosschainCctxStatus: type: string enum: @@ -57276,6 +57284,7 @@ definitions: gas_limit: type: string format: uint64 + title: Deprecated (v21), use CallOptions gas_price: type: string gas_priority_fee: @@ -57302,6 +57311,8 @@ definitions: type: string tx_finalization_status: $ref: '#/definitions/crosschainTxFinalizationStatus' + call_options: + $ref: '#/definitions/crosschainCallOptions' crosschainOutboundTracker: type: object properties: diff --git a/docs/spec/crosschain/messages.md b/docs/spec/crosschain/messages.md index f2fba7cd1d..c369443d27 100644 --- a/docs/spec/crosschain/messages.md +++ b/docs/spec/crosschain/messages.md @@ -189,6 +189,7 @@ message MsgVoteInbound { uint64 event_index = 15; ProtocolContractVersion protocol_contract_version = 16; RevertOptions revert_options = 17; + CallOptions call_options = 18; } ``` diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index dd9409e4cf..08314f9300 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -131,7 +131,9 @@ const ( TestV2ETHDepositAndCallRevertName = "v2_eth_deposit_and_call_revert" TestV2ETHDepositAndCallRevertWithCallName = "v2_eth_deposit_and_call_revert_with_call" TestV2ETHWithdrawName = "v2_eth_withdraw" + TestV2ETHWithdrawAndArbitraryCallName = "v2_eth_withdraw_and_arbitrary_call" TestV2ETHWithdrawAndCallName = "v2_eth_withdraw_and_call" + TestV2ETHWithdrawAndCallThroughContractName = "v2_eth_withdraw_and_call_through_contract" TestV2ETHWithdrawAndCallRevertName = "v2_eth_withdraw_and_call_revert" TestV2ETHWithdrawAndCallRevertWithCallName = "v2_eth_withdraw_and_call_revert_with_call" TestV2ERC20DepositName = "v2_erc20_deposit" @@ -142,7 +144,9 @@ const ( TestV2ERC20WithdrawAndCallName = "v2_erc20_withdraw_and_call" TestV2ERC20WithdrawAndCallRevertName = "v2_erc20_withdraw_and_call_revert" TestV2ERC20WithdrawAndCallRevertWithCallName = "v2_erc20_withdraw_and_call_revert_with_call" + TestV2ZEVMToEVMArbitraryCallName = "v2_zevm_to_evm_arbitrary_call" TestV2ZEVMToEVMCallName = "v2_zevm_to_evm_call" + TestV2ZEVMToEVMCallThroughContractName = "v2_zevm_to_evm_call_through_contract" TestV2EVMToZEVMCallName = "v2_evm_to_zevm_call" /* @@ -731,13 +735,29 @@ var AllE2ETests = []runner.E2ETest{ TestV2ETHWithdraw, ), runner.NewE2ETest( - TestV2ETHWithdrawAndCallName, + TestV2ETHWithdrawAndArbitraryCallName, "withdraw Ether from ZEVM and call a contract using V2 contract", []runner.ArgDefinition{ {Description: "amount in wei", DefaultValue: "100000"}, }, + TestV2ETHWithdrawAndArbitraryCall, + ), + runner.NewE2ETest( + TestV2ETHWithdrawAndCallName, + "withdraw Ether from ZEVM call a contract using V2 contract", + []runner.ArgDefinition{ + {Description: "amount in wei", DefaultValue: "100000"}, + }, TestV2ETHWithdrawAndCall, ), + runner.NewE2ETest( + TestV2ETHWithdrawAndCallThroughContractName, + "withdraw Ether from ZEVM call a contract using V2 contract through intermediary contract", + []runner.ArgDefinition{ + {Description: "amount in wei", DefaultValue: "100000"}, + }, + TestV2ETHWithdrawAndCallThroughContract, + ), runner.NewE2ETest( TestV2ETHWithdrawAndCallRevertName, "withdraw Ether from ZEVM and call a contract using V2 contract that reverts", @@ -818,12 +838,24 @@ var AllE2ETests = []runner.E2ETest{ }, TestV2ERC20WithdrawAndCallRevertWithCall, ), + runner.NewE2ETest( + TestV2ZEVMToEVMArbitraryCallName, + "zevm -> evm call using V2 contract", + []runner.ArgDefinition{}, + TestV2ZEVMToEVMArbitraryCall, + ), runner.NewE2ETest( TestV2ZEVMToEVMCallName, "zevm -> evm call using V2 contract", []runner.ArgDefinition{}, TestV2ZEVMToEVMCall, ), + runner.NewE2ETest( + TestV2ZEVMToEVMCallThroughContractName, + "zevm -> evm call using V2 contract through intermediary contract", + []runner.ArgDefinition{}, + TestV2ZEVMToEVMCallThroughContract, + ), runner.NewE2ETest( TestV2EVMToZEVMCallName, "evm -> zevm call using V2 contract", diff --git a/e2e/e2etests/test_v2_eth_withdraw_and_arbitrary_call.go b/e2e/e2etests/test_v2_eth_withdraw_and_arbitrary_call.go new file mode 100644 index 0000000000..932034d963 --- /dev/null +++ b/e2e/e2etests/test_v2_eth_withdraw_and_arbitrary_call.go @@ -0,0 +1,40 @@ +package e2etests + +import ( + "math/big" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol" + + "github.com/zeta-chain/node/e2e/runner" + "github.com/zeta-chain/node/e2e/utils" + crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" +) + +const payloadMessageWithdrawETH = "this is a test ETH withdraw and call payload" + +func TestV2ETHWithdrawAndArbitraryCall(r *runner.E2ERunner, args []string) { + require.Len(r, args, 1) + + amount, ok := big.NewInt(0).SetString(args[0], 10) + require.True(r, ok, "Invalid amount specified for TestV2ETHWithdrawAndCall") + + r.AssertTestDAppEVMCalled(false, payloadMessageWithdrawETH, amount) + + r.ApproveETHZRC20(r.GatewayZEVMAddr) + + // perform the withdraw + tx := r.V2ETHWithdrawAndCall( + r.TestDAppV2EVMAddr, + amount, + r.EncodeGasCall(payloadMessageWithdrawETH), + gatewayzevm.RevertOptions{OnRevertGasLimit: big.NewInt(0)}, + ) + + // wait for the cctx to be mined + cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) + r.Logger.CCTX(*cctx, "withdraw") + require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctx.CctxStatus.Status) + + r.AssertTestDAppEVMCalled(true, payloadMessageWithdrawETH, amount) +} diff --git a/e2e/e2etests/test_v2_eth_withdraw_and_call.go b/e2e/e2etests/test_v2_eth_withdraw_and_call.go index 40194c93ba..de0cadabcf 100644 --- a/e2e/e2etests/test_v2_eth_withdraw_and_call.go +++ b/e2e/e2etests/test_v2_eth_withdraw_and_call.go @@ -3,6 +3,7 @@ package e2etests import ( "math/big" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/stretchr/testify/require" "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol" @@ -11,23 +12,34 @@ import ( crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" ) -const payloadMessageWithdrawETH = "this is a test ETH withdraw and call payload" +const payloadMessageAuthenticatedWithdrawETH = "this is a test ETH withdraw and authenticated call payload" func TestV2ETHWithdrawAndCall(r *runner.E2ERunner, args []string) { require.Len(r, args, 1) + previousGasLimit := r.ZEVMAuth.GasLimit + r.ZEVMAuth.GasLimit = 10000000 + defer func() { + r.ZEVMAuth.GasLimit = previousGasLimit + }() + amount, ok := big.NewInt(0).SetString(args[0], 10) require.True(r, ok, "Invalid amount specified for TestV2ETHWithdrawAndCall") - r.AssertTestDAppEVMCalled(false, payloadMessageWithdrawETH, amount) + r.AssertTestDAppEVMCalled(false, payloadMessageAuthenticatedWithdrawETH, amount) r.ApproveETHZRC20(r.GatewayZEVMAddr) + // set expected sender + tx, err := r.TestDAppV2EVM.SetExpectedOnCallSender(r.EVMAuth, r.ZEVMAuth.From) + require.NoError(r, err) + utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + // perform the withdraw - tx := r.V2ETHWithdrawAndCall( + tx = r.V2ETHWithdrawAndAuthenticatedCall( r.TestDAppV2EVMAddr, amount, - r.EncodeGasCall(payloadMessageWithdrawETH), + []byte(payloadMessageAuthenticatedWithdrawETH), gatewayzevm.RevertOptions{OnRevertGasLimit: big.NewInt(0)}, ) @@ -36,5 +48,13 @@ func TestV2ETHWithdrawAndCall(r *runner.E2ERunner, args []string) { r.Logger.CCTX(*cctx, "withdraw") require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctx.CctxStatus.Status) - r.AssertTestDAppEVMCalled(true, payloadMessageWithdrawETH, amount) + r.AssertTestDAppEVMCalled(true, payloadMessageAuthenticatedWithdrawETH, amount) + + // check expected sender was used + senderForMsg, err := r.TestDAppV2EVM.SenderWithMessage( + &bind.CallOpts{}, + []byte(payloadMessageAuthenticatedWithdrawETH), + ) + require.NoError(r, err) + require.Equal(r, r.ZEVMAuth.From, senderForMsg) } diff --git a/e2e/e2etests/test_v2_eth_withdraw_and_call_through_contract.go b/e2e/e2etests/test_v2_eth_withdraw_and_call_through_contract.go new file mode 100644 index 0000000000..f2d4949032 --- /dev/null +++ b/e2e/e2etests/test_v2_eth_withdraw_and_call_through_contract.go @@ -0,0 +1,84 @@ +package e2etests + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" + + "github.com/zeta-chain/node/e2e/runner" + "github.com/zeta-chain/node/e2e/utils" + gatewayzevmcaller "github.com/zeta-chain/node/pkg/contracts/gatewayzevmcaller" + crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" +) + +const payloadMessageAuthenticatedWithdrawETHThroughContract = "this is a test ETH withdraw and authenticated call payload through contract" + +func TestV2ETHWithdrawAndCallThroughContract(r *runner.E2ERunner, args []string) { + require.Len(r, args, 1) + + previousGasLimit := r.ZEVMAuth.GasLimit + r.ZEVMAuth.GasLimit = 10000000 + defer func() { + r.ZEVMAuth.GasLimit = previousGasLimit + }() + + amount, ok := big.NewInt(0).SetString(args[0], 10) + require.True(r, ok, "Invalid amount specified for TestV2ETHWithdrawAndCall") + + // deploy caller contract and send it gas zrc20 to pay gas fee + gatewayCallerAddr, tx, gatewayCaller, err := gatewayzevmcaller.DeployGatewayZEVMCaller( + r.ZEVMAuth, + r.ZEVMClient, + r.GatewayZEVMAddr, + r.WZetaAddr, + ) + require.NoError(r, err) + utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + + tx, err = r.ETHZRC20.Transfer(r.ZEVMAuth, gatewayCallerAddr, big.NewInt(100000000000000000)) + require.NoError(r, err) + utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + + // set expected sender + tx, err = r.TestDAppV2EVM.SetExpectedOnCallSender(r.EVMAuth, gatewayCallerAddr) + require.NoError(r, err) + utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + + // perform the authenticated call + tx = r.V2ETHWithdrawAndAuthenticatedCallThroughContract(gatewayCaller, r.TestDAppV2EVMAddr, + amount, + []byte(payloadMessageAuthenticatedWithdrawETHThroughContract), + gatewayzevmcaller.RevertOptions{OnRevertGasLimit: big.NewInt(0)}) + + utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) + r.Logger.CCTX(*cctx, "withdraw") + require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctx.CctxStatus.Status) + + r.AssertTestDAppEVMCalled(true, payloadMessageAuthenticatedWithdrawETHThroughContract, amount) + + // check expected sender was used + senderForMsg, err := r.TestDAppV2EVM.SenderWithMessage( + &bind.CallOpts{}, + []byte(payloadMessageAuthenticatedWithdrawETHThroughContract), + ) + require.NoError(r, err) + require.Equal(r, gatewayCallerAddr, senderForMsg) + + // set expected sender to wrong one + tx, err = r.TestDAppV2EVM.SetExpectedOnCallSender(r.EVMAuth, r.ZEVMAuth.From) + require.NoError(r, err) + utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + + // repeat authenticated call through contract, should revert because of wrong sender + tx = r.V2ETHWithdrawAndAuthenticatedCallThroughContract(gatewayCaller, r.TestDAppV2EVMAddr, + amount, + []byte(payloadMessageAuthenticatedWithdrawETHThroughContract), + gatewayzevmcaller.RevertOptions{OnRevertGasLimit: big.NewInt(0)}) + + utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + cctx = utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) + r.Logger.CCTX(*cctx, "withdraw") + require.Equal(r, crosschaintypes.CctxStatus_Reverted, cctx.CctxStatus.Status) +} diff --git a/e2e/e2etests/test_v2_zevm_to_evm_arbitrary_call.go b/e2e/e2etests/test_v2_zevm_to_evm_arbitrary_call.go new file mode 100644 index 0000000000..21104767f9 --- /dev/null +++ b/e2e/e2etests/test_v2_zevm_to_evm_arbitrary_call.go @@ -0,0 +1,36 @@ +package e2etests + +import ( + "math/big" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol" + + "github.com/zeta-chain/node/e2e/runner" + "github.com/zeta-chain/node/e2e/utils" + crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" +) + +const payloadMessageEVMCall = "this is a test EVM call payload" + +func TestV2ZEVMToEVMArbitraryCall(r *runner.E2ERunner, args []string) { + require.Len(r, args, 0) + + r.AssertTestDAppEVMCalled(false, payloadMessageEVMCall, big.NewInt(0)) + + // Necessary approval for fee payment + r.ApproveETHZRC20(r.GatewayZEVMAddr) + + // perform the call + tx := r.V2ZEVMToEMVCall(r.TestDAppV2EVMAddr, r.EncodeSimpleCall(payloadMessageEVMCall), gatewayzevm.RevertOptions{ + OnRevertGasLimit: big.NewInt(0), + }) + + // wait for the cctx to be mined + cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) + r.Logger.CCTX(*cctx, "call") + require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctx.CctxStatus.Status) + + // check the payload was received on the contract + r.AssertTestDAppEVMCalled(true, payloadMessageEVMCall, big.NewInt(0)) +} diff --git a/e2e/e2etests/test_v2_zevm_to_evm_call.go b/e2e/e2etests/test_v2_zevm_to_evm_call.go index c38d328db8..ba9d5fba6f 100644 --- a/e2e/e2etests/test_v2_zevm_to_evm_call.go +++ b/e2e/e2etests/test_v2_zevm_to_evm_call.go @@ -3,6 +3,7 @@ package e2etests import ( "math/big" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/stretchr/testify/require" "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol" @@ -11,20 +12,29 @@ import ( crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" ) -const payloadMessageEVMCall = "this is a test EVM call payload" +const payloadMessageEVMAuthenticatedCall = "this is a test EVM authenticated call payload" func TestV2ZEVMToEVMCall(r *runner.E2ERunner, args []string) { require.Len(r, args, 0) - r.AssertTestDAppEVMCalled(false, payloadMessageEVMCall, big.NewInt(0)) + r.AssertTestDAppEVMCalled(false, payloadMessageEVMAuthenticatedCall, big.NewInt(0)) - // Necessary approval for fee payment + // necessary approval for fee payment r.ApproveETHZRC20(r.GatewayZEVMAddr) - // perform the withdraw - tx := r.V2ZEVMToEMVCall(r.TestDAppV2EVMAddr, r.EncodeSimpleCall(payloadMessageEVMCall), gatewayzevm.RevertOptions{ - OnRevertGasLimit: big.NewInt(0), - }) + // set expected sender + tx, err := r.TestDAppV2EVM.SetExpectedOnCallSender(r.EVMAuth, r.ZEVMAuth.From) + require.NoError(r, err) + utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + + // perform the authenticated call + tx = r.V2ZEVMToEMVAuthenticatedCall( + r.TestDAppV2EVMAddr, + []byte(payloadMessageEVMAuthenticatedCall), + gatewayzevm.RevertOptions{ + OnRevertGasLimit: big.NewInt(0), + }, + ) // wait for the cctx to be mined cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) @@ -32,5 +42,10 @@ func TestV2ZEVMToEVMCall(r *runner.E2ERunner, args []string) { require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctx.CctxStatus.Status) // check the payload was received on the contract - r.AssertTestDAppEVMCalled(true, payloadMessageEVMCall, big.NewInt(0)) + r.AssertTestDAppEVMCalled(true, payloadMessageEVMAuthenticatedCall, big.NewInt(0)) + + // check expected sender was used + senderForMsg, err := r.TestDAppV2EVM.SenderWithMessage(&bind.CallOpts{}, []byte(payloadMessageEVMAuthenticatedCall)) + require.NoError(r, err) + require.Equal(r, r.ZEVMAuth.From, senderForMsg) } diff --git a/e2e/e2etests/test_v2_zevm_to_evm_call_through_contract.go b/e2e/e2etests/test_v2_zevm_to_evm_call_through_contract.go new file mode 100644 index 0000000000..a46b9f09f9 --- /dev/null +++ b/e2e/e2etests/test_v2_zevm_to_evm_call_through_contract.go @@ -0,0 +1,83 @@ +package e2etests + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" + + "github.com/zeta-chain/node/e2e/runner" + "github.com/zeta-chain/node/e2e/utils" + gatewayzevmcaller "github.com/zeta-chain/node/pkg/contracts/gatewayzevmcaller" + crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" +) + +const payloadMessageEVMAuthenticatedCallThroughContract = "this is a test EVM authenticated call payload through contract" + +func TestV2ZEVMToEVMCallThroughContract(r *runner.E2ERunner, args []string) { + require.Len(r, args, 0) + + r.AssertTestDAppEVMCalled(false, payloadMessageEVMAuthenticatedCallThroughContract, big.NewInt(0)) + + // deploy caller contract and send it gas zrc20 to pay gas fee + gatewayCallerAddr, tx, gatewayCaller, err := gatewayzevmcaller.DeployGatewayZEVMCaller( + r.ZEVMAuth, + r.ZEVMClient, + r.GatewayZEVMAddr, + r.WZetaAddr, + ) + require.NoError(r, err) + utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + + tx, err = r.ETHZRC20.Transfer(r.ZEVMAuth, gatewayCallerAddr, big.NewInt(100000000000000000)) + require.NoError(r, err) + utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + + // set expected sender + tx, err = r.TestDAppV2EVM.SetExpectedOnCallSender(r.EVMAuth, gatewayCallerAddr) + require.NoError(r, err) + utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + + // perform the authenticated call + tx = r.V2ZEVMToEMVAuthenticatedCallThroughContract( + gatewayCaller, + r.TestDAppV2EVMAddr, + []byte(payloadMessageEVMAuthenticatedCallThroughContract), + gatewayzevmcaller.RevertOptions{ + OnRevertGasLimit: big.NewInt(0), + }, + ) + utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) + r.Logger.CCTX(*cctx, "call") + require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctx.CctxStatus.Status) + + r.AssertTestDAppEVMCalled(true, payloadMessageEVMAuthenticatedCallThroughContract, big.NewInt(0)) + + // check expected sender was used + senderForMsg, err := r.TestDAppV2EVM.SenderWithMessage( + &bind.CallOpts{}, + []byte(payloadMessageEVMAuthenticatedCallThroughContract), + ) + require.NoError(r, err) + require.Equal(r, gatewayCallerAddr, senderForMsg) + + // set expected sender to wrong one + tx, err = r.TestDAppV2EVM.SetExpectedOnCallSender(r.EVMAuth, r.ZEVMAuth.From) + require.NoError(r, err) + utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + + // repeat authenticated call through contract, should revert because of wrong sender + tx = r.V2ZEVMToEMVAuthenticatedCallThroughContract( + gatewayCaller, + r.TestDAppV2EVMAddr, + []byte(payloadMessageEVMAuthenticatedCallThroughContract), + gatewayzevmcaller.RevertOptions{ + OnRevertGasLimit: big.NewInt(0), + }, + ) + utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + cctx = utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) + r.Logger.CCTX(*cctx, "call") + require.Equal(r, crosschaintypes.CctxStatus_Reverted, cctx.CctxStatus.Status) +} diff --git a/e2e/runner/logger.go b/e2e/runner/logger.go index 16b34836f4..24f9c8f7bc 100644 --- a/e2e/runner/logger.go +++ b/e2e/runner/logger.go @@ -153,6 +153,7 @@ func (l *Logger) CCTX(cctx crosschaintypes.CrossChainTx, name string) { l.Info(" TxHeight: %d", outTxParam.ObservedExternalHeight) l.Info(" BallotIndex: %s", outTxParam.BallotIndex) l.Info(" TSSNonce: %d", outTxParam.TssNonce) + l.Info(" CallOptions: %+v", outTxParam.CallOptions) l.Info(" GasLimit: %d", outTxParam.GasLimit) l.Info(" GasPrice: %s", outTxParam.GasPrice) l.Info(" GasUsed: %d", outTxParam.GasUsed) diff --git a/e2e/runner/v2_zevm.go b/e2e/runner/v2_zevm.go index 681696b195..4824884bd0 100644 --- a/e2e/runner/v2_zevm.go +++ b/e2e/runner/v2_zevm.go @@ -7,6 +7,8 @@ import ( ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/require" "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol" + + gatewayzevmcaller "github.com/zeta-chain/node/pkg/contracts/gatewayzevmcaller" ) var gasLimit = big.NewInt(1000000) @@ -50,6 +52,56 @@ func (r *E2ERunner) V2ETHWithdrawAndCall( return tx } +// V2ETHWithdrawAndCall calls WithdrawAndCall of Gateway with gas token on ZEVM using authenticated call +func (r *E2ERunner) V2ETHWithdrawAndAuthenticatedCall( + receiver ethcommon.Address, + amount *big.Int, + payload []byte, + revertOptions gatewayzevm.RevertOptions, +) *ethtypes.Transaction { + tx, err := r.GatewayZEVM.WithdrawAndCall2( + r.ZEVMAuth, + receiver.Bytes(), + amount, + r.ETHZRC20Addr, + payload, + gatewayzevm.CallOptions{ + IsArbitraryCall: false, + GasLimit: gasLimit, + }, + revertOptions, + ) + require.NoError(r, err) + + return tx +} + +// V2ETHWithdrawAndCall calls WithdrawAndCall of Gateway with gas token on ZEVM using authenticated call +// through contract +func (r *E2ERunner) V2ETHWithdrawAndAuthenticatedCallThroughContract( + gatewayZEVMCaller *gatewayzevmcaller.GatewayZEVMCaller, + receiver ethcommon.Address, + amount *big.Int, + payload []byte, + revertOptions gatewayzevmcaller.RevertOptions, +) *ethtypes.Transaction { + tx, err := gatewayZEVMCaller.WithdrawAndCallGatewayZEVM( + r.ZEVMAuth, + receiver.Bytes(), + amount, + r.ETHZRC20Addr, + payload, + gatewayzevmcaller.CallOptions{ + IsArbitraryCall: false, + GasLimit: gasLimit, + }, + revertOptions, + ) + require.NoError(r, err) + + return tx +} + // V2ERC20Withdraw calls Withdraw of Gateway with erc20 token on ZEVM func (r *E2ERunner) V2ERC20Withdraw( receiver ethcommon.Address, @@ -103,7 +155,7 @@ func (r *E2ERunner) V2ZEVMToEMVCall( payload []byte, revertOptions gatewayzevm.RevertOptions, ) *ethtypes.Transaction { - tx, err := r.GatewayZEVM.Call( + tx, err := r.GatewayZEVM.Call0( r.ZEVMAuth, receiver.Bytes(), r.ETHZRC20Addr, @@ -115,3 +167,48 @@ func (r *E2ERunner) V2ZEVMToEMVCall( return tx } + +// V2ZEVMToEMVCall calls authenticated Call of Gateway on ZEVM +func (r *E2ERunner) V2ZEVMToEMVAuthenticatedCall( + receiver ethcommon.Address, + payload []byte, + revertOptions gatewayzevm.RevertOptions, +) *ethtypes.Transaction { + tx, err := r.GatewayZEVM.Call( + r.ZEVMAuth, + receiver.Bytes(), + r.ETHZRC20Addr, + payload, + gatewayzevm.CallOptions{ + GasLimit: gasLimit, + IsArbitraryCall: false, + }, + revertOptions, + ) + require.NoError(r, err) + + return tx +} + +// V2ZEVMToEMVCall calls authenticated Call of Gateway on ZEVM through contract +func (r *E2ERunner) V2ZEVMToEMVAuthenticatedCallThroughContract( + gatewayZEVMCaller *gatewayzevmcaller.GatewayZEVMCaller, + receiver ethcommon.Address, + payload []byte, + revertOptions gatewayzevmcaller.RevertOptions, +) *ethtypes.Transaction { + tx, err := gatewayZEVMCaller.CallGatewayZEVM( + r.ZEVMAuth, + receiver.Bytes(), + r.ETHZRC20Addr, + payload, + gatewayzevmcaller.CallOptions{ + GasLimit: gasLimit, + IsArbitraryCall: false, + }, + revertOptions, + ) + require.NoError(r, err) + + return tx +} diff --git a/go.mod b/go.mod index ef1e1de174..17899e5ccb 100644 --- a/go.mod +++ b/go.mod @@ -59,7 +59,7 @@ require ( github.com/stretchr/testify v1.9.0 github.com/zeta-chain/ethermint v0.0.0-20240909234716-2fad916e7179 github.com/zeta-chain/keystone/keys v0.0.0-20240826165841-3874f358c138 - github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240819143729-b8229cd7b410 + github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240920151810-cabe34920d52 gitlab.com/thorchain/tss/go-tss v1.6.5 go.nhat.io/grpcmock v0.25.0 golang.org/x/crypto v0.23.0 diff --git a/go.sum b/go.sum index e47729265c..972c2695ce 100644 --- a/go.sum +++ b/go.sum @@ -4182,8 +4182,8 @@ github.com/zeta-chain/go-tss v0.0.0-20240916173049-89fee4b0ae7f h1:XqUvw9a3EnDa2 github.com/zeta-chain/go-tss v0.0.0-20240916173049-89fee4b0ae7f/go.mod h1:B1FDE6kHs8hozKSX1/iXgCdvlFbS6+FeAupoBHDK0Cc= github.com/zeta-chain/keystone/keys v0.0.0-20240826165841-3874f358c138 h1:vck/FcIIpFOvpBUm0NO17jbEtmSz/W/a5Y4jRuSJl6I= github.com/zeta-chain/keystone/keys v0.0.0-20240826165841-3874f358c138/go.mod h1:U494OsZTWsU75hqoriZgMdSsgSGP1mUL1jX+wN/Aez8= -github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240819143729-b8229cd7b410 h1:sBeVX63s/qmfT1KnIKj1Y2SK3PsFpAM/P49ODcD1CN8= -github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240819143729-b8229cd7b410/go.mod h1:SjT7QirtJE8stnAe1SlNOanxtfSfijJm3MGJ+Ax7w7w= +github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240920151810-cabe34920d52 h1:DlSY9awQteXVmvY0lPD4Or83iuL4P5KwSGky+n4mYio= +github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240920151810-cabe34920d52/go.mod h1:SjT7QirtJE8stnAe1SlNOanxtfSfijJm3MGJ+Ax7w7w= github.com/zeta-chain/tss-lib v0.0.0-20240916163010-2e6b438bd901 h1:9whtN5fjYHfk4yXIuAsYP2EHxImwDWDVUOnZJ2pfL3w= github.com/zeta-chain/tss-lib v0.0.0-20240916163010-2e6b438bd901/go.mod h1:d2iTC62s9JwKiCMPhcDDXbIZmuzAyJ4lwso0H5QyRbk= github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= diff --git a/pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.abi b/pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.abi new file mode 100644 index 0000000000..373cc949b7 --- /dev/null +++ b/pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.abi @@ -0,0 +1,251 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "gatewayZEVMAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "wzetaAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "receiver", + "type": "bytes" + }, + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isArbitraryCall", + "type": "bool" + } + ], + "internalType": "struct CallOptions", + "name": "callOptions", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "revertAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "callOnRevert", + "type": "bool" + }, + { + "internalType": "address", + "name": "abortAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "revertMessage", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "onRevertGasLimit", + "type": "uint256" + } + ], + "internalType": "struct RevertOptions", + "name": "revertOptions", + "type": "tuple" + } + ], + "name": "callGatewayZEVM", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositWZETA", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "receiver", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isArbitraryCall", + "type": "bool" + } + ], + "internalType": "struct CallOptions", + "name": "callOptions", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "revertAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "callOnRevert", + "type": "bool" + }, + { + "internalType": "address", + "name": "abortAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "revertMessage", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "onRevertGasLimit", + "type": "uint256" + } + ], + "internalType": "struct RevertOptions", + "name": "revertOptions", + "type": "tuple" + } + ], + "name": "withdrawAndCallGatewayZEVM", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "receiver", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isArbitraryCall", + "type": "bool" + } + ], + "internalType": "struct CallOptions", + "name": "callOptions", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "revertAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "callOnRevert", + "type": "bool" + }, + { + "internalType": "address", + "name": "abortAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "revertMessage", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "onRevertGasLimit", + "type": "uint256" + } + ], + "internalType": "struct RevertOptions", + "name": "revertOptions", + "type": "tuple" + } + ], + "name": "withdrawAndCallGatewayZEVM", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.bin b/pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.bin new file mode 100644 index 0000000000..f0626b3dc0 --- /dev/null +++ b/pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.bin @@ -0,0 +1 @@ +60806040523480156200001157600080fd5b50604051620011613803806200116183398181016040528101906200003791906200012a565b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505062000171565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000f282620000c5565b9050919050565b6200010481620000e5565b81146200011057600080fd5b50565b6000815190506200012481620000f9565b92915050565b60008060408385031215620001445762000143620000c0565b5b6000620001548582860162000113565b9250506020620001678582860162000113565b9150509250929050565b610fe080620001816000396000f3fe60806040526004361061003f5760003560e01c806325859e62146100445780632c5d24ae1461006d57806362543ae714610077578063f66f4625146100a0575b600080fd5b34801561005057600080fd5b5061006b60048036038101906100669190610795565b6100c9565b005b61007561020d565b005b34801561008357600080fd5b5061009e6004803603810190610099919061089d565b610292565b005b3480156100ac57600080fd5b506100c760048036038101906100c29190610984565b6103d9565b005b8473ffffffffffffffffffffffffffffffffffffffff1663095ea7b360008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1667016345785d8a00006040518363ffffffff1660e01b815260040161012c929190610abf565b6020604051808303816000875af115801561014b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016f9190610b20565b5060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306cb89838787878787876040518763ffffffff1660e01b81526004016101d396959493929190610e18565b600060405180830381600087803b1580156101ed57600080fd5b505af1158015610201573d6000803e3d6000fd5b50505050505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561027757600080fd5b505af115801561028b573d6000803e3d6000fd5b5050505050565b8473ffffffffffffffffffffffffffffffffffffffff1663095ea7b360008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1667016345785d8a00006040518363ffffffff1660e01b81526004016102f5929190610abf565b6020604051808303816000875af1158015610314573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103389190610b20565b5060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637b15118b888888888888886040518863ffffffff1660e01b815260040161039e9796959493929190610e91565b600060405180830381600087803b1580156103b857600080fd5b505af11580156103cc573d6000803e3d6000fd5b5050505050505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b360008054906101000a900473ffffffffffffffffffffffffffffffffffffffff16886040518363ffffffff1660e01b8152600401610456929190610f09565b6020604051808303816000875af1158015610475573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104999190610b20565b5060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632810ae63888888888888886040518863ffffffff1660e01b81526004016104ff9796959493929190610f32565b600060405180830381600087803b15801561051957600080fd5b505af115801561052d573d6000803e3d6000fd5b5050505050505050505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6105a182610558565b810181811067ffffffffffffffff821117156105c0576105bf610569565b5b80604052505050565b60006105d361053a565b90506105df8282610598565b919050565b600067ffffffffffffffff8211156105ff576105fe610569565b5b61060882610558565b9050602081019050919050565b82818337600083830152505050565b6000610637610632846105e4565b6105c9565b90508281526020810184848401111561065357610652610553565b5b61065e848285610615565b509392505050565b600082601f83011261067b5761067a61054e565b5b813561068b848260208601610624565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106bf82610694565b9050919050565b6106cf816106b4565b81146106da57600080fd5b50565b6000813590506106ec816106c6565b92915050565b600080fd5b600080fd5b60008083601f8401126107125761071161054e565b5b8235905067ffffffffffffffff81111561072f5761072e6106f2565b5b60208301915083600182028301111561074b5761074a6106f7565b5b9250929050565b600080fd5b60006040828403121561076d5761076c610752565b5b81905092915050565b600060a0828403121561078c5761078b610752565b5b81905092915050565b60008060008060008060c087890312156107b2576107b1610544565b5b600087013567ffffffffffffffff8111156107d0576107cf610549565b5b6107dc89828a01610666565b96505060206107ed89828a016106dd565b955050604087013567ffffffffffffffff81111561080e5761080d610549565b5b61081a89828a016106fc565b9450945050606061082d89828a01610757565b92505060a087013567ffffffffffffffff81111561084e5761084d610549565b5b61085a89828a01610776565b9150509295509295509295565b6000819050919050565b61087a81610867565b811461088557600080fd5b50565b60008135905061089781610871565b92915050565b600080600080600080600060e0888a0312156108bc576108bb610544565b5b600088013567ffffffffffffffff8111156108da576108d9610549565b5b6108e68a828b01610666565b97505060206108f78a828b01610888565b96505060406109088a828b016106dd565b955050606088013567ffffffffffffffff81111561092957610928610549565b5b6109358a828b016106fc565b945094505060806109488a828b01610757565b92505060c088013567ffffffffffffffff81111561096957610968610549565b5b6109758a828b01610776565b91505092959891949750929550565b600080600080600080600060e0888a0312156109a3576109a2610544565b5b600088013567ffffffffffffffff8111156109c1576109c0610549565b5b6109cd8a828b01610666565b97505060206109de8a828b01610888565b96505060406109ef8a828b01610888565b955050606088013567ffffffffffffffff811115610a1057610a0f610549565b5b610a1c8a828b016106fc565b94509450506080610a2f8a828b01610757565b92505060c088013567ffffffffffffffff811115610a5057610a4f610549565b5b610a5c8a828b01610776565b91505092959891949750929550565b610a74816106b4565b82525050565b6000819050919050565b6000819050919050565b6000610aa9610aa4610a9f84610a7a565b610a84565b610867565b9050919050565b610ab981610a8e565b82525050565b6000604082019050610ad46000830185610a6b565b610ae16020830184610ab0565b9392505050565b60008115159050919050565b610afd81610ae8565b8114610b0857600080fd5b50565b600081519050610b1a81610af4565b92915050565b600060208284031215610b3657610b35610544565b5b6000610b4484828501610b0b565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610b87578082015181840152602081019050610b6c565b83811115610b96576000848401525b50505050565b6000610ba782610b4d565b610bb18185610b58565b9350610bc1818560208601610b69565b610bca81610558565b840191505092915050565b6000610be18385610b58565b9350610bee838584610615565b610bf783610558565b840190509392505050565b6000610c116020840184610888565b905092915050565b610c2281610867565b82525050565b600081359050610c3781610af4565b92915050565b6000610c4c6020840184610c28565b905092915050565b610c5d81610ae8565b82525050565b60408201610c746000830183610c02565b610c816000850182610c19565b50610c8f6020830183610c3d565b610c9c6020850182610c54565b50505050565b6000610cb160208401846106dd565b905092915050565b610cc2816106b4565b82525050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112610cf457610cf3610cd2565b5b83810192508235915060208301925067ffffffffffffffff821115610d1c57610d1b610cc8565b5b600182023603841315610d3257610d31610ccd565b5b509250929050565b600082825260208201905092915050565b6000610d578385610d3a565b9350610d64838584610615565b610d6d83610558565b840190509392505050565b600060a08301610d8b6000840184610ca2565b610d986000860182610cb9565b50610da66020840184610c3d565b610db36020860182610c54565b50610dc16040840184610ca2565b610dce6040860182610cb9565b50610ddc6060840184610cd7565b8583036060870152610def838284610d4b565b92505050610e006080840184610c02565b610e0d6080860182610c19565b508091505092915050565b600060c0820190508181036000830152610e328189610b9c565b9050610e416020830188610a6b565b8181036040830152610e54818688610bd5565b9050610e636060830185610c63565b81810360a0830152610e758184610d78565b9050979650505050505050565b610e8b81610867565b82525050565b600060e0820190508181036000830152610eab818a610b9c565b9050610eba6020830189610e82565b610ec76040830188610a6b565b8181036060830152610eda818688610bd5565b9050610ee96080830185610c63565b81810360c0830152610efb8184610d78565b905098975050505050505050565b6000604082019050610f1e6000830185610a6b565b610f2b6020830184610e82565b9392505050565b600060e0820190508181036000830152610f4c818a610b9c565b9050610f5b6020830189610e82565b610f686040830188610e82565b8181036060830152610f7b818688610bd5565b9050610f8a6080830185610c63565b81810360c0830152610f9c8184610d78565b90509897505050505050505056fea26469706673582212204b70dead8f68839447fc08bd73294d57367a484ba9b048960ffcc202a737ae5664736f6c634300080a0033 diff --git a/pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.go b/pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.go new file mode 100644 index 0000000000..3411e3a9d1 --- /dev/null +++ b/pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.go @@ -0,0 +1,302 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package gatewayzevmcaller + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// CallOptions is an auto generated low-level Go binding around an user-defined struct. +type CallOptions struct { + GasLimit *big.Int + IsArbitraryCall bool +} + +// RevertOptions is an auto generated low-level Go binding around an user-defined struct. +type RevertOptions struct { + RevertAddress common.Address + CallOnRevert bool + AbortAddress common.Address + RevertMessage []byte + OnRevertGasLimit *big.Int +} + +// GatewayZEVMCallerMetaData contains all meta data concerning the GatewayZEVMCaller contract. +var GatewayZEVMCallerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"gatewayZEVMAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"wzetaAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"zrc20\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isArbitraryCall\",\"type\":\"bool\"}],\"internalType\":\"structCallOptions\",\"name\":\"callOptions\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"revertAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"callOnRevert\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"abortAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"revertMessage\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"onRevertGasLimit\",\"type\":\"uint256\"}],\"internalType\":\"structRevertOptions\",\"name\":\"revertOptions\",\"type\":\"tuple\"}],\"name\":\"callGatewayZEVM\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositWZETA\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"zrc20\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isArbitraryCall\",\"type\":\"bool\"}],\"internalType\":\"structCallOptions\",\"name\":\"callOptions\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"revertAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"callOnRevert\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"abortAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"revertMessage\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"onRevertGasLimit\",\"type\":\"uint256\"}],\"internalType\":\"structRevertOptions\",\"name\":\"revertOptions\",\"type\":\"tuple\"}],\"name\":\"withdrawAndCallGatewayZEVM\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isArbitraryCall\",\"type\":\"bool\"}],\"internalType\":\"structCallOptions\",\"name\":\"callOptions\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"revertAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"callOnRevert\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"abortAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"revertMessage\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"onRevertGasLimit\",\"type\":\"uint256\"}],\"internalType\":\"structRevertOptions\",\"name\":\"revertOptions\",\"type\":\"tuple\"}],\"name\":\"withdrawAndCallGatewayZEVM\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b50604051620011613803806200116183398181016040528101906200003791906200012a565b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505062000171565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000f282620000c5565b9050919050565b6200010481620000e5565b81146200011057600080fd5b50565b6000815190506200012481620000f9565b92915050565b60008060408385031215620001445762000143620000c0565b5b6000620001548582860162000113565b9250506020620001678582860162000113565b9150509250929050565b610fe080620001816000396000f3fe60806040526004361061003f5760003560e01c806325859e62146100445780632c5d24ae1461006d57806362543ae714610077578063f66f4625146100a0575b600080fd5b34801561005057600080fd5b5061006b60048036038101906100669190610795565b6100c9565b005b61007561020d565b005b34801561008357600080fd5b5061009e6004803603810190610099919061089d565b610292565b005b3480156100ac57600080fd5b506100c760048036038101906100c29190610984565b6103d9565b005b8473ffffffffffffffffffffffffffffffffffffffff1663095ea7b360008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1667016345785d8a00006040518363ffffffff1660e01b815260040161012c929190610abf565b6020604051808303816000875af115801561014b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016f9190610b20565b5060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306cb89838787878787876040518763ffffffff1660e01b81526004016101d396959493929190610e18565b600060405180830381600087803b1580156101ed57600080fd5b505af1158015610201573d6000803e3d6000fd5b50505050505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561027757600080fd5b505af115801561028b573d6000803e3d6000fd5b5050505050565b8473ffffffffffffffffffffffffffffffffffffffff1663095ea7b360008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1667016345785d8a00006040518363ffffffff1660e01b81526004016102f5929190610abf565b6020604051808303816000875af1158015610314573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103389190610b20565b5060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637b15118b888888888888886040518863ffffffff1660e01b815260040161039e9796959493929190610e91565b600060405180830381600087803b1580156103b857600080fd5b505af11580156103cc573d6000803e3d6000fd5b5050505050505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b360008054906101000a900473ffffffffffffffffffffffffffffffffffffffff16886040518363ffffffff1660e01b8152600401610456929190610f09565b6020604051808303816000875af1158015610475573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104999190610b20565b5060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632810ae63888888888888886040518863ffffffff1660e01b81526004016104ff9796959493929190610f32565b600060405180830381600087803b15801561051957600080fd5b505af115801561052d573d6000803e3d6000fd5b5050505050505050505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6105a182610558565b810181811067ffffffffffffffff821117156105c0576105bf610569565b5b80604052505050565b60006105d361053a565b90506105df8282610598565b919050565b600067ffffffffffffffff8211156105ff576105fe610569565b5b61060882610558565b9050602081019050919050565b82818337600083830152505050565b6000610637610632846105e4565b6105c9565b90508281526020810184848401111561065357610652610553565b5b61065e848285610615565b509392505050565b600082601f83011261067b5761067a61054e565b5b813561068b848260208601610624565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106bf82610694565b9050919050565b6106cf816106b4565b81146106da57600080fd5b50565b6000813590506106ec816106c6565b92915050565b600080fd5b600080fd5b60008083601f8401126107125761071161054e565b5b8235905067ffffffffffffffff81111561072f5761072e6106f2565b5b60208301915083600182028301111561074b5761074a6106f7565b5b9250929050565b600080fd5b60006040828403121561076d5761076c610752565b5b81905092915050565b600060a0828403121561078c5761078b610752565b5b81905092915050565b60008060008060008060c087890312156107b2576107b1610544565b5b600087013567ffffffffffffffff8111156107d0576107cf610549565b5b6107dc89828a01610666565b96505060206107ed89828a016106dd565b955050604087013567ffffffffffffffff81111561080e5761080d610549565b5b61081a89828a016106fc565b9450945050606061082d89828a01610757565b92505060a087013567ffffffffffffffff81111561084e5761084d610549565b5b61085a89828a01610776565b9150509295509295509295565b6000819050919050565b61087a81610867565b811461088557600080fd5b50565b60008135905061089781610871565b92915050565b600080600080600080600060e0888a0312156108bc576108bb610544565b5b600088013567ffffffffffffffff8111156108da576108d9610549565b5b6108e68a828b01610666565b97505060206108f78a828b01610888565b96505060406109088a828b016106dd565b955050606088013567ffffffffffffffff81111561092957610928610549565b5b6109358a828b016106fc565b945094505060806109488a828b01610757565b92505060c088013567ffffffffffffffff81111561096957610968610549565b5b6109758a828b01610776565b91505092959891949750929550565b600080600080600080600060e0888a0312156109a3576109a2610544565b5b600088013567ffffffffffffffff8111156109c1576109c0610549565b5b6109cd8a828b01610666565b97505060206109de8a828b01610888565b96505060406109ef8a828b01610888565b955050606088013567ffffffffffffffff811115610a1057610a0f610549565b5b610a1c8a828b016106fc565b94509450506080610a2f8a828b01610757565b92505060c088013567ffffffffffffffff811115610a5057610a4f610549565b5b610a5c8a828b01610776565b91505092959891949750929550565b610a74816106b4565b82525050565b6000819050919050565b6000819050919050565b6000610aa9610aa4610a9f84610a7a565b610a84565b610867565b9050919050565b610ab981610a8e565b82525050565b6000604082019050610ad46000830185610a6b565b610ae16020830184610ab0565b9392505050565b60008115159050919050565b610afd81610ae8565b8114610b0857600080fd5b50565b600081519050610b1a81610af4565b92915050565b600060208284031215610b3657610b35610544565b5b6000610b4484828501610b0b565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610b87578082015181840152602081019050610b6c565b83811115610b96576000848401525b50505050565b6000610ba782610b4d565b610bb18185610b58565b9350610bc1818560208601610b69565b610bca81610558565b840191505092915050565b6000610be18385610b58565b9350610bee838584610615565b610bf783610558565b840190509392505050565b6000610c116020840184610888565b905092915050565b610c2281610867565b82525050565b600081359050610c3781610af4565b92915050565b6000610c4c6020840184610c28565b905092915050565b610c5d81610ae8565b82525050565b60408201610c746000830183610c02565b610c816000850182610c19565b50610c8f6020830183610c3d565b610c9c6020850182610c54565b50505050565b6000610cb160208401846106dd565b905092915050565b610cc2816106b4565b82525050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112610cf457610cf3610cd2565b5b83810192508235915060208301925067ffffffffffffffff821115610d1c57610d1b610cc8565b5b600182023603841315610d3257610d31610ccd565b5b509250929050565b600082825260208201905092915050565b6000610d578385610d3a565b9350610d64838584610615565b610d6d83610558565b840190509392505050565b600060a08301610d8b6000840184610ca2565b610d986000860182610cb9565b50610da66020840184610c3d565b610db36020860182610c54565b50610dc16040840184610ca2565b610dce6040860182610cb9565b50610ddc6060840184610cd7565b8583036060870152610def838284610d4b565b92505050610e006080840184610c02565b610e0d6080860182610c19565b508091505092915050565b600060c0820190508181036000830152610e328189610b9c565b9050610e416020830188610a6b565b8181036040830152610e54818688610bd5565b9050610e636060830185610c63565b81810360a0830152610e758184610d78565b9050979650505050505050565b610e8b81610867565b82525050565b600060e0820190508181036000830152610eab818a610b9c565b9050610eba6020830189610e82565b610ec76040830188610a6b565b8181036060830152610eda818688610bd5565b9050610ee96080830185610c63565b81810360c0830152610efb8184610d78565b905098975050505050505050565b6000604082019050610f1e6000830185610a6b565b610f2b6020830184610e82565b9392505050565b600060e0820190508181036000830152610f4c818a610b9c565b9050610f5b6020830189610e82565b610f686040830188610e82565b8181036060830152610f7b818688610bd5565b9050610f8a6080830185610c63565b81810360c0830152610f9c8184610d78565b90509897505050505050505056fea26469706673582212204b70dead8f68839447fc08bd73294d57367a484ba9b048960ffcc202a737ae5664736f6c634300080a0033", +} + +// GatewayZEVMCallerABI is the input ABI used to generate the binding from. +// Deprecated: Use GatewayZEVMCallerMetaData.ABI instead. +var GatewayZEVMCallerABI = GatewayZEVMCallerMetaData.ABI + +// GatewayZEVMCallerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use GatewayZEVMCallerMetaData.Bin instead. +var GatewayZEVMCallerBin = GatewayZEVMCallerMetaData.Bin + +// DeployGatewayZEVMCaller deploys a new Ethereum contract, binding an instance of GatewayZEVMCaller to it. +func DeployGatewayZEVMCaller(auth *bind.TransactOpts, backend bind.ContractBackend, gatewayZEVMAddress common.Address, wzetaAddress common.Address) (common.Address, *types.Transaction, *GatewayZEVMCaller, error) { + parsed, err := GatewayZEVMCallerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(GatewayZEVMCallerBin), backend, gatewayZEVMAddress, wzetaAddress) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &GatewayZEVMCaller{GatewayZEVMCallerCaller: GatewayZEVMCallerCaller{contract: contract}, GatewayZEVMCallerTransactor: GatewayZEVMCallerTransactor{contract: contract}, GatewayZEVMCallerFilterer: GatewayZEVMCallerFilterer{contract: contract}}, nil +} + +// GatewayZEVMCaller is an auto generated Go binding around an Ethereum contract. +type GatewayZEVMCaller struct { + GatewayZEVMCallerCaller // Read-only binding to the contract + GatewayZEVMCallerTransactor // Write-only binding to the contract + GatewayZEVMCallerFilterer // Log filterer for contract events +} + +// GatewayZEVMCallerCaller is an auto generated read-only Go binding around an Ethereum contract. +type GatewayZEVMCallerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GatewayZEVMCallerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type GatewayZEVMCallerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GatewayZEVMCallerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type GatewayZEVMCallerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GatewayZEVMCallerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type GatewayZEVMCallerSession struct { + Contract *GatewayZEVMCaller // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// GatewayZEVMCallerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type GatewayZEVMCallerCallerSession struct { + Contract *GatewayZEVMCallerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// GatewayZEVMCallerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type GatewayZEVMCallerTransactorSession struct { + Contract *GatewayZEVMCallerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// GatewayZEVMCallerRaw is an auto generated low-level Go binding around an Ethereum contract. +type GatewayZEVMCallerRaw struct { + Contract *GatewayZEVMCaller // Generic contract binding to access the raw methods on +} + +// GatewayZEVMCallerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type GatewayZEVMCallerCallerRaw struct { + Contract *GatewayZEVMCallerCaller // Generic read-only contract binding to access the raw methods on +} + +// GatewayZEVMCallerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type GatewayZEVMCallerTransactorRaw struct { + Contract *GatewayZEVMCallerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewGatewayZEVMCaller creates a new instance of GatewayZEVMCaller, bound to a specific deployed contract. +func NewGatewayZEVMCaller(address common.Address, backend bind.ContractBackend) (*GatewayZEVMCaller, error) { + contract, err := bindGatewayZEVMCaller(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &GatewayZEVMCaller{GatewayZEVMCallerCaller: GatewayZEVMCallerCaller{contract: contract}, GatewayZEVMCallerTransactor: GatewayZEVMCallerTransactor{contract: contract}, GatewayZEVMCallerFilterer: GatewayZEVMCallerFilterer{contract: contract}}, nil +} + +// NewGatewayZEVMCallerCaller creates a new read-only instance of GatewayZEVMCaller, bound to a specific deployed contract. +func NewGatewayZEVMCallerCaller(address common.Address, caller bind.ContractCaller) (*GatewayZEVMCallerCaller, error) { + contract, err := bindGatewayZEVMCaller(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &GatewayZEVMCallerCaller{contract: contract}, nil +} + +// NewGatewayZEVMCallerTransactor creates a new write-only instance of GatewayZEVMCaller, bound to a specific deployed contract. +func NewGatewayZEVMCallerTransactor(address common.Address, transactor bind.ContractTransactor) (*GatewayZEVMCallerTransactor, error) { + contract, err := bindGatewayZEVMCaller(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &GatewayZEVMCallerTransactor{contract: contract}, nil +} + +// NewGatewayZEVMCallerFilterer creates a new log filterer instance of GatewayZEVMCaller, bound to a specific deployed contract. +func NewGatewayZEVMCallerFilterer(address common.Address, filterer bind.ContractFilterer) (*GatewayZEVMCallerFilterer, error) { + contract, err := bindGatewayZEVMCaller(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &GatewayZEVMCallerFilterer{contract: contract}, nil +} + +// bindGatewayZEVMCaller binds a generic wrapper to an already deployed contract. +func bindGatewayZEVMCaller(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := GatewayZEVMCallerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_GatewayZEVMCaller *GatewayZEVMCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GatewayZEVMCaller.Contract.GatewayZEVMCallerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_GatewayZEVMCaller *GatewayZEVMCallerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GatewayZEVMCaller.Contract.GatewayZEVMCallerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_GatewayZEVMCaller *GatewayZEVMCallerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GatewayZEVMCaller.Contract.GatewayZEVMCallerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_GatewayZEVMCaller *GatewayZEVMCallerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GatewayZEVMCaller.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_GatewayZEVMCaller *GatewayZEVMCallerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GatewayZEVMCaller.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_GatewayZEVMCaller *GatewayZEVMCallerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GatewayZEVMCaller.Contract.contract.Transact(opts, method, params...) +} + +// CallGatewayZEVM is a paid mutator transaction binding the contract method 0x25859e62. +// +// Solidity: function callGatewayZEVM(bytes receiver, address zrc20, bytes message, (uint256,bool) callOptions, (address,bool,address,bytes,uint256) revertOptions) returns() +func (_GatewayZEVMCaller *GatewayZEVMCallerTransactor) CallGatewayZEVM(opts *bind.TransactOpts, receiver []byte, zrc20 common.Address, message []byte, callOptions CallOptions, revertOptions RevertOptions) (*types.Transaction, error) { + return _GatewayZEVMCaller.contract.Transact(opts, "callGatewayZEVM", receiver, zrc20, message, callOptions, revertOptions) +} + +// CallGatewayZEVM is a paid mutator transaction binding the contract method 0x25859e62. +// +// Solidity: function callGatewayZEVM(bytes receiver, address zrc20, bytes message, (uint256,bool) callOptions, (address,bool,address,bytes,uint256) revertOptions) returns() +func (_GatewayZEVMCaller *GatewayZEVMCallerSession) CallGatewayZEVM(receiver []byte, zrc20 common.Address, message []byte, callOptions CallOptions, revertOptions RevertOptions) (*types.Transaction, error) { + return _GatewayZEVMCaller.Contract.CallGatewayZEVM(&_GatewayZEVMCaller.TransactOpts, receiver, zrc20, message, callOptions, revertOptions) +} + +// CallGatewayZEVM is a paid mutator transaction binding the contract method 0x25859e62. +// +// Solidity: function callGatewayZEVM(bytes receiver, address zrc20, bytes message, (uint256,bool) callOptions, (address,bool,address,bytes,uint256) revertOptions) returns() +func (_GatewayZEVMCaller *GatewayZEVMCallerTransactorSession) CallGatewayZEVM(receiver []byte, zrc20 common.Address, message []byte, callOptions CallOptions, revertOptions RevertOptions) (*types.Transaction, error) { + return _GatewayZEVMCaller.Contract.CallGatewayZEVM(&_GatewayZEVMCaller.TransactOpts, receiver, zrc20, message, callOptions, revertOptions) +} + +// DepositWZETA is a paid mutator transaction binding the contract method 0x2c5d24ae. +// +// Solidity: function depositWZETA() payable returns() +func (_GatewayZEVMCaller *GatewayZEVMCallerTransactor) DepositWZETA(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GatewayZEVMCaller.contract.Transact(opts, "depositWZETA") +} + +// DepositWZETA is a paid mutator transaction binding the contract method 0x2c5d24ae. +// +// Solidity: function depositWZETA() payable returns() +func (_GatewayZEVMCaller *GatewayZEVMCallerSession) DepositWZETA() (*types.Transaction, error) { + return _GatewayZEVMCaller.Contract.DepositWZETA(&_GatewayZEVMCaller.TransactOpts) +} + +// DepositWZETA is a paid mutator transaction binding the contract method 0x2c5d24ae. +// +// Solidity: function depositWZETA() payable returns() +func (_GatewayZEVMCaller *GatewayZEVMCallerTransactorSession) DepositWZETA() (*types.Transaction, error) { + return _GatewayZEVMCaller.Contract.DepositWZETA(&_GatewayZEVMCaller.TransactOpts) +} + +// WithdrawAndCallGatewayZEVM is a paid mutator transaction binding the contract method 0x62543ae7. +// +// Solidity: function withdrawAndCallGatewayZEVM(bytes receiver, uint256 amount, address zrc20, bytes message, (uint256,bool) callOptions, (address,bool,address,bytes,uint256) revertOptions) returns() +func (_GatewayZEVMCaller *GatewayZEVMCallerTransactor) WithdrawAndCallGatewayZEVM(opts *bind.TransactOpts, receiver []byte, amount *big.Int, zrc20 common.Address, message []byte, callOptions CallOptions, revertOptions RevertOptions) (*types.Transaction, error) { + return _GatewayZEVMCaller.contract.Transact(opts, "withdrawAndCallGatewayZEVM", receiver, amount, zrc20, message, callOptions, revertOptions) +} + +// WithdrawAndCallGatewayZEVM is a paid mutator transaction binding the contract method 0x62543ae7. +// +// Solidity: function withdrawAndCallGatewayZEVM(bytes receiver, uint256 amount, address zrc20, bytes message, (uint256,bool) callOptions, (address,bool,address,bytes,uint256) revertOptions) returns() +func (_GatewayZEVMCaller *GatewayZEVMCallerSession) WithdrawAndCallGatewayZEVM(receiver []byte, amount *big.Int, zrc20 common.Address, message []byte, callOptions CallOptions, revertOptions RevertOptions) (*types.Transaction, error) { + return _GatewayZEVMCaller.Contract.WithdrawAndCallGatewayZEVM(&_GatewayZEVMCaller.TransactOpts, receiver, amount, zrc20, message, callOptions, revertOptions) +} + +// WithdrawAndCallGatewayZEVM is a paid mutator transaction binding the contract method 0x62543ae7. +// +// Solidity: function withdrawAndCallGatewayZEVM(bytes receiver, uint256 amount, address zrc20, bytes message, (uint256,bool) callOptions, (address,bool,address,bytes,uint256) revertOptions) returns() +func (_GatewayZEVMCaller *GatewayZEVMCallerTransactorSession) WithdrawAndCallGatewayZEVM(receiver []byte, amount *big.Int, zrc20 common.Address, message []byte, callOptions CallOptions, revertOptions RevertOptions) (*types.Transaction, error) { + return _GatewayZEVMCaller.Contract.WithdrawAndCallGatewayZEVM(&_GatewayZEVMCaller.TransactOpts, receiver, amount, zrc20, message, callOptions, revertOptions) +} + +// WithdrawAndCallGatewayZEVM0 is a paid mutator transaction binding the contract method 0xf66f4625. +// +// Solidity: function withdrawAndCallGatewayZEVM(bytes receiver, uint256 amount, uint256 chainId, bytes message, (uint256,bool) callOptions, (address,bool,address,bytes,uint256) revertOptions) returns() +func (_GatewayZEVMCaller *GatewayZEVMCallerTransactor) WithdrawAndCallGatewayZEVM0(opts *bind.TransactOpts, receiver []byte, amount *big.Int, chainId *big.Int, message []byte, callOptions CallOptions, revertOptions RevertOptions) (*types.Transaction, error) { + return _GatewayZEVMCaller.contract.Transact(opts, "withdrawAndCallGatewayZEVM0", receiver, amount, chainId, message, callOptions, revertOptions) +} + +// WithdrawAndCallGatewayZEVM0 is a paid mutator transaction binding the contract method 0xf66f4625. +// +// Solidity: function withdrawAndCallGatewayZEVM(bytes receiver, uint256 amount, uint256 chainId, bytes message, (uint256,bool) callOptions, (address,bool,address,bytes,uint256) revertOptions) returns() +func (_GatewayZEVMCaller *GatewayZEVMCallerSession) WithdrawAndCallGatewayZEVM0(receiver []byte, amount *big.Int, chainId *big.Int, message []byte, callOptions CallOptions, revertOptions RevertOptions) (*types.Transaction, error) { + return _GatewayZEVMCaller.Contract.WithdrawAndCallGatewayZEVM0(&_GatewayZEVMCaller.TransactOpts, receiver, amount, chainId, message, callOptions, revertOptions) +} + +// WithdrawAndCallGatewayZEVM0 is a paid mutator transaction binding the contract method 0xf66f4625. +// +// Solidity: function withdrawAndCallGatewayZEVM(bytes receiver, uint256 amount, uint256 chainId, bytes message, (uint256,bool) callOptions, (address,bool,address,bytes,uint256) revertOptions) returns() +func (_GatewayZEVMCaller *GatewayZEVMCallerTransactorSession) WithdrawAndCallGatewayZEVM0(receiver []byte, amount *big.Int, chainId *big.Int, message []byte, callOptions CallOptions, revertOptions RevertOptions) (*types.Transaction, error) { + return _GatewayZEVMCaller.Contract.WithdrawAndCallGatewayZEVM0(&_GatewayZEVMCaller.TransactOpts, receiver, amount, chainId, message, callOptions, revertOptions) +} diff --git a/pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.json b/pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.json new file mode 100644 index 0000000000..1ce09e97a9 --- /dev/null +++ b/pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.json @@ -0,0 +1,254 @@ +{ + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "gatewayZEVMAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "wzetaAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "receiver", + "type": "bytes" + }, + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isArbitraryCall", + "type": "bool" + } + ], + "internalType": "struct CallOptions", + "name": "callOptions", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "revertAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "callOnRevert", + "type": "bool" + }, + { + "internalType": "address", + "name": "abortAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "revertMessage", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "onRevertGasLimit", + "type": "uint256" + } + ], + "internalType": "struct RevertOptions", + "name": "revertOptions", + "type": "tuple" + } + ], + "name": "callGatewayZEVM", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositWZETA", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "receiver", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isArbitraryCall", + "type": "bool" + } + ], + "internalType": "struct CallOptions", + "name": "callOptions", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "revertAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "callOnRevert", + "type": "bool" + }, + { + "internalType": "address", + "name": "abortAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "revertMessage", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "onRevertGasLimit", + "type": "uint256" + } + ], + "internalType": "struct RevertOptions", + "name": "revertOptions", + "type": "tuple" + } + ], + "name": "withdrawAndCallGatewayZEVM", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "receiver", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isArbitraryCall", + "type": "bool" + } + ], + "internalType": "struct CallOptions", + "name": "callOptions", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "revertAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "callOnRevert", + "type": "bool" + }, + { + "internalType": "address", + "name": "abortAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "revertMessage", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "onRevertGasLimit", + "type": "uint256" + } + ], + "internalType": "struct RevertOptions", + "name": "revertOptions", + "type": "tuple" + } + ], + "name": "withdrawAndCallGatewayZEVM", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bin": "60806040523480156200001157600080fd5b50604051620011613803806200116183398181016040528101906200003791906200012a565b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505062000171565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000f282620000c5565b9050919050565b6200010481620000e5565b81146200011057600080fd5b50565b6000815190506200012481620000f9565b92915050565b60008060408385031215620001445762000143620000c0565b5b6000620001548582860162000113565b9250506020620001678582860162000113565b9150509250929050565b610fe080620001816000396000f3fe60806040526004361061003f5760003560e01c806325859e62146100445780632c5d24ae1461006d57806362543ae714610077578063f66f4625146100a0575b600080fd5b34801561005057600080fd5b5061006b60048036038101906100669190610795565b6100c9565b005b61007561020d565b005b34801561008357600080fd5b5061009e6004803603810190610099919061089d565b610292565b005b3480156100ac57600080fd5b506100c760048036038101906100c29190610984565b6103d9565b005b8473ffffffffffffffffffffffffffffffffffffffff1663095ea7b360008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1667016345785d8a00006040518363ffffffff1660e01b815260040161012c929190610abf565b6020604051808303816000875af115801561014b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016f9190610b20565b5060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306cb89838787878787876040518763ffffffff1660e01b81526004016101d396959493929190610e18565b600060405180830381600087803b1580156101ed57600080fd5b505af1158015610201573d6000803e3d6000fd5b50505050505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561027757600080fd5b505af115801561028b573d6000803e3d6000fd5b5050505050565b8473ffffffffffffffffffffffffffffffffffffffff1663095ea7b360008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1667016345785d8a00006040518363ffffffff1660e01b81526004016102f5929190610abf565b6020604051808303816000875af1158015610314573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103389190610b20565b5060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637b15118b888888888888886040518863ffffffff1660e01b815260040161039e9796959493929190610e91565b600060405180830381600087803b1580156103b857600080fd5b505af11580156103cc573d6000803e3d6000fd5b5050505050505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b360008054906101000a900473ffffffffffffffffffffffffffffffffffffffff16886040518363ffffffff1660e01b8152600401610456929190610f09565b6020604051808303816000875af1158015610475573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104999190610b20565b5060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632810ae63888888888888886040518863ffffffff1660e01b81526004016104ff9796959493929190610f32565b600060405180830381600087803b15801561051957600080fd5b505af115801561052d573d6000803e3d6000fd5b5050505050505050505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6105a182610558565b810181811067ffffffffffffffff821117156105c0576105bf610569565b5b80604052505050565b60006105d361053a565b90506105df8282610598565b919050565b600067ffffffffffffffff8211156105ff576105fe610569565b5b61060882610558565b9050602081019050919050565b82818337600083830152505050565b6000610637610632846105e4565b6105c9565b90508281526020810184848401111561065357610652610553565b5b61065e848285610615565b509392505050565b600082601f83011261067b5761067a61054e565b5b813561068b848260208601610624565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106bf82610694565b9050919050565b6106cf816106b4565b81146106da57600080fd5b50565b6000813590506106ec816106c6565b92915050565b600080fd5b600080fd5b60008083601f8401126107125761071161054e565b5b8235905067ffffffffffffffff81111561072f5761072e6106f2565b5b60208301915083600182028301111561074b5761074a6106f7565b5b9250929050565b600080fd5b60006040828403121561076d5761076c610752565b5b81905092915050565b600060a0828403121561078c5761078b610752565b5b81905092915050565b60008060008060008060c087890312156107b2576107b1610544565b5b600087013567ffffffffffffffff8111156107d0576107cf610549565b5b6107dc89828a01610666565b96505060206107ed89828a016106dd565b955050604087013567ffffffffffffffff81111561080e5761080d610549565b5b61081a89828a016106fc565b9450945050606061082d89828a01610757565b92505060a087013567ffffffffffffffff81111561084e5761084d610549565b5b61085a89828a01610776565b9150509295509295509295565b6000819050919050565b61087a81610867565b811461088557600080fd5b50565b60008135905061089781610871565b92915050565b600080600080600080600060e0888a0312156108bc576108bb610544565b5b600088013567ffffffffffffffff8111156108da576108d9610549565b5b6108e68a828b01610666565b97505060206108f78a828b01610888565b96505060406109088a828b016106dd565b955050606088013567ffffffffffffffff81111561092957610928610549565b5b6109358a828b016106fc565b945094505060806109488a828b01610757565b92505060c088013567ffffffffffffffff81111561096957610968610549565b5b6109758a828b01610776565b91505092959891949750929550565b600080600080600080600060e0888a0312156109a3576109a2610544565b5b600088013567ffffffffffffffff8111156109c1576109c0610549565b5b6109cd8a828b01610666565b97505060206109de8a828b01610888565b96505060406109ef8a828b01610888565b955050606088013567ffffffffffffffff811115610a1057610a0f610549565b5b610a1c8a828b016106fc565b94509450506080610a2f8a828b01610757565b92505060c088013567ffffffffffffffff811115610a5057610a4f610549565b5b610a5c8a828b01610776565b91505092959891949750929550565b610a74816106b4565b82525050565b6000819050919050565b6000819050919050565b6000610aa9610aa4610a9f84610a7a565b610a84565b610867565b9050919050565b610ab981610a8e565b82525050565b6000604082019050610ad46000830185610a6b565b610ae16020830184610ab0565b9392505050565b60008115159050919050565b610afd81610ae8565b8114610b0857600080fd5b50565b600081519050610b1a81610af4565b92915050565b600060208284031215610b3657610b35610544565b5b6000610b4484828501610b0b565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610b87578082015181840152602081019050610b6c565b83811115610b96576000848401525b50505050565b6000610ba782610b4d565b610bb18185610b58565b9350610bc1818560208601610b69565b610bca81610558565b840191505092915050565b6000610be18385610b58565b9350610bee838584610615565b610bf783610558565b840190509392505050565b6000610c116020840184610888565b905092915050565b610c2281610867565b82525050565b600081359050610c3781610af4565b92915050565b6000610c4c6020840184610c28565b905092915050565b610c5d81610ae8565b82525050565b60408201610c746000830183610c02565b610c816000850182610c19565b50610c8f6020830183610c3d565b610c9c6020850182610c54565b50505050565b6000610cb160208401846106dd565b905092915050565b610cc2816106b4565b82525050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112610cf457610cf3610cd2565b5b83810192508235915060208301925067ffffffffffffffff821115610d1c57610d1b610cc8565b5b600182023603841315610d3257610d31610ccd565b5b509250929050565b600082825260208201905092915050565b6000610d578385610d3a565b9350610d64838584610615565b610d6d83610558565b840190509392505050565b600060a08301610d8b6000840184610ca2565b610d986000860182610cb9565b50610da66020840184610c3d565b610db36020860182610c54565b50610dc16040840184610ca2565b610dce6040860182610cb9565b50610ddc6060840184610cd7565b8583036060870152610def838284610d4b565b92505050610e006080840184610c02565b610e0d6080860182610c19565b508091505092915050565b600060c0820190508181036000830152610e328189610b9c565b9050610e416020830188610a6b565b8181036040830152610e54818688610bd5565b9050610e636060830185610c63565b81810360a0830152610e758184610d78565b9050979650505050505050565b610e8b81610867565b82525050565b600060e0820190508181036000830152610eab818a610b9c565b9050610eba6020830189610e82565b610ec76040830188610a6b565b8181036060830152610eda818688610bd5565b9050610ee96080830185610c63565b81810360c0830152610efb8184610d78565b905098975050505050505050565b6000604082019050610f1e6000830185610a6b565b610f2b6020830184610e82565b9392505050565b600060e0820190508181036000830152610f4c818a610b9c565b9050610f5b6020830189610e82565b610f686040830188610e82565b8181036060830152610f7b818688610bd5565b9050610f8a6080830185610c63565b81810360c0830152610f9c8184610d78565b90509897505050505050505056fea26469706673582212204b70dead8f68839447fc08bd73294d57367a484ba9b048960ffcc202a737ae5664736f6c634300080a0033" +} diff --git a/pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.sol b/pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.sol new file mode 100644 index 0000000000..e58a7197dd --- /dev/null +++ b/pkg/contracts/gatewayzevmcaller/GatewayZEVMCaller.sol @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + +struct CallOptions { + uint256 gasLimit; + bool isArbitraryCall; +} + +struct RevertOptions { + address revertAddress; + bool callOnRevert; + address abortAddress; + bytes revertMessage; + uint256 onRevertGasLimit; +} + +interface IGatewayZEVM { + function call( + bytes memory receiver, + address zrc20, + bytes calldata message, + CallOptions calldata callOptions, + RevertOptions calldata revertOptions + ) + external; + + function withdrawAndCall( + bytes memory receiver, + uint256 amount, + uint256 chainId, + bytes calldata message, + CallOptions calldata callOptions, + RevertOptions calldata revertOptions + ) + external; + + function withdrawAndCall( + bytes memory receiver, + uint256 amount, + address zrc20, + bytes calldata message, + CallOptions calldata callOptions, + RevertOptions calldata revertOptions + ) + external; +} + +interface IZRC20 { + function approve(address spender, uint256 amount) external returns (bool); +} + +interface WZETA { + function deposit() external payable; + function approve(address guy, uint256 wad) external returns (bool); +} + +contract GatewayZEVMCaller { + IGatewayZEVM private gatewayZEVM; + WZETA wzeta; + constructor(address gatewayZEVMAddress, address wzetaAddress) { + gatewayZEVM = IGatewayZEVM(gatewayZEVMAddress); + wzeta = WZETA(wzetaAddress); + } + + function callGatewayZEVM( + bytes memory receiver, + address zrc20, + bytes calldata message, + CallOptions calldata callOptions, + RevertOptions calldata revertOptions + ) external { + IZRC20(zrc20).approve(address(gatewayZEVM), 100000000000000000); + gatewayZEVM.call(receiver, zrc20, message, callOptions, revertOptions); + } + + function withdrawAndCallGatewayZEVM( + bytes memory receiver, + uint256 amount, + uint256 chainId, + bytes calldata message, + CallOptions calldata callOptions, + RevertOptions calldata revertOptions + ) external { + wzeta.approve(address(gatewayZEVM), amount); + gatewayZEVM.withdrawAndCall(receiver, amount, chainId, message, callOptions, revertOptions); + } + + function withdrawAndCallGatewayZEVM( + bytes memory receiver, + uint256 amount, + address zrc20, + bytes calldata message, + CallOptions calldata callOptions, + RevertOptions calldata revertOptions + ) external { + IZRC20(zrc20).approve(address(gatewayZEVM), 100000000000000000); + gatewayZEVM.withdrawAndCall(receiver, amount, zrc20, message, callOptions, revertOptions); + } + + function depositWZETA() external payable { + wzeta.deposit{value: msg.value}(); + } +} \ No newline at end of file diff --git a/pkg/contracts/gatewayzevmcaller/bindings.go b/pkg/contracts/gatewayzevmcaller/bindings.go new file mode 100644 index 0000000000..591004208d --- /dev/null +++ b/pkg/contracts/gatewayzevmcaller/bindings.go @@ -0,0 +1,8 @@ +//go:generate sh -c "solc GatewayZEVMCaller.sol --combined-json abi,bin | jq '.contracts.\"GatewayZEVMCaller.sol:GatewayZEVMCaller\"' > GatewayZEVMCaller.json" +//go:generate sh -c "cat GatewayZEVMCaller.json | jq .abi > GatewayZEVMCaller.abi" +//go:generate sh -c "cat GatewayZEVMCaller.json | jq .bin | tr -d '\"' > GatewayZEVMCaller.bin" +//go:generate sh -c "abigen --abi GatewayZEVMCaller.abi --bin GatewayZEVMCaller.bin --pkg gatewayzevmcaller --type GatewayZEVMCaller --out GatewayZEVMCaller.go" + +package gatewayzevmcaller + +var _ GatewayZEVMCaller diff --git a/pkg/contracts/testdappv2/TestDAppV2.abi b/pkg/contracts/testdappv2/TestDAppV2.abi index 568085dcc8..b57adc2484 100644 --- a/pkg/contracts/testdappv2/TestDAppV2.abi +++ b/pkg/contracts/testdappv2/TestDAppV2.abi @@ -60,6 +60,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "expectedOnCallSender", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -111,6 +124,37 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "internalType": "struct TestDAppV2.MessageContext", + "name": "messageContext", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "name": "onCall", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -186,6 +230,38 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "senderWithMessage", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_expectedOnCallSender", + "type": "address" + } + ], + "name": "setExpectedOnCallSender", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { diff --git a/pkg/contracts/testdappv2/TestDAppV2.bin b/pkg/contracts/testdappv2/TestDAppV2.bin index 2c35399c09..b8768f52b4 100644 --- a/pkg/contracts/testdappv2/TestDAppV2.bin +++ b/pkg/contracts/testdappv2/TestDAppV2.bin @@ -1 +1 @@ -608060405234801561001057600080fd5b50610e3a806100206000396000f3fe60806040526004361061008a5760003560e01c8063a799911f11610059578063a799911f14610162578063c7a339a91461017e578063de43156e146101a7578063e2842ed7146101d0578063f592cbfb1461020d57610091565b806336e980a0146100965780634297a263146100bf578063660b9de0146100fc5780639291fe261461012557610091565b3661009157005b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190610900565b61024a565b005b3480156100cb57600080fd5b506100e660048036038101906100e19190610864565b610274565b6040516100f39190610b35565b60405180910390f35b34801561010857600080fd5b50610123600480360381019061011e9190610949565b61028c565b005b34801561013157600080fd5b5061014c60048036038101906101479190610900565b610347565b6040516101599190610b35565b60405180910390f35b61017c60048036038101906101779190610900565b61038a565b005b34801561018a57600080fd5b506101a560048036038101906101a09190610891565b6103b3565b005b3480156101b357600080fd5b506101ce60048036038101906101c99190610992565b610476565b005b3480156101dc57600080fd5b506101f760048036038101906101f29190610864565b61056f565b6040516102049190610b1a565b60405180910390f35b34801561021957600080fd5b50610234600480360381019061022f9190610900565b61058f565b6040516102419190610b1a565b60405180910390f35b610253816105de565b1561025d57600080fd5b61026681610634565b610271816000610688565b50565b60016020528060005260406000206000915090505481565b6102e781806040019061029f9190610b50565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610634565b6103448180604001906102fa9190610b50565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506000610688565b50565b6000600160008360405160200161035e9190610ab7565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b610393816105de565b1561039d57600080fd5b6103a681610634565b6103b08134610688565b50565b6103bc816105de565b156103c657600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161040393929190610ae3565b602060405180830381600087803b15801561041d57600080fd5b505af1158015610431573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104559190610837565b61045e57600080fd5b61046781610634565b6104718183610688565b505050565b6104c382828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506105de565b156104cd57600080fd5b61051a82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610634565b61056882828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084610688565b5050505050565b60006020528060005260406000206000915054906101000a900460ff1681565b6000806000836040516020016105a59190610ab7565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b60006040516020016105ef90610ace565b60405160208183030381529060405280519060200120826040516020016106169190610ab7565b60405160208183030381529060405280519060200120149050919050565b60016000808360405160200161064a9190610ab7565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b80600160008460405160200161069e9190610ab7565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b60006106dd6106d884610bd8565b610bb3565b9050828152602081018484840111156106f9576106f8610d48565b5b610704848285610c83565b509392505050565b60008135905061071b81610d91565b92915050565b60008151905061073081610da8565b92915050565b60008135905061074581610dbf565b92915050565b60008083601f84011261076157610760610d2a565b5b8235905067ffffffffffffffff81111561077e5761077d610d25565b5b60208301915083600182028301111561079a57610799610d3e565b5b9250929050565b6000813590506107b081610dd6565b92915050565b600082601f8301126107cb576107ca610d2a565b5b81356107db8482602086016106ca565b91505092915050565b6000606082840312156107fa576107f9610d34565b5b81905092915050565b60006060828403121561081957610818610d34565b5b81905092915050565b60008135905061083181610ded565b92915050565b60006020828403121561084d5761084c610d52565b5b600061085b84828501610721565b91505092915050565b60006020828403121561087a57610879610d52565b5b600061088884828501610736565b91505092915050565b6000806000606084860312156108aa576108a9610d52565b5b60006108b8868287016107a1565b93505060206108c986828701610822565b925050604084013567ffffffffffffffff8111156108ea576108e9610d4d565b5b6108f6868287016107b6565b9150509250925092565b60006020828403121561091657610915610d52565b5b600082013567ffffffffffffffff81111561093457610933610d4d565b5b610940848285016107b6565b91505092915050565b60006020828403121561095f5761095e610d52565b5b600082013567ffffffffffffffff81111561097d5761097c610d4d565b5b610989848285016107e4565b91505092915050565b6000806000806000608086880312156109ae576109ad610d52565b5b600086013567ffffffffffffffff8111156109cc576109cb610d4d565b5b6109d888828901610803565b95505060206109e98882890161070c565b94505060406109fa88828901610822565b935050606086013567ffffffffffffffff811115610a1b57610a1a610d4d565b5b610a278882890161074b565b92509250509295509295909350565b610a3f81610c1f565b82525050565b610a4e81610c31565b82525050565b6000610a5f82610c09565b610a698185610c14565b9350610a79818560208601610c92565b80840191505092915050565b6000610a92600683610c14565b9150610a9d82610d68565b600682019050919050565b610ab181610c79565b82525050565b6000610ac38284610a54565b915081905092915050565b6000610ad982610a85565b9150819050919050565b6000606082019050610af86000830186610a36565b610b056020830185610a36565b610b126040830184610aa8565b949350505050565b6000602082019050610b2f6000830184610a45565b92915050565b6000602082019050610b4a6000830184610aa8565b92915050565b60008083356001602003843603038112610b6d57610b6c610d39565b5b80840192508235915067ffffffffffffffff821115610b8f57610b8e610d2f565b5b602083019250600182023603831315610bab57610baa610d43565b5b509250929050565b6000610bbd610bce565b9050610bc98282610cc5565b919050565b6000604051905090565b600067ffffffffffffffff821115610bf357610bf2610cf6565b5b610bfc82610d57565b9050602081019050919050565b600081519050919050565b600081905092915050565b6000610c2a82610c59565b9050919050565b60008115159050919050565b6000819050919050565b6000610c5282610c1f565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015610cb0578082015181840152602081019050610c95565b83811115610cbf576000848401525b50505050565b610cce82610d57565b810181811067ffffffffffffffff82111715610ced57610cec610cf6565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b610d9a81610c1f565b8114610da557600080fd5b50565b610db181610c31565b8114610dbc57600080fd5b50565b610dc881610c3d565b8114610dd357600080fd5b50565b610ddf81610c47565b8114610dea57600080fd5b50565b610df681610c79565b8114610e0157600080fd5b5056fea2646970667358221220d6765b67214e8cadf15b569ed63c4c4628bd833acf6926d71b9b6a6011fbb78064736f6c63430008070033 +608060405234801561001057600080fd5b5061147c806100206000396000f3fe6080604052600436106100c65760003560e01c8063a799911f1161007f578063de43156e11610059578063de43156e14610267578063e2842ed714610290578063f592cbfb146102cd578063f936ae851461030a576100cd565b8063a799911f146101f9578063c234fecf14610215578063c7a339a91461023e576100cd565b806336e980a0146100d25780634297a263146100fb57806359f4a77714610138578063660b9de014610163578063676cc0541461018c5780639291fe26146101bc576100cd565b366100cd57005b600080fd5b3480156100de57600080fd5b506100f960048036038101906100f49190610b78565b610347565b005b34801561010757600080fd5b50610122600480360381019061011d9190610bf7565b610371565b60405161012f9190610c3d565b60405180910390f35b34801561014457600080fd5b5061014d610389565b60405161015a9190610c99565b60405180910390f35b34801561016f57600080fd5b5061018a60048036038101906101859190610cd8565b6103ad565b005b6101a660048036038101906101a19190610da0565b610468565b6040516101b39190610e88565b60405180910390f35b3480156101c857600080fd5b506101e360048036038101906101de9190610b78565b61061d565b6040516101f09190610c3d565b60405180910390f35b610213600480360381019061020e9190610b78565b610660565b005b34801561022157600080fd5b5061023c60048036038101906102379190610ed6565b610689565b005b34801561024a57600080fd5b5061026560048036038101906102609190610f6d565b6106cc565b005b34801561027357600080fd5b5061028e60048036038101906102899190610ffb565b610780565b005b34801561029c57600080fd5b506102b760048036038101906102b29190610bf7565b610879565b6040516102c491906110ba565b60405180910390f35b3480156102d957600080fd5b506102f460048036038101906102ef9190610b78565b610899565b60405161030191906110ba565b60405180910390f35b34801561031657600080fd5b50610331600480360381019061032c9190611176565b6108e9565b60405161033e9190610c99565b60405180910390f35b61035081610932565b1561035a57600080fd5b61036381610988565b61036e8160006109dc565b50565b60036020528060005260406000206000915090505481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6104088180604001906103c091906111ce565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b61046581806040019061041b91906111ce565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060006109dc565b50565b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168460000160208101906104b49190610ed6565b73ffffffffffffffffffffffffffffffffffffffff161461050a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105019061128e565b60405180910390fd5b61055783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b6105a583838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050346109dc565b8360000160208101906105b89190610ed6565b600284846040516105ca9291906112de565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509392505050565b60006003600083604051602001610634919061133e565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b61066981610932565b1561067357600080fd5b61067c81610988565b61068681346109dc565b50565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6106d581610932565b156106df57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161071c93929190611355565b6020604051808303816000875af115801561073b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075f91906113b8565b61076857600080fd5b61077181610988565b61077b81836109dc565b505050565b6107cd82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610932565b156107d757600080fd5b61082482828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b61087282828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050846109dc565b5050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b600060016000836040516020016108b0919061133e565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b6002818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060405160200161094390611431565b604051602081830303815290604052805190602001208260405160200161096a919061133e565b60405160208183030381529060405280519060200120149050919050565b60018060008360405160200161099e919061133e565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b8060036000846040516020016109f2919061133e565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610a8582610a3c565b810181811067ffffffffffffffff82111715610aa457610aa3610a4d565b5b80604052505050565b6000610ab7610a1e565b9050610ac38282610a7c565b919050565b600067ffffffffffffffff821115610ae357610ae2610a4d565b5b610aec82610a3c565b9050602081019050919050565b82818337600083830152505050565b6000610b1b610b1684610ac8565b610aad565b905082815260208101848484011115610b3757610b36610a37565b5b610b42848285610af9565b509392505050565b600082601f830112610b5f57610b5e610a32565b5b8135610b6f848260208601610b08565b91505092915050565b600060208284031215610b8e57610b8d610a28565b5b600082013567ffffffffffffffff811115610bac57610bab610a2d565b5b610bb884828501610b4a565b91505092915050565b6000819050919050565b610bd481610bc1565b8114610bdf57600080fd5b50565b600081359050610bf181610bcb565b92915050565b600060208284031215610c0d57610c0c610a28565b5b6000610c1b84828501610be2565b91505092915050565b6000819050919050565b610c3781610c24565b82525050565b6000602082019050610c526000830184610c2e565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610c8382610c58565b9050919050565b610c9381610c78565b82525050565b6000602082019050610cae6000830184610c8a565b92915050565b600080fd5b600060608284031215610ccf57610cce610cb4565b5b81905092915050565b600060208284031215610cee57610ced610a28565b5b600082013567ffffffffffffffff811115610d0c57610d0b610a2d565b5b610d1884828501610cb9565b91505092915050565b600060208284031215610d3757610d36610cb4565b5b81905092915050565b600080fd5b600080fd5b60008083601f840112610d6057610d5f610a32565b5b8235905067ffffffffffffffff811115610d7d57610d7c610d40565b5b602083019150836001820283011115610d9957610d98610d45565b5b9250929050565b600080600060408486031215610db957610db8610a28565b5b6000610dc786828701610d21565b935050602084013567ffffffffffffffff811115610de857610de7610a2d565b5b610df486828701610d4a565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b60005b83811015610e3a578082015181840152602081019050610e1f565b83811115610e49576000848401525b50505050565b6000610e5a82610e00565b610e648185610e0b565b9350610e74818560208601610e1c565b610e7d81610a3c565b840191505092915050565b60006020820190508181036000830152610ea28184610e4f565b905092915050565b610eb381610c78565b8114610ebe57600080fd5b50565b600081359050610ed081610eaa565b92915050565b600060208284031215610eec57610eeb610a28565b5b6000610efa84828501610ec1565b91505092915050565b6000610f0e82610c78565b9050919050565b610f1e81610f03565b8114610f2957600080fd5b50565b600081359050610f3b81610f15565b92915050565b610f4a81610c24565b8114610f5557600080fd5b50565b600081359050610f6781610f41565b92915050565b600080600060608486031215610f8657610f85610a28565b5b6000610f9486828701610f2c565b9350506020610fa586828701610f58565b925050604084013567ffffffffffffffff811115610fc657610fc5610a2d565b5b610fd286828701610b4a565b9150509250925092565b600060608284031215610ff257610ff1610cb4565b5b81905092915050565b60008060008060006080868803121561101757611016610a28565b5b600086013567ffffffffffffffff81111561103557611034610a2d565b5b61104188828901610fdc565b955050602061105288828901610ec1565b945050604061106388828901610f58565b935050606086013567ffffffffffffffff81111561108457611083610a2d565b5b61109088828901610d4a565b92509250509295509295909350565b60008115159050919050565b6110b48161109f565b82525050565b60006020820190506110cf60008301846110ab565b92915050565b600067ffffffffffffffff8211156110f0576110ef610a4d565b5b6110f982610a3c565b9050602081019050919050565b6000611119611114846110d5565b610aad565b90508281526020810184848401111561113557611134610a37565b5b611140848285610af9565b509392505050565b600082601f83011261115d5761115c610a32565b5b813561116d848260208601611106565b91505092915050565b60006020828403121561118c5761118b610a28565b5b600082013567ffffffffffffffff8111156111aa576111a9610a2d565b5b6111b684828501611148565b91505092915050565b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126111eb576111ea6111bf565b5b80840192508235915067ffffffffffffffff82111561120d5761120c6111c4565b5b602083019250600182023603831315611229576112286111c9565b5b509250929050565b600082825260208201905092915050565b7f756e61757468656e746963617465642073656e64657200000000000000000000600082015250565b6000611278601683611231565b915061128382611242565b602082019050919050565b600060208201905081810360008301526112a78161126b565b9050919050565b600081905092915050565b60006112c583856112ae565b93506112d2838584610af9565b82840190509392505050565b60006112eb8284866112b9565b91508190509392505050565b600081519050919050565b600081905092915050565b6000611318826112f7565b6113228185611302565b9350611332818560208601610e1c565b80840191505092915050565b600061134a828461130d565b915081905092915050565b600060608201905061136a6000830186610c8a565b6113776020830185610c8a565b6113846040830184610c2e565b949350505050565b6113958161109f565b81146113a057600080fd5b50565b6000815190506113b28161138c565b92915050565b6000602082840312156113ce576113cd610a28565b5b60006113dc848285016113a3565b91505092915050565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b600061141b600683611302565b9150611426826113e5565b600682019050919050565b600061143c8261140e565b915081905091905056fea264697066735822122046fb444f8c754142359339f5f1d728822414688169d0d22f23bd25c688c73fdf64736f6c634300080a0033 diff --git a/pkg/contracts/testdappv2/TestDAppV2.go b/pkg/contracts/testdappv2/TestDAppV2.go index 9afe3b5c9d..689014c847 100644 --- a/pkg/contracts/testdappv2/TestDAppV2.go +++ b/pkg/contracts/testdappv2/TestDAppV2.go @@ -29,6 +29,11 @@ var ( _ = abi.ConvertType ) +// TestDAppV2MessageContext is an auto generated low-level Go binding around an user-defined struct. +type TestDAppV2MessageContext struct { + Sender common.Address +} + // TestDAppV2RevertContext is an auto generated low-level Go binding around an user-defined struct. type TestDAppV2RevertContext struct { Asset common.Address @@ -45,8 +50,8 @@ type TestDAppV2zContext struct { // TestDAppV2MetaData contains all meta data concerning the TestDAppV2 contract. var TestDAppV2MetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"amountWithMessage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"calledWithMessage\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"erc20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"erc20Call\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"gasCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"getAmountWithMessage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"getCalledWithMessage\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"origin\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainID\",\"type\":\"uint256\"}],\"internalType\":\"structTestDAppV2.zContext\",\"name\":\"_context\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"_zrc20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"onCrossChainCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"amount\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"revertMessage\",\"type\":\"bytes\"}],\"internalType\":\"structTestDAppV2.RevertContext\",\"name\":\"revertContext\",\"type\":\"tuple\"}],\"name\":\"onRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"simpleCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", - Bin: "0x608060405234801561001057600080fd5b50610e3a806100206000396000f3fe60806040526004361061008a5760003560e01c8063a799911f11610059578063a799911f14610162578063c7a339a91461017e578063de43156e146101a7578063e2842ed7146101d0578063f592cbfb1461020d57610091565b806336e980a0146100965780634297a263146100bf578063660b9de0146100fc5780639291fe261461012557610091565b3661009157005b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190610900565b61024a565b005b3480156100cb57600080fd5b506100e660048036038101906100e19190610864565b610274565b6040516100f39190610b35565b60405180910390f35b34801561010857600080fd5b50610123600480360381019061011e9190610949565b61028c565b005b34801561013157600080fd5b5061014c60048036038101906101479190610900565b610347565b6040516101599190610b35565b60405180910390f35b61017c60048036038101906101779190610900565b61038a565b005b34801561018a57600080fd5b506101a560048036038101906101a09190610891565b6103b3565b005b3480156101b357600080fd5b506101ce60048036038101906101c99190610992565b610476565b005b3480156101dc57600080fd5b506101f760048036038101906101f29190610864565b61056f565b6040516102049190610b1a565b60405180910390f35b34801561021957600080fd5b50610234600480360381019061022f9190610900565b61058f565b6040516102419190610b1a565b60405180910390f35b610253816105de565b1561025d57600080fd5b61026681610634565b610271816000610688565b50565b60016020528060005260406000206000915090505481565b6102e781806040019061029f9190610b50565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610634565b6103448180604001906102fa9190610b50565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506000610688565b50565b6000600160008360405160200161035e9190610ab7565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b610393816105de565b1561039d57600080fd5b6103a681610634565b6103b08134610688565b50565b6103bc816105de565b156103c657600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161040393929190610ae3565b602060405180830381600087803b15801561041d57600080fd5b505af1158015610431573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104559190610837565b61045e57600080fd5b61046781610634565b6104718183610688565b505050565b6104c382828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506105de565b156104cd57600080fd5b61051a82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610634565b61056882828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084610688565b5050505050565b60006020528060005260406000206000915054906101000a900460ff1681565b6000806000836040516020016105a59190610ab7565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b60006040516020016105ef90610ace565b60405160208183030381529060405280519060200120826040516020016106169190610ab7565b60405160208183030381529060405280519060200120149050919050565b60016000808360405160200161064a9190610ab7565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b80600160008460405160200161069e9190610ab7565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b60006106dd6106d884610bd8565b610bb3565b9050828152602081018484840111156106f9576106f8610d48565b5b610704848285610c83565b509392505050565b60008135905061071b81610d91565b92915050565b60008151905061073081610da8565b92915050565b60008135905061074581610dbf565b92915050565b60008083601f84011261076157610760610d2a565b5b8235905067ffffffffffffffff81111561077e5761077d610d25565b5b60208301915083600182028301111561079a57610799610d3e565b5b9250929050565b6000813590506107b081610dd6565b92915050565b600082601f8301126107cb576107ca610d2a565b5b81356107db8482602086016106ca565b91505092915050565b6000606082840312156107fa576107f9610d34565b5b81905092915050565b60006060828403121561081957610818610d34565b5b81905092915050565b60008135905061083181610ded565b92915050565b60006020828403121561084d5761084c610d52565b5b600061085b84828501610721565b91505092915050565b60006020828403121561087a57610879610d52565b5b600061088884828501610736565b91505092915050565b6000806000606084860312156108aa576108a9610d52565b5b60006108b8868287016107a1565b93505060206108c986828701610822565b925050604084013567ffffffffffffffff8111156108ea576108e9610d4d565b5b6108f6868287016107b6565b9150509250925092565b60006020828403121561091657610915610d52565b5b600082013567ffffffffffffffff81111561093457610933610d4d565b5b610940848285016107b6565b91505092915050565b60006020828403121561095f5761095e610d52565b5b600082013567ffffffffffffffff81111561097d5761097c610d4d565b5b610989848285016107e4565b91505092915050565b6000806000806000608086880312156109ae576109ad610d52565b5b600086013567ffffffffffffffff8111156109cc576109cb610d4d565b5b6109d888828901610803565b95505060206109e98882890161070c565b94505060406109fa88828901610822565b935050606086013567ffffffffffffffff811115610a1b57610a1a610d4d565b5b610a278882890161074b565b92509250509295509295909350565b610a3f81610c1f565b82525050565b610a4e81610c31565b82525050565b6000610a5f82610c09565b610a698185610c14565b9350610a79818560208601610c92565b80840191505092915050565b6000610a92600683610c14565b9150610a9d82610d68565b600682019050919050565b610ab181610c79565b82525050565b6000610ac38284610a54565b915081905092915050565b6000610ad982610a85565b9150819050919050565b6000606082019050610af86000830186610a36565b610b056020830185610a36565b610b126040830184610aa8565b949350505050565b6000602082019050610b2f6000830184610a45565b92915050565b6000602082019050610b4a6000830184610aa8565b92915050565b60008083356001602003843603038112610b6d57610b6c610d39565b5b80840192508235915067ffffffffffffffff821115610b8f57610b8e610d2f565b5b602083019250600182023603831315610bab57610baa610d43565b5b509250929050565b6000610bbd610bce565b9050610bc98282610cc5565b919050565b6000604051905090565b600067ffffffffffffffff821115610bf357610bf2610cf6565b5b610bfc82610d57565b9050602081019050919050565b600081519050919050565b600081905092915050565b6000610c2a82610c59565b9050919050565b60008115159050919050565b6000819050919050565b6000610c5282610c1f565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015610cb0578082015181840152602081019050610c95565b83811115610cbf576000848401525b50505050565b610cce82610d57565b810181811067ffffffffffffffff82111715610ced57610cec610cf6565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b610d9a81610c1f565b8114610da557600080fd5b50565b610db181610c31565b8114610dbc57600080fd5b50565b610dc881610c3d565b8114610dd357600080fd5b50565b610ddf81610c47565b8114610dea57600080fd5b50565b610df681610c79565b8114610e0157600080fd5b5056fea2646970667358221220d6765b67214e8cadf15b569ed63c4c4628bd833acf6926d71b9b6a6011fbb78064736f6c63430008070033", + ABI: "[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"amountWithMessage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"calledWithMessage\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"erc20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"erc20Call\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"expectedOnCallSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"gasCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"getAmountWithMessage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"getCalledWithMessage\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"internalType\":\"structTestDAppV2.MessageContext\",\"name\":\"messageContext\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"onCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"origin\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainID\",\"type\":\"uint256\"}],\"internalType\":\"structTestDAppV2.zContext\",\"name\":\"_context\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"_zrc20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"onCrossChainCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"amount\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"revertMessage\",\"type\":\"bytes\"}],\"internalType\":\"structTestDAppV2.RevertContext\",\"name\":\"revertContext\",\"type\":\"tuple\"}],\"name\":\"onRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"senderWithMessage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_expectedOnCallSender\",\"type\":\"address\"}],\"name\":\"setExpectedOnCallSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"simpleCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x608060405234801561001057600080fd5b5061147c806100206000396000f3fe6080604052600436106100c65760003560e01c8063a799911f1161007f578063de43156e11610059578063de43156e14610267578063e2842ed714610290578063f592cbfb146102cd578063f936ae851461030a576100cd565b8063a799911f146101f9578063c234fecf14610215578063c7a339a91461023e576100cd565b806336e980a0146100d25780634297a263146100fb57806359f4a77714610138578063660b9de014610163578063676cc0541461018c5780639291fe26146101bc576100cd565b366100cd57005b600080fd5b3480156100de57600080fd5b506100f960048036038101906100f49190610b78565b610347565b005b34801561010757600080fd5b50610122600480360381019061011d9190610bf7565b610371565b60405161012f9190610c3d565b60405180910390f35b34801561014457600080fd5b5061014d610389565b60405161015a9190610c99565b60405180910390f35b34801561016f57600080fd5b5061018a60048036038101906101859190610cd8565b6103ad565b005b6101a660048036038101906101a19190610da0565b610468565b6040516101b39190610e88565b60405180910390f35b3480156101c857600080fd5b506101e360048036038101906101de9190610b78565b61061d565b6040516101f09190610c3d565b60405180910390f35b610213600480360381019061020e9190610b78565b610660565b005b34801561022157600080fd5b5061023c60048036038101906102379190610ed6565b610689565b005b34801561024a57600080fd5b5061026560048036038101906102609190610f6d565b6106cc565b005b34801561027357600080fd5b5061028e60048036038101906102899190610ffb565b610780565b005b34801561029c57600080fd5b506102b760048036038101906102b29190610bf7565b610879565b6040516102c491906110ba565b60405180910390f35b3480156102d957600080fd5b506102f460048036038101906102ef9190610b78565b610899565b60405161030191906110ba565b60405180910390f35b34801561031657600080fd5b50610331600480360381019061032c9190611176565b6108e9565b60405161033e9190610c99565b60405180910390f35b61035081610932565b1561035a57600080fd5b61036381610988565b61036e8160006109dc565b50565b60036020528060005260406000206000915090505481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6104088180604001906103c091906111ce565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b61046581806040019061041b91906111ce565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060006109dc565b50565b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168460000160208101906104b49190610ed6565b73ffffffffffffffffffffffffffffffffffffffff161461050a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105019061128e565b60405180910390fd5b61055783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b6105a583838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050346109dc565b8360000160208101906105b89190610ed6565b600284846040516105ca9291906112de565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509392505050565b60006003600083604051602001610634919061133e565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b61066981610932565b1561067357600080fd5b61067c81610988565b61068681346109dc565b50565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6106d581610932565b156106df57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161071c93929190611355565b6020604051808303816000875af115801561073b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075f91906113b8565b61076857600080fd5b61077181610988565b61077b81836109dc565b505050565b6107cd82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610932565b156107d757600080fd5b61082482828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b61087282828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050846109dc565b5050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b600060016000836040516020016108b0919061133e565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b6002818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060405160200161094390611431565b604051602081830303815290604052805190602001208260405160200161096a919061133e565b60405160208183030381529060405280519060200120149050919050565b60018060008360405160200161099e919061133e565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b8060036000846040516020016109f2919061133e565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610a8582610a3c565b810181811067ffffffffffffffff82111715610aa457610aa3610a4d565b5b80604052505050565b6000610ab7610a1e565b9050610ac38282610a7c565b919050565b600067ffffffffffffffff821115610ae357610ae2610a4d565b5b610aec82610a3c565b9050602081019050919050565b82818337600083830152505050565b6000610b1b610b1684610ac8565b610aad565b905082815260208101848484011115610b3757610b36610a37565b5b610b42848285610af9565b509392505050565b600082601f830112610b5f57610b5e610a32565b5b8135610b6f848260208601610b08565b91505092915050565b600060208284031215610b8e57610b8d610a28565b5b600082013567ffffffffffffffff811115610bac57610bab610a2d565b5b610bb884828501610b4a565b91505092915050565b6000819050919050565b610bd481610bc1565b8114610bdf57600080fd5b50565b600081359050610bf181610bcb565b92915050565b600060208284031215610c0d57610c0c610a28565b5b6000610c1b84828501610be2565b91505092915050565b6000819050919050565b610c3781610c24565b82525050565b6000602082019050610c526000830184610c2e565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610c8382610c58565b9050919050565b610c9381610c78565b82525050565b6000602082019050610cae6000830184610c8a565b92915050565b600080fd5b600060608284031215610ccf57610cce610cb4565b5b81905092915050565b600060208284031215610cee57610ced610a28565b5b600082013567ffffffffffffffff811115610d0c57610d0b610a2d565b5b610d1884828501610cb9565b91505092915050565b600060208284031215610d3757610d36610cb4565b5b81905092915050565b600080fd5b600080fd5b60008083601f840112610d6057610d5f610a32565b5b8235905067ffffffffffffffff811115610d7d57610d7c610d40565b5b602083019150836001820283011115610d9957610d98610d45565b5b9250929050565b600080600060408486031215610db957610db8610a28565b5b6000610dc786828701610d21565b935050602084013567ffffffffffffffff811115610de857610de7610a2d565b5b610df486828701610d4a565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b60005b83811015610e3a578082015181840152602081019050610e1f565b83811115610e49576000848401525b50505050565b6000610e5a82610e00565b610e648185610e0b565b9350610e74818560208601610e1c565b610e7d81610a3c565b840191505092915050565b60006020820190508181036000830152610ea28184610e4f565b905092915050565b610eb381610c78565b8114610ebe57600080fd5b50565b600081359050610ed081610eaa565b92915050565b600060208284031215610eec57610eeb610a28565b5b6000610efa84828501610ec1565b91505092915050565b6000610f0e82610c78565b9050919050565b610f1e81610f03565b8114610f2957600080fd5b50565b600081359050610f3b81610f15565b92915050565b610f4a81610c24565b8114610f5557600080fd5b50565b600081359050610f6781610f41565b92915050565b600080600060608486031215610f8657610f85610a28565b5b6000610f9486828701610f2c565b9350506020610fa586828701610f58565b925050604084013567ffffffffffffffff811115610fc657610fc5610a2d565b5b610fd286828701610b4a565b9150509250925092565b600060608284031215610ff257610ff1610cb4565b5b81905092915050565b60008060008060006080868803121561101757611016610a28565b5b600086013567ffffffffffffffff81111561103557611034610a2d565b5b61104188828901610fdc565b955050602061105288828901610ec1565b945050604061106388828901610f58565b935050606086013567ffffffffffffffff81111561108457611083610a2d565b5b61109088828901610d4a565b92509250509295509295909350565b60008115159050919050565b6110b48161109f565b82525050565b60006020820190506110cf60008301846110ab565b92915050565b600067ffffffffffffffff8211156110f0576110ef610a4d565b5b6110f982610a3c565b9050602081019050919050565b6000611119611114846110d5565b610aad565b90508281526020810184848401111561113557611134610a37565b5b611140848285610af9565b509392505050565b600082601f83011261115d5761115c610a32565b5b813561116d848260208601611106565b91505092915050565b60006020828403121561118c5761118b610a28565b5b600082013567ffffffffffffffff8111156111aa576111a9610a2d565b5b6111b684828501611148565b91505092915050565b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126111eb576111ea6111bf565b5b80840192508235915067ffffffffffffffff82111561120d5761120c6111c4565b5b602083019250600182023603831315611229576112286111c9565b5b509250929050565b600082825260208201905092915050565b7f756e61757468656e746963617465642073656e64657200000000000000000000600082015250565b6000611278601683611231565b915061128382611242565b602082019050919050565b600060208201905081810360008301526112a78161126b565b9050919050565b600081905092915050565b60006112c583856112ae565b93506112d2838584610af9565b82840190509392505050565b60006112eb8284866112b9565b91508190509392505050565b600081519050919050565b600081905092915050565b6000611318826112f7565b6113228185611302565b9350611332818560208601610e1c565b80840191505092915050565b600061134a828461130d565b915081905092915050565b600060608201905061136a6000830186610c8a565b6113776020830185610c8a565b6113846040830184610c2e565b949350505050565b6113958161109f565b81146113a057600080fd5b50565b6000815190506113b28161138c565b92915050565b6000602082840312156113ce576113cd610a28565b5b60006113dc848285016113a3565b91505092915050565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b600061141b600683611302565b9150611426826113e5565b600682019050919050565b600061143c8261140e565b915081905091905056fea264697066735822122046fb444f8c754142359339f5f1d728822414688169d0d22f23bd25c688c73fdf64736f6c634300080a0033", } // TestDAppV2ABI is the input ABI used to generate the binding from. @@ -278,6 +283,37 @@ func (_TestDAppV2 *TestDAppV2CallerSession) CalledWithMessage(arg0 [32]byte) (bo return _TestDAppV2.Contract.CalledWithMessage(&_TestDAppV2.CallOpts, arg0) } +// ExpectedOnCallSender is a free data retrieval call binding the contract method 0x59f4a777. +// +// Solidity: function expectedOnCallSender() view returns(address) +func (_TestDAppV2 *TestDAppV2Caller) ExpectedOnCallSender(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TestDAppV2.contract.Call(opts, &out, "expectedOnCallSender") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// ExpectedOnCallSender is a free data retrieval call binding the contract method 0x59f4a777. +// +// Solidity: function expectedOnCallSender() view returns(address) +func (_TestDAppV2 *TestDAppV2Session) ExpectedOnCallSender() (common.Address, error) { + return _TestDAppV2.Contract.ExpectedOnCallSender(&_TestDAppV2.CallOpts) +} + +// ExpectedOnCallSender is a free data retrieval call binding the contract method 0x59f4a777. +// +// Solidity: function expectedOnCallSender() view returns(address) +func (_TestDAppV2 *TestDAppV2CallerSession) ExpectedOnCallSender() (common.Address, error) { + return _TestDAppV2.Contract.ExpectedOnCallSender(&_TestDAppV2.CallOpts) +} + // GetAmountWithMessage is a free data retrieval call binding the contract method 0x9291fe26. // // Solidity: function getAmountWithMessage(string message) view returns(uint256) @@ -340,6 +376,37 @@ func (_TestDAppV2 *TestDAppV2CallerSession) GetCalledWithMessage(message string) return _TestDAppV2.Contract.GetCalledWithMessage(&_TestDAppV2.CallOpts, message) } +// SenderWithMessage is a free data retrieval call binding the contract method 0xf936ae85. +// +// Solidity: function senderWithMessage(bytes ) view returns(address) +func (_TestDAppV2 *TestDAppV2Caller) SenderWithMessage(opts *bind.CallOpts, arg0 []byte) (common.Address, error) { + var out []interface{} + err := _TestDAppV2.contract.Call(opts, &out, "senderWithMessage", arg0) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SenderWithMessage is a free data retrieval call binding the contract method 0xf936ae85. +// +// Solidity: function senderWithMessage(bytes ) view returns(address) +func (_TestDAppV2 *TestDAppV2Session) SenderWithMessage(arg0 []byte) (common.Address, error) { + return _TestDAppV2.Contract.SenderWithMessage(&_TestDAppV2.CallOpts, arg0) +} + +// SenderWithMessage is a free data retrieval call binding the contract method 0xf936ae85. +// +// Solidity: function senderWithMessage(bytes ) view returns(address) +func (_TestDAppV2 *TestDAppV2CallerSession) SenderWithMessage(arg0 []byte) (common.Address, error) { + return _TestDAppV2.Contract.SenderWithMessage(&_TestDAppV2.CallOpts, arg0) +} + // Erc20Call is a paid mutator transaction binding the contract method 0xc7a339a9. // // Solidity: function erc20Call(address erc20, uint256 amount, string message) returns() @@ -382,6 +449,27 @@ func (_TestDAppV2 *TestDAppV2TransactorSession) GasCall(message string) (*types. return _TestDAppV2.Contract.GasCall(&_TestDAppV2.TransactOpts, message) } +// OnCall is a paid mutator transaction binding the contract method 0x676cc054. +// +// Solidity: function onCall((address) messageContext, bytes message) payable returns(bytes) +func (_TestDAppV2 *TestDAppV2Transactor) OnCall(opts *bind.TransactOpts, messageContext TestDAppV2MessageContext, message []byte) (*types.Transaction, error) { + return _TestDAppV2.contract.Transact(opts, "onCall", messageContext, message) +} + +// OnCall is a paid mutator transaction binding the contract method 0x676cc054. +// +// Solidity: function onCall((address) messageContext, bytes message) payable returns(bytes) +func (_TestDAppV2 *TestDAppV2Session) OnCall(messageContext TestDAppV2MessageContext, message []byte) (*types.Transaction, error) { + return _TestDAppV2.Contract.OnCall(&_TestDAppV2.TransactOpts, messageContext, message) +} + +// OnCall is a paid mutator transaction binding the contract method 0x676cc054. +// +// Solidity: function onCall((address) messageContext, bytes message) payable returns(bytes) +func (_TestDAppV2 *TestDAppV2TransactorSession) OnCall(messageContext TestDAppV2MessageContext, message []byte) (*types.Transaction, error) { + return _TestDAppV2.Contract.OnCall(&_TestDAppV2.TransactOpts, messageContext, message) +} + // OnCrossChainCall is a paid mutator transaction binding the contract method 0xde43156e. // // Solidity: function onCrossChainCall((bytes,address,uint256) _context, address _zrc20, uint256 amount, bytes message) returns() @@ -424,6 +512,27 @@ func (_TestDAppV2 *TestDAppV2TransactorSession) OnRevert(revertContext TestDAppV return _TestDAppV2.Contract.OnRevert(&_TestDAppV2.TransactOpts, revertContext) } +// SetExpectedOnCallSender is a paid mutator transaction binding the contract method 0xc234fecf. +// +// Solidity: function setExpectedOnCallSender(address _expectedOnCallSender) returns() +func (_TestDAppV2 *TestDAppV2Transactor) SetExpectedOnCallSender(opts *bind.TransactOpts, _expectedOnCallSender common.Address) (*types.Transaction, error) { + return _TestDAppV2.contract.Transact(opts, "setExpectedOnCallSender", _expectedOnCallSender) +} + +// SetExpectedOnCallSender is a paid mutator transaction binding the contract method 0xc234fecf. +// +// Solidity: function setExpectedOnCallSender(address _expectedOnCallSender) returns() +func (_TestDAppV2 *TestDAppV2Session) SetExpectedOnCallSender(_expectedOnCallSender common.Address) (*types.Transaction, error) { + return _TestDAppV2.Contract.SetExpectedOnCallSender(&_TestDAppV2.TransactOpts, _expectedOnCallSender) +} + +// SetExpectedOnCallSender is a paid mutator transaction binding the contract method 0xc234fecf. +// +// Solidity: function setExpectedOnCallSender(address _expectedOnCallSender) returns() +func (_TestDAppV2 *TestDAppV2TransactorSession) SetExpectedOnCallSender(_expectedOnCallSender common.Address) (*types.Transaction, error) { + return _TestDAppV2.Contract.SetExpectedOnCallSender(&_TestDAppV2.TransactOpts, _expectedOnCallSender) +} + // SimpleCall is a paid mutator transaction binding the contract method 0x36e980a0. // // Solidity: function simpleCall(string message) returns() diff --git a/pkg/contracts/testdappv2/TestDAppV2.json b/pkg/contracts/testdappv2/TestDAppV2.json index bcac60c189..04cbd8756a 100644 --- a/pkg/contracts/testdappv2/TestDAppV2.json +++ b/pkg/contracts/testdappv2/TestDAppV2.json @@ -61,6 +61,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "expectedOnCallSender", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -112,6 +125,37 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "internalType": "struct TestDAppV2.MessageContext", + "name": "messageContext", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "name": "onCall", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -187,6 +231,38 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "senderWithMessage", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_expectedOnCallSender", + "type": "address" + } + ], + "name": "setExpectedOnCallSender", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -205,5 +281,5 @@ "type": "receive" } ], - "bin": "608060405234801561001057600080fd5b50610e3a806100206000396000f3fe60806040526004361061008a5760003560e01c8063a799911f11610059578063a799911f14610162578063c7a339a91461017e578063de43156e146101a7578063e2842ed7146101d0578063f592cbfb1461020d57610091565b806336e980a0146100965780634297a263146100bf578063660b9de0146100fc5780639291fe261461012557610091565b3661009157005b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190610900565b61024a565b005b3480156100cb57600080fd5b506100e660048036038101906100e19190610864565b610274565b6040516100f39190610b35565b60405180910390f35b34801561010857600080fd5b50610123600480360381019061011e9190610949565b61028c565b005b34801561013157600080fd5b5061014c60048036038101906101479190610900565b610347565b6040516101599190610b35565b60405180910390f35b61017c60048036038101906101779190610900565b61038a565b005b34801561018a57600080fd5b506101a560048036038101906101a09190610891565b6103b3565b005b3480156101b357600080fd5b506101ce60048036038101906101c99190610992565b610476565b005b3480156101dc57600080fd5b506101f760048036038101906101f29190610864565b61056f565b6040516102049190610b1a565b60405180910390f35b34801561021957600080fd5b50610234600480360381019061022f9190610900565b61058f565b6040516102419190610b1a565b60405180910390f35b610253816105de565b1561025d57600080fd5b61026681610634565b610271816000610688565b50565b60016020528060005260406000206000915090505481565b6102e781806040019061029f9190610b50565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610634565b6103448180604001906102fa9190610b50565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506000610688565b50565b6000600160008360405160200161035e9190610ab7565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b610393816105de565b1561039d57600080fd5b6103a681610634565b6103b08134610688565b50565b6103bc816105de565b156103c657600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161040393929190610ae3565b602060405180830381600087803b15801561041d57600080fd5b505af1158015610431573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104559190610837565b61045e57600080fd5b61046781610634565b6104718183610688565b505050565b6104c382828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506105de565b156104cd57600080fd5b61051a82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610634565b61056882828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084610688565b5050505050565b60006020528060005260406000206000915054906101000a900460ff1681565b6000806000836040516020016105a59190610ab7565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b60006040516020016105ef90610ace565b60405160208183030381529060405280519060200120826040516020016106169190610ab7565b60405160208183030381529060405280519060200120149050919050565b60016000808360405160200161064a9190610ab7565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b80600160008460405160200161069e9190610ab7565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b60006106dd6106d884610bd8565b610bb3565b9050828152602081018484840111156106f9576106f8610d48565b5b610704848285610c83565b509392505050565b60008135905061071b81610d91565b92915050565b60008151905061073081610da8565b92915050565b60008135905061074581610dbf565b92915050565b60008083601f84011261076157610760610d2a565b5b8235905067ffffffffffffffff81111561077e5761077d610d25565b5b60208301915083600182028301111561079a57610799610d3e565b5b9250929050565b6000813590506107b081610dd6565b92915050565b600082601f8301126107cb576107ca610d2a565b5b81356107db8482602086016106ca565b91505092915050565b6000606082840312156107fa576107f9610d34565b5b81905092915050565b60006060828403121561081957610818610d34565b5b81905092915050565b60008135905061083181610ded565b92915050565b60006020828403121561084d5761084c610d52565b5b600061085b84828501610721565b91505092915050565b60006020828403121561087a57610879610d52565b5b600061088884828501610736565b91505092915050565b6000806000606084860312156108aa576108a9610d52565b5b60006108b8868287016107a1565b93505060206108c986828701610822565b925050604084013567ffffffffffffffff8111156108ea576108e9610d4d565b5b6108f6868287016107b6565b9150509250925092565b60006020828403121561091657610915610d52565b5b600082013567ffffffffffffffff81111561093457610933610d4d565b5b610940848285016107b6565b91505092915050565b60006020828403121561095f5761095e610d52565b5b600082013567ffffffffffffffff81111561097d5761097c610d4d565b5b610989848285016107e4565b91505092915050565b6000806000806000608086880312156109ae576109ad610d52565b5b600086013567ffffffffffffffff8111156109cc576109cb610d4d565b5b6109d888828901610803565b95505060206109e98882890161070c565b94505060406109fa88828901610822565b935050606086013567ffffffffffffffff811115610a1b57610a1a610d4d565b5b610a278882890161074b565b92509250509295509295909350565b610a3f81610c1f565b82525050565b610a4e81610c31565b82525050565b6000610a5f82610c09565b610a698185610c14565b9350610a79818560208601610c92565b80840191505092915050565b6000610a92600683610c14565b9150610a9d82610d68565b600682019050919050565b610ab181610c79565b82525050565b6000610ac38284610a54565b915081905092915050565b6000610ad982610a85565b9150819050919050565b6000606082019050610af86000830186610a36565b610b056020830185610a36565b610b126040830184610aa8565b949350505050565b6000602082019050610b2f6000830184610a45565b92915050565b6000602082019050610b4a6000830184610aa8565b92915050565b60008083356001602003843603038112610b6d57610b6c610d39565b5b80840192508235915067ffffffffffffffff821115610b8f57610b8e610d2f565b5b602083019250600182023603831315610bab57610baa610d43565b5b509250929050565b6000610bbd610bce565b9050610bc98282610cc5565b919050565b6000604051905090565b600067ffffffffffffffff821115610bf357610bf2610cf6565b5b610bfc82610d57565b9050602081019050919050565b600081519050919050565b600081905092915050565b6000610c2a82610c59565b9050919050565b60008115159050919050565b6000819050919050565b6000610c5282610c1f565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015610cb0578082015181840152602081019050610c95565b83811115610cbf576000848401525b50505050565b610cce82610d57565b810181811067ffffffffffffffff82111715610ced57610cec610cf6565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b610d9a81610c1f565b8114610da557600080fd5b50565b610db181610c31565b8114610dbc57600080fd5b50565b610dc881610c3d565b8114610dd357600080fd5b50565b610ddf81610c47565b8114610dea57600080fd5b50565b610df681610c79565b8114610e0157600080fd5b5056fea2646970667358221220d6765b67214e8cadf15b569ed63c4c4628bd833acf6926d71b9b6a6011fbb78064736f6c63430008070033" + "bin": "608060405234801561001057600080fd5b5061147c806100206000396000f3fe6080604052600436106100c65760003560e01c8063a799911f1161007f578063de43156e11610059578063de43156e14610267578063e2842ed714610290578063f592cbfb146102cd578063f936ae851461030a576100cd565b8063a799911f146101f9578063c234fecf14610215578063c7a339a91461023e576100cd565b806336e980a0146100d25780634297a263146100fb57806359f4a77714610138578063660b9de014610163578063676cc0541461018c5780639291fe26146101bc576100cd565b366100cd57005b600080fd5b3480156100de57600080fd5b506100f960048036038101906100f49190610b78565b610347565b005b34801561010757600080fd5b50610122600480360381019061011d9190610bf7565b610371565b60405161012f9190610c3d565b60405180910390f35b34801561014457600080fd5b5061014d610389565b60405161015a9190610c99565b60405180910390f35b34801561016f57600080fd5b5061018a60048036038101906101859190610cd8565b6103ad565b005b6101a660048036038101906101a19190610da0565b610468565b6040516101b39190610e88565b60405180910390f35b3480156101c857600080fd5b506101e360048036038101906101de9190610b78565b61061d565b6040516101f09190610c3d565b60405180910390f35b610213600480360381019061020e9190610b78565b610660565b005b34801561022157600080fd5b5061023c60048036038101906102379190610ed6565b610689565b005b34801561024a57600080fd5b5061026560048036038101906102609190610f6d565b6106cc565b005b34801561027357600080fd5b5061028e60048036038101906102899190610ffb565b610780565b005b34801561029c57600080fd5b506102b760048036038101906102b29190610bf7565b610879565b6040516102c491906110ba565b60405180910390f35b3480156102d957600080fd5b506102f460048036038101906102ef9190610b78565b610899565b60405161030191906110ba565b60405180910390f35b34801561031657600080fd5b50610331600480360381019061032c9190611176565b6108e9565b60405161033e9190610c99565b60405180910390f35b61035081610932565b1561035a57600080fd5b61036381610988565b61036e8160006109dc565b50565b60036020528060005260406000206000915090505481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6104088180604001906103c091906111ce565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b61046581806040019061041b91906111ce565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060006109dc565b50565b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168460000160208101906104b49190610ed6565b73ffffffffffffffffffffffffffffffffffffffff161461050a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105019061128e565b60405180910390fd5b61055783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b6105a583838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050346109dc565b8360000160208101906105b89190610ed6565b600284846040516105ca9291906112de565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509392505050565b60006003600083604051602001610634919061133e565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b61066981610932565b1561067357600080fd5b61067c81610988565b61068681346109dc565b50565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6106d581610932565b156106df57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161071c93929190611355565b6020604051808303816000875af115801561073b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075f91906113b8565b61076857600080fd5b61077181610988565b61077b81836109dc565b505050565b6107cd82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610932565b156107d757600080fd5b61082482828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b61087282828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050846109dc565b5050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b600060016000836040516020016108b0919061133e565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b6002818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060405160200161094390611431565b604051602081830303815290604052805190602001208260405160200161096a919061133e565b60405160208183030381529060405280519060200120149050919050565b60018060008360405160200161099e919061133e565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b8060036000846040516020016109f2919061133e565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610a8582610a3c565b810181811067ffffffffffffffff82111715610aa457610aa3610a4d565b5b80604052505050565b6000610ab7610a1e565b9050610ac38282610a7c565b919050565b600067ffffffffffffffff821115610ae357610ae2610a4d565b5b610aec82610a3c565b9050602081019050919050565b82818337600083830152505050565b6000610b1b610b1684610ac8565b610aad565b905082815260208101848484011115610b3757610b36610a37565b5b610b42848285610af9565b509392505050565b600082601f830112610b5f57610b5e610a32565b5b8135610b6f848260208601610b08565b91505092915050565b600060208284031215610b8e57610b8d610a28565b5b600082013567ffffffffffffffff811115610bac57610bab610a2d565b5b610bb884828501610b4a565b91505092915050565b6000819050919050565b610bd481610bc1565b8114610bdf57600080fd5b50565b600081359050610bf181610bcb565b92915050565b600060208284031215610c0d57610c0c610a28565b5b6000610c1b84828501610be2565b91505092915050565b6000819050919050565b610c3781610c24565b82525050565b6000602082019050610c526000830184610c2e565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610c8382610c58565b9050919050565b610c9381610c78565b82525050565b6000602082019050610cae6000830184610c8a565b92915050565b600080fd5b600060608284031215610ccf57610cce610cb4565b5b81905092915050565b600060208284031215610cee57610ced610a28565b5b600082013567ffffffffffffffff811115610d0c57610d0b610a2d565b5b610d1884828501610cb9565b91505092915050565b600060208284031215610d3757610d36610cb4565b5b81905092915050565b600080fd5b600080fd5b60008083601f840112610d6057610d5f610a32565b5b8235905067ffffffffffffffff811115610d7d57610d7c610d40565b5b602083019150836001820283011115610d9957610d98610d45565b5b9250929050565b600080600060408486031215610db957610db8610a28565b5b6000610dc786828701610d21565b935050602084013567ffffffffffffffff811115610de857610de7610a2d565b5b610df486828701610d4a565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b60005b83811015610e3a578082015181840152602081019050610e1f565b83811115610e49576000848401525b50505050565b6000610e5a82610e00565b610e648185610e0b565b9350610e74818560208601610e1c565b610e7d81610a3c565b840191505092915050565b60006020820190508181036000830152610ea28184610e4f565b905092915050565b610eb381610c78565b8114610ebe57600080fd5b50565b600081359050610ed081610eaa565b92915050565b600060208284031215610eec57610eeb610a28565b5b6000610efa84828501610ec1565b91505092915050565b6000610f0e82610c78565b9050919050565b610f1e81610f03565b8114610f2957600080fd5b50565b600081359050610f3b81610f15565b92915050565b610f4a81610c24565b8114610f5557600080fd5b50565b600081359050610f6781610f41565b92915050565b600080600060608486031215610f8657610f85610a28565b5b6000610f9486828701610f2c565b9350506020610fa586828701610f58565b925050604084013567ffffffffffffffff811115610fc657610fc5610a2d565b5b610fd286828701610b4a565b9150509250925092565b600060608284031215610ff257610ff1610cb4565b5b81905092915050565b60008060008060006080868803121561101757611016610a28565b5b600086013567ffffffffffffffff81111561103557611034610a2d565b5b61104188828901610fdc565b955050602061105288828901610ec1565b945050604061106388828901610f58565b935050606086013567ffffffffffffffff81111561108457611083610a2d565b5b61109088828901610d4a565b92509250509295509295909350565b60008115159050919050565b6110b48161109f565b82525050565b60006020820190506110cf60008301846110ab565b92915050565b600067ffffffffffffffff8211156110f0576110ef610a4d565b5b6110f982610a3c565b9050602081019050919050565b6000611119611114846110d5565b610aad565b90508281526020810184848401111561113557611134610a37565b5b611140848285610af9565b509392505050565b600082601f83011261115d5761115c610a32565b5b813561116d848260208601611106565b91505092915050565b60006020828403121561118c5761118b610a28565b5b600082013567ffffffffffffffff8111156111aa576111a9610a2d565b5b6111b684828501611148565b91505092915050565b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126111eb576111ea6111bf565b5b80840192508235915067ffffffffffffffff82111561120d5761120c6111c4565b5b602083019250600182023603831315611229576112286111c9565b5b509250929050565b600082825260208201905092915050565b7f756e61757468656e746963617465642073656e64657200000000000000000000600082015250565b6000611278601683611231565b915061128382611242565b602082019050919050565b600060208201905081810360008301526112a78161126b565b9050919050565b600081905092915050565b60006112c583856112ae565b93506112d2838584610af9565b82840190509392505050565b60006112eb8284866112b9565b91508190509392505050565b600081519050919050565b600081905092915050565b6000611318826112f7565b6113228185611302565b9350611332818560208601610e1c565b80840191505092915050565b600061134a828461130d565b915081905092915050565b600060608201905061136a6000830186610c8a565b6113776020830185610c8a565b6113846040830184610c2e565b949350505050565b6113958161109f565b81146113a057600080fd5b50565b6000815190506113b28161138c565b92915050565b6000602082840312156113ce576113cd610a28565b5b60006113dc848285016113a3565b91505092915050565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b600061141b600683611302565b9150611426826113e5565b600682019050919050565b600061143c8261140e565b915081905091905056fea264697066735822122046fb444f8c754142359339f5f1d728822414688169d0d22f23bd25c688c73fdf64736f6c634300080a0033" } diff --git a/pkg/contracts/testdappv2/TestDAppV2.sol b/pkg/contracts/testdappv2/TestDAppV2.sol index 4ab39a05a0..431ccf417d 100644 --- a/pkg/contracts/testdappv2/TestDAppV2.sol +++ b/pkg/contracts/testdappv2/TestDAppV2.sol @@ -22,8 +22,17 @@ contract TestDAppV2 { bytes revertMessage; } + /// @notice Message context passed to execute function. + /// @param sender Sender from omnichain contract. + struct MessageContext { + address sender; + } + + address public expectedOnCallSender; + // these structures allow to assess contract calls mapping(bytes32 => bool) public calledWithMessage; + mapping(bytes => address) public senderWithMessage; mapping(bytes32 => uint256) public amountWithMessage; function setCalledWithMessage(string memory message) internal { @@ -93,5 +102,16 @@ contract TestDAppV2 { setAmountWithMessage(string(revertContext.revertMessage), 0); } + function setExpectedOnCallSender(address _expectedOnCallSender) external { + expectedOnCallSender = _expectedOnCallSender; + } + + function onCall(MessageContext calldata messageContext, bytes calldata message) external payable returns (bytes memory) { + require(messageContext.sender == expectedOnCallSender, "unauthenticated sender"); + setCalledWithMessage(string(message)); + setAmountWithMessage(string(message), msg.value); + senderWithMessage[message] = messageContext.sender; + } + receive() external payable {} } \ No newline at end of file diff --git a/proto/zetachain/zetacore/crosschain/cross_chain_tx.proto b/proto/zetachain/zetacore/crosschain/cross_chain_tx.proto index f8da0d0daa..0ca1f56f7d 100644 --- a/proto/zetachain/zetacore/crosschain/cross_chain_tx.proto +++ b/proto/zetachain/zetacore/crosschain/cross_chain_tx.proto @@ -54,6 +54,11 @@ message ZetaAccounting { ]; } +message CallOptions { + uint64 gas_limit = 1; + bool is_arbitrary_call = 2; +} + message OutboundParams { string receiver = 1; int64 receiver_chainId = 2; @@ -63,6 +68,7 @@ message OutboundParams { (gogoproto.nullable) = false ]; uint64 tss_nonce = 5; + // Deprecated (v21), use CallOptions uint64 gas_limit = 6; string gas_price = 7; string gas_priority_fee = 23; @@ -80,6 +86,8 @@ message OutboundParams { string tss_pubkey = 11; TxFinalizationStatus tx_finalization_status = 12; + CallOptions call_options = 24; + // not used. do not edit. reserved 13 to 19; } diff --git a/proto/zetachain/zetacore/crosschain/tx.proto b/proto/zetachain/zetacore/crosschain/tx.proto index e5d310976d..59a449ddfc 100644 --- a/proto/zetachain/zetacore/crosschain/tx.proto +++ b/proto/zetachain/zetacore/crosschain/tx.proto @@ -163,6 +163,7 @@ message MsgVoteInbound { string message = 8; string inbound_hash = 9; uint64 inbound_block_height = 10; + // Deprecated (v21), use CallOptions uint64 gas_limit = 11; pkg.coin.CoinType coin_type = 12; string tx_origin = 13; @@ -175,6 +176,8 @@ message MsgVoteInbound { // revert options provided by the sender RevertOptions revert_options = 17 [ (gogoproto.nullable) = false ]; + + CallOptions call_options = 18; } message MsgVoteInboundResponse {} diff --git a/testutil/sample/crosschain.go b/testutil/sample/crosschain.go index defc1f217a..8f09271e23 100644 --- a/testutil/sample/crosschain.go +++ b/testutil/sample/crosschain.go @@ -148,12 +148,14 @@ func InboundParamsValidChainID(r *rand.Rand) *types.InboundParams { func OutboundParams(r *rand.Rand) *types.OutboundParams { return &types.OutboundParams{ - Receiver: EthAddress().String(), - ReceiverChainId: r.Int63(), - CoinType: coin.CoinType(r.Intn(100)), - Amount: math.NewUint(uint64(r.Int63())), - TssNonce: r.Uint64(), - GasLimit: r.Uint64(), + Receiver: EthAddress().String(), + ReceiverChainId: r.Int63(), + CoinType: coin.CoinType(r.Intn(100)), + Amount: math.NewUint(uint64(r.Int63())), + TssNonce: r.Uint64(), + CallOptions: &types.CallOptions{ + GasLimit: r.Uint64(), + }, GasPrice: math.NewUint(uint64(r.Int63())).String(), Hash: StringRandom(r, 32), BallotIndex: StringRandom(r, 32), @@ -165,11 +167,13 @@ func OutboundParams(r *rand.Rand) *types.OutboundParams { func OutboundParamsValidChainID(r *rand.Rand) *types.OutboundParams { return &types.OutboundParams{ - Receiver: EthAddress().String(), - ReceiverChainId: chains.Goerli.ChainId, - Amount: math.NewUint(uint64(r.Int63())), - TssNonce: r.Uint64(), - GasLimit: r.Uint64(), + Receiver: EthAddress().String(), + ReceiverChainId: chains.Goerli.ChainId, + Amount: math.NewUint(uint64(r.Int63())), + TssNonce: r.Uint64(), + CallOptions: &types.CallOptions{ + GasLimit: r.Uint64(), + }, GasPrice: math.NewUint(uint64(r.Int63())).String(), Hash: StringRandom(r, 32), BallotIndex: StringRandom(r, 32), @@ -279,12 +283,14 @@ func InboundVote(coinType coin.CoinType, from, to int64) types.MsgVoteInbound { Amount: UintInRange(10000000, 1000000000), Message: base64.StdEncoding.EncodeToString(Bytes()), InboundBlockHeight: Uint64InRange(1, 10000), - GasLimit: 1000000000, - InboundHash: Hash().String(), - CoinType: coinType, - TxOrigin: EthAddress().String(), - Asset: "", - EventIndex: EventIndex(), + CallOptions: &types.CallOptions{ + GasLimit: 1000000000, + }, + InboundHash: Hash().String(), + CoinType: coinType, + TxOrigin: EthAddress().String(), + Asset: "", + EventIndex: EventIndex(), } } diff --git a/typescript/zetachain/zetacore/crosschain/cross_chain_tx_pb.d.ts b/typescript/zetachain/zetacore/crosschain/cross_chain_tx_pb.d.ts index a0ab4b06ca..1ffa04eaca 100644 --- a/typescript/zetachain/zetacore/crosschain/cross_chain_tx_pb.d.ts +++ b/typescript/zetachain/zetacore/crosschain/cross_chain_tx_pb.d.ts @@ -207,6 +207,35 @@ export declare class ZetaAccounting extends Message { static equals(a: ZetaAccounting | PlainMessage | undefined, b: ZetaAccounting | PlainMessage | undefined): boolean; } +/** + * @generated from message zetachain.zetacore.crosschain.CallOptions + */ +export declare class CallOptions extends Message { + /** + * @generated from field: uint64 gas_limit = 1; + */ + gasLimit: bigint; + + /** + * @generated from field: bool is_arbitrary_call = 2; + */ + isArbitraryCall: boolean; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.crosschain.CallOptions"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): CallOptions; + + static fromJson(jsonValue: JsonValue, options?: Partial): CallOptions; + + static fromJsonString(jsonString: string, options?: Partial): CallOptions; + + static equals(a: CallOptions | PlainMessage | undefined, b: CallOptions | PlainMessage | undefined): boolean; +} + /** * @generated from message zetachain.zetacore.crosschain.OutboundParams */ @@ -237,6 +266,8 @@ export declare class OutboundParams extends Message { tssNonce: bigint; /** + * Deprecated (v21), use CallOptions + * * @generated from field: uint64 gas_limit = 6; */ gasLimit: bigint; @@ -294,6 +325,11 @@ export declare class OutboundParams extends Message { */ txFinalizationStatus: TxFinalizationStatus; + /** + * @generated from field: zetachain.zetacore.crosschain.CallOptions call_options = 24; + */ + callOptions?: CallOptions; + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; diff --git a/typescript/zetachain/zetacore/crosschain/tx_pb.d.ts b/typescript/zetachain/zetacore/crosschain/tx_pb.d.ts index 657a772384..751371fa03 100644 --- a/typescript/zetachain/zetacore/crosschain/tx_pb.d.ts +++ b/typescript/zetachain/zetacore/crosschain/tx_pb.d.ts @@ -8,7 +8,7 @@ import { Message, proto3 } from "@bufbuild/protobuf"; import type { CoinType } from "../pkg/coin/coin_pb.js"; import type { Proof } from "../pkg/proofs/proofs_pb.js"; import type { ReceiveStatus } from "../pkg/chains/chains_pb.js"; -import type { ProtocolContractVersion, RevertOptions } from "./cross_chain_tx_pb.js"; +import type { CallOptions, ProtocolContractVersion, RevertOptions } from "./cross_chain_tx_pb.js"; import type { RateLimiterFlags } from "./rate_limiter_flags_pb.js"; /** @@ -616,6 +616,8 @@ export declare class MsgVoteInbound extends Message { inboundBlockHeight: bigint; /** + * Deprecated (v21), use CallOptions + * * @generated from field: uint64 gas_limit = 11; */ gasLimit: bigint; @@ -656,6 +658,11 @@ export declare class MsgVoteInbound extends Message { */ revertOptions?: RevertOptions; + /** + * @generated from field: zetachain.zetacore.crosschain.CallOptions call_options = 18; + */ + callOptions?: CallOptions; + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; diff --git a/x/crosschain/client/cli/tx_vote_inbound.go b/x/crosschain/client/cli/tx_vote_inbound.go index 3c7fae37c0..e4b8b9ecc9 100644 --- a/x/crosschain/client/cli/tx_vote_inbound.go +++ b/x/crosschain/client/cli/tx_vote_inbound.go @@ -17,7 +17,7 @@ import ( func CmdVoteInbound() *cobra.Command { cmd := &cobra.Command{ Use: "vote-inbound [sender] [senderChainID] [txOrigin] [receiver] [receiverChainID] [amount] [message" + - "] [inboundHash] [inBlockHeight] [coinType] [asset] [eventIndex] [protocolContractVersion]", + "] [inboundHash] [inBlockHeight] [coinType] [asset] [eventIndex] [protocolContractVersion] [isArbitraryCall]", Short: "Broadcast message to vote an inbound", Args: cobra.ExactArgs(13), RunE: func(cmd *cobra.Command, args []string) error { @@ -67,6 +67,11 @@ func CmdVoteInbound() *cobra.Command { return err } + isArbitraryCall, err := strconv.ParseBool(args[13]) + if err != nil { + return err + } + msg := types.NewMsgVoteInbound( clientCtx.GetFromAddress().String(), argsSender, @@ -83,6 +88,7 @@ func CmdVoteInbound() *cobra.Command { argsAsset, uint(argsEventIndex), protocolContractVersion, + isArbitraryCall, ) return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) diff --git a/x/crosschain/keeper/abci.go b/x/crosschain/keeper/abci.go index c499f5fe05..03d13fb6d5 100644 --- a/x/crosschain/keeper/abci.go +++ b/x/crosschain/keeper/abci.go @@ -109,7 +109,7 @@ func CheckAndUpdateCctxGasPrice( flags observertypes.GasPriceIncreaseFlags, ) (math.Uint, math.Uint, error) { // skip if gas price or gas limit is not set - if cctx.GetCurrentOutboundParam().GasPrice == "" || cctx.GetCurrentOutboundParam().GasLimit == 0 { + if cctx.GetCurrentOutboundParam().GasPrice == "" || cctx.GetCurrentOutboundParam().CallOptions.GasLimit == 0 { return math.ZeroUint(), math.ZeroUint(), nil } @@ -159,7 +159,7 @@ func CheckAndUpdateCctxGasPrice( } // withdraw additional fees from the gas stability pool - gasLimit := math.NewUint(cctx.GetCurrentOutboundParam().GasLimit) + gasLimit := math.NewUint(cctx.GetCurrentOutboundParam().CallOptions.GasLimit) additionalFees := gasLimit.Mul(gasPriceIncrease) if err := k.fungibleKeeper.WithdrawFromGasStabilityPool(ctx, chainID, additionalFees.BigInt()); err != nil { return math.ZeroUint(), math.ZeroUint(), cosmoserrors.Wrap( diff --git a/x/crosschain/keeper/abci_test.go b/x/crosschain/keeper/abci_test.go index cee15a2777..32499e1827 100644 --- a/x/crosschain/keeper/abci_test.go +++ b/x/crosschain/keeper/abci_test.go @@ -134,8 +134,10 @@ func TestCheckAndUpdateCctxGasPrice(t *testing.T) { OutboundParams: []*types.OutboundParams{ { ReceiverChainId: 42, - GasLimit: 1000, - GasPrice: "100", + CallOptions: &types.CallOptions{ + GasLimit: 1000, + }, + GasPrice: "100", }, }, }, @@ -159,8 +161,10 @@ func TestCheckAndUpdateCctxGasPrice(t *testing.T) { OutboundParams: []*types.OutboundParams{ { ReceiverChainId: 42, - GasLimit: 1000, - GasPrice: "100", + CallOptions: &types.CallOptions{ + GasLimit: 1000, + }, + GasPrice: "100", }, }, }, @@ -188,8 +192,10 @@ func TestCheckAndUpdateCctxGasPrice(t *testing.T) { OutboundParams: []*types.OutboundParams{ { ReceiverChainId: 42, - GasLimit: 1000, - GasPrice: "100", + CallOptions: &types.CallOptions{ + GasLimit: 1000, + }, + GasPrice: "100", }, }, }, @@ -217,8 +223,10 @@ func TestCheckAndUpdateCctxGasPrice(t *testing.T) { OutboundParams: []*types.OutboundParams{ { ReceiverChainId: 42, - GasLimit: 1000, - GasPrice: "100", + CallOptions: &types.CallOptions{ + GasLimit: 1000, + }, + GasPrice: "100", }, }, }, @@ -245,8 +253,10 @@ func TestCheckAndUpdateCctxGasPrice(t *testing.T) { OutboundParams: []*types.OutboundParams{ { ReceiverChainId: 42, - GasLimit: 100, - GasPrice: "", + CallOptions: &types.CallOptions{ + GasLimit: 100, + }, + GasPrice: "", }, }, }, @@ -268,8 +278,10 @@ func TestCheckAndUpdateCctxGasPrice(t *testing.T) { OutboundParams: []*types.OutboundParams{ { ReceiverChainId: 42, - GasLimit: 0, - GasPrice: "100", + CallOptions: &types.CallOptions{ + GasLimit: 0, + }, + GasPrice: "100", }, }, }, @@ -291,8 +303,10 @@ func TestCheckAndUpdateCctxGasPrice(t *testing.T) { OutboundParams: []*types.OutboundParams{ { ReceiverChainId: 42, - GasLimit: 0, - GasPrice: "100", + CallOptions: &types.CallOptions{ + GasLimit: 0, + }, + GasPrice: "100", }, }, }, @@ -314,8 +328,10 @@ func TestCheckAndUpdateCctxGasPrice(t *testing.T) { OutboundParams: []*types.OutboundParams{ { ReceiverChainId: 42, - GasLimit: 1000, - GasPrice: "100", + CallOptions: &types.CallOptions{ + GasLimit: 1000, + }, + GasPrice: "100", }, }, }, @@ -336,8 +352,10 @@ func TestCheckAndUpdateCctxGasPrice(t *testing.T) { OutboundParams: []*types.OutboundParams{ { ReceiverChainId: 42, - GasLimit: 1000, - GasPrice: "100", + CallOptions: &types.CallOptions{ + GasLimit: 1000, + }, + GasPrice: "100", }, }, }, diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go index af1521c988..492ef14db0 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go @@ -78,11 +78,13 @@ func TestKeeper_ValidateInbound(t *testing.T) { Message: message, InboundHash: inboundHash.String(), InboundBlockHeight: inboundBlockHeight, - GasLimit: gasLimit, - CoinType: cointType, - TxOrigin: sender.String(), - Asset: asset, - EventIndex: eventIndex, + CallOptions: &types.CallOptions{ + GasLimit: gasLimit, + }, + CoinType: cointType, + TxOrigin: sender.String(), + Asset: asset, + EventIndex: eventIndex, } _, err := k.ValidateInbound(ctx, &msg, false) @@ -136,11 +138,13 @@ func TestKeeper_ValidateInbound(t *testing.T) { Message: message, InboundHash: inboundHash.String(), InboundBlockHeight: inboundBlockHeight, - GasLimit: gasLimit, - CoinType: cointType, - TxOrigin: sender.String(), - Asset: asset, - EventIndex: eventIndex, + CallOptions: &types.CallOptions{ + GasLimit: gasLimit, + }, + CoinType: cointType, + TxOrigin: sender.String(), + Asset: asset, + EventIndex: eventIndex, } _, err := k.ValidateInbound(ctx, &msg, false) @@ -203,11 +207,13 @@ func TestKeeper_ValidateInbound(t *testing.T) { Message: message, InboundHash: inboundHash.String(), InboundBlockHeight: inboundBlockHeight, - GasLimit: gasLimit, - CoinType: cointType, - TxOrigin: sender.String(), - Asset: asset, - EventIndex: eventIndex, + CallOptions: &types.CallOptions{ + GasLimit: gasLimit, + }, + CoinType: cointType, + TxOrigin: sender.String(), + Asset: asset, + EventIndex: eventIndex, } _, err := k.ValidateInbound(ctx, &msg, false) @@ -267,11 +273,13 @@ func TestKeeper_ValidateInbound(t *testing.T) { Message: message, InboundHash: inboundHash.String(), InboundBlockHeight: inboundBlockHeight, - GasLimit: gasLimit, - CoinType: cointType, - TxOrigin: sender.String(), - Asset: asset, - EventIndex: eventIndex, + CallOptions: &types.CallOptions{ + GasLimit: gasLimit, + }, + CoinType: cointType, + TxOrigin: sender.String(), + Asset: asset, + EventIndex: eventIndex, } _, err := k.ValidateInbound(ctx, &msg, false) @@ -329,11 +337,13 @@ func TestKeeper_ValidateInbound(t *testing.T) { Message: message, InboundHash: inboundHash.String(), InboundBlockHeight: inboundBlockHeight, - GasLimit: gasLimit, - CoinType: cointType, - TxOrigin: sender.String(), - Asset: asset, - EventIndex: eventIndex, + CallOptions: &types.CallOptions{ + GasLimit: gasLimit, + }, + CoinType: cointType, + TxOrigin: sender.String(), + Asset: asset, + EventIndex: eventIndex, } _, err := k.ValidateInbound(ctx, &msg, false) diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go index aec7eccb6e..d788e60fe0 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go @@ -171,7 +171,7 @@ func (k Keeper) processFailedOutboundOnExternalChain( } if gasLimit == 0 { // use same gas limit of outbound as a fallback -- should not happen - gasLimit = cctx.OutboundParams[0].GasLimit + gasLimit = cctx.OutboundParams[0].CallOptions.GasLimit } // create new OutboundParams for the revert diff --git a/x/crosschain/keeper/cctx_test.go b/x/crosschain/keeper/cctx_test.go index ef54e7151b..9b17f825d6 100644 --- a/x/crosschain/keeper/cctx_test.go +++ b/x/crosschain/keeper/cctx_test.go @@ -37,7 +37,7 @@ func createNCctxWithStatus( } items[i].ZetaFees = math.OneUint() items[i].InboundParams = &types.InboundParams{ObservedHash: fmt.Sprintf("%d", i), Amount: math.OneUint()} - items[i].OutboundParams = []*types.OutboundParams{{Amount: math.ZeroUint()}} + items[i].OutboundParams = []*types.OutboundParams{{Amount: math.ZeroUint(), CallOptions: &types.CallOptions{}}} items[i].RevertOptions = types.NewEmptyRevertOptions() keeper.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, items[i], tssPubkey) @@ -61,11 +61,13 @@ func createNCctx(keeper *keeper.Keeper, ctx sdk.Context, n int, tssPubkey string FinalizedZetaHeight: uint64(i), } items[i].OutboundParams = []*types.OutboundParams{{ - Receiver: fmt.Sprintf("%d", i), - ReceiverChainId: int64(i), - Hash: fmt.Sprintf("%d", i), - TssNonce: uint64(i), - GasLimit: uint64(i), + Receiver: fmt.Sprintf("%d", i), + ReceiverChainId: int64(i), + Hash: fmt.Sprintf("%d", i), + TssNonce: uint64(i), + CallOptions: &types.CallOptions{ + GasLimit: uint64(i), + }, GasPrice: fmt.Sprintf("%d", i), BallotIndex: fmt.Sprintf("%d", i), ObservedExternalHeight: uint64(i), diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index 5669c10fe7..c07cba213a 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -87,7 +87,7 @@ func (k Keeper) ProcessLogs( // run the processing for the v1 and the v2 protocol contracts for _, log := range logs { if !crypto.IsEmptyAddress(gatewayAddr) { - if err := k.ProcessZEVMInboundV2(ctx, log, gatewayAddr, emittingAddress, txOrigin); err != nil { + if err := k.ProcessZEVMInboundV2(ctx, log, gatewayAddr, txOrigin); err != nil { return errors.Wrap(err, "failed to process ZEVM inbound V2") } } @@ -206,6 +206,7 @@ func (k Keeper) ProcessZRC20WithdrawalEvent( foreignCoin.Asset, event.Raw.Index, types.ProtocolContractVersion_V1, + false, // not relevant for v1 ) cctx, err := k.ValidateInbound(ctx, msg, false) @@ -286,6 +287,7 @@ func (k Keeper) ProcessZetaSentEvent( "", event.Raw.Index, types.ProtocolContractVersion_V1, + false, // not relevant for v1 ) cctx, err := k.ValidateInbound(ctx, msg, true) diff --git a/x/crosschain/keeper/gas_payment.go b/x/crosschain/keeper/gas_payment.go index 63cbea0d4f..d0bd4921df 100644 --- a/x/crosschain/keeper/gas_payment.go +++ b/x/crosschain/keeper/gas_payment.go @@ -139,7 +139,7 @@ func (k Keeper) PayGasNativeAndUpdateCctx( // update cctx cctx.GetCurrentOutboundParam().Amount = newAmount - cctx.GetCurrentOutboundParam().GasLimit = gas.GasLimit.Uint64() + cctx.GetCurrentOutboundParam().CallOptions.GasLimit = gas.GasLimit.Uint64() cctx.GetCurrentOutboundParam().GasPrice = gas.GasPrice.String() cctx.GetCurrentOutboundParam().GasPriorityFee = gas.PriorityFee.String() @@ -296,7 +296,7 @@ func (k Keeper) PayGasInERC20AndUpdateCctx( // update cctx cctx.GetCurrentOutboundParam().Amount = newAmount - cctx.GetCurrentOutboundParam().GasLimit = gas.GasLimit.Uint64() + cctx.GetCurrentOutboundParam().CallOptions.GasLimit = gas.GasLimit.Uint64() cctx.GetCurrentOutboundParam().GasPrice = gas.GasPrice.String() cctx.GetCurrentOutboundParam().GasPriorityFee = gas.PriorityFee.String() @@ -362,7 +362,7 @@ func (k Keeper) PayGasInZetaAndUpdateCctx( } // get the gas fee in gas token - gasLimit := sdk.NewUint(cctx.GetCurrentOutboundParam().GasLimit) + gasLimit := sdk.NewUint(cctx.GetCurrentOutboundParam().CallOptions.GasLimit) outTxGasFee := gasLimit.Mul(gasPrice) // get the gas fee in Zeta using system uniswapv2 pool wzeta/gasZRC20 and adding the protocol fee diff --git a/x/crosschain/keeper/gas_payment_test.go b/x/crosschain/keeper/gas_payment_test.go index 3907268fd0..9f91ffc8d1 100644 --- a/x/crosschain/keeper/gas_payment_test.go +++ b/x/crosschain/keeper/gas_payment_test.go @@ -53,9 +53,11 @@ func TestKeeper_PayGasNativeAndUpdateCctx(t *testing.T) { { ReceiverChainId: chains.ZetaChainPrivnet.ChainId, CoinType: coin.CoinType_Gas, + CallOptions: &types.CallOptions{}, }, { ReceiverChainId: chainID, + CallOptions: &types.CallOptions{}, }, }, } @@ -65,7 +67,7 @@ func TestKeeper_PayGasNativeAndUpdateCctx(t *testing.T) { err = k.PayGasNativeAndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount)) require.NoError(t, err) require.Equal(t, uint64(9999999999957000), cctx.GetCurrentOutboundParam().Amount.Uint64()) - require.Equal(t, uint64(21_000), cctx.GetCurrentOutboundParam().GasLimit) + require.Equal(t, uint64(21_000), cctx.GetCurrentOutboundParam().CallOptions.GasLimit) require.Equal(t, "2", cctx.GetCurrentOutboundParam().GasPrice) }) @@ -229,7 +231,7 @@ func TestKeeper_PayGasInERC20AndUpdateCctx(t *testing.T) { err = k.PayGasInERC20AndUpdateCctx(ctx, chainID, &cctx, math.NewUint(inputAmount), false) require.NoError(t, err) require.Equal(t, inputAmount-expectedInZRC20.Uint64(), cctx.GetCurrentOutboundParam().Amount.Uint64()) - require.Equal(t, uint64(21_000), cctx.GetCurrentOutboundParam().GasLimit) + require.Equal(t, uint64(21_000), cctx.GetCurrentOutboundParam().CallOptions.GasLimit) require.Equal(t, "2", cctx.GetCurrentOutboundParam().GasPrice) }) @@ -476,7 +478,9 @@ func TestKeeper_PayGasInZetaAndUpdateCctx(t *testing.T) { OutboundParams: []*types.OutboundParams{ { ReceiverChainId: chainID, - GasLimit: 1000, + CallOptions: &types.CallOptions{ + GasLimit: 1000, + }, }, }, ZetaFees: math.NewUint(100), @@ -512,7 +516,9 @@ func TestKeeper_PayGasInZetaAndUpdateCctx(t *testing.T) { OutboundParams: []*types.OutboundParams{ { ReceiverChainId: chainID, - GasLimit: 1000, + CallOptions: &types.CallOptions{ + GasLimit: 1000, + }, }, }, } @@ -582,7 +588,9 @@ func TestKeeper_PayGasInZetaAndUpdateCctx(t *testing.T) { OutboundParams: []*types.OutboundParams{ { ReceiverChainId: chainID, - GasLimit: 1000, + CallOptions: &types.CallOptions{ + GasLimit: 1000, + }, }, }, } @@ -616,7 +624,9 @@ func TestKeeper_PayGasInZetaAndUpdateCctx(t *testing.T) { OutboundParams: []*types.OutboundParams{ { ReceiverChainId: chainID, - GasLimit: 1000, + CallOptions: &types.CallOptions{ + GasLimit: 1000, + }, }, }, ZetaFees: math.NewUint(100), diff --git a/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go b/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go index c88f05ab29..5ac59b0995 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go @@ -391,7 +391,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { index := hash.Hex() cctx, found := k.GetCrossChainTx(ctx, index) require.True(t, found) - feeCalculated := sdk.NewUint(cctx.GetCurrentOutboundParam().GasLimit). + feeCalculated := sdk.NewUint(cctx.GetCurrentOutboundParam().CallOptions.GasLimit). Mul(sdkmath.NewUintFromString(cctx.GetCurrentOutboundParam().GasPrice)). Add(sdkmath.NewUintFromString(crosschaintypes.TSSMigrationBufferAmountEVM)) require.Equal(t, cctx.GetCurrentOutboundParam().Amount.String(), amount.Sub(feeCalculated).String()) diff --git a/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go b/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go index 97263add19..e824a01707 100644 --- a/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go +++ b/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go @@ -126,12 +126,14 @@ func TestKeeper_VoteInbound(t *testing.T) { Amount: sdkmath.NewUintFromString("10000000"), Message: "", InboundBlockHeight: 1, - GasLimit: 1000000000, - InboundHash: "0x7a900ef978743f91f57ca47c6d1a1add75df4d3531da17671e9cf149e1aefe0b", - CoinType: 0, // zeta - TxOrigin: "0x954598965C2aCdA2885B037561526260764095B8", - Asset: "", - EventIndex: 1, + CallOptions: &types.CallOptions{ + GasLimit: 1000000000, + }, + InboundHash: "0x7a900ef978743f91f57ca47c6d1a1add75df4d3531da17671e9cf149e1aefe0b", + CoinType: 0, // zeta + TxOrigin: "0x954598965C2aCdA2885B037561526260764095B8", + Asset: "", + EventIndex: 1, } _, err := msgServer.VoteInbound( ctx, @@ -153,12 +155,14 @@ func TestKeeper_VoteInbound(t *testing.T) { Amount: sdkmath.NewUintFromString("10000000"), Message: "", InboundBlockHeight: 1, - GasLimit: 1000000001, // <---- Change here - InboundHash: "0x7a900ef978743f91f57ca47c6d1a1add75df4d3531da17671e9cf149e1aefe0b", - CoinType: 0, - TxOrigin: "0x954598965C2aCdA2885B037561526260764095B8", - Asset: "", - EventIndex: 1, + CallOptions: &types.CallOptions{ + GasLimit: 1000000001, // <---- Change here + }, + InboundHash: "0x7a900ef978743f91f57ca47c6d1a1add75df4d3531da17671e9cf149e1aefe0b", + CoinType: 0, + TxOrigin: "0x954598965C2aCdA2885B037561526260764095B8", + Asset: "", + EventIndex: 1, } _, err = msgServer.VoteInbound( diff --git a/x/crosschain/keeper/v2_zevm_inbound.go b/x/crosschain/keeper/v2_zevm_inbound.go index 040bdec883..9efc5e1e2e 100644 --- a/x/crosschain/keeper/v2_zevm_inbound.go +++ b/x/crosschain/keeper/v2_zevm_inbound.go @@ -26,8 +26,7 @@ import ( func (k Keeper) ProcessZEVMInboundV2( ctx sdk.Context, log *ethtypes.Log, - gatewayAddr, - from ethcommon.Address, + gatewayAddr ethcommon.Address, txOrigin string, ) error { // try to parse a withdrawal event from the log @@ -68,12 +67,12 @@ func (k Keeper) ProcessZEVMInboundV2( // create inbound object depending on the event type if withdrawalEvent != nil { - inbound, err = k.newWithdrawalInbound(ctx, from, txOrigin, foreignCoin, withdrawalEvent) + inbound, err = k.newWithdrawalInbound(ctx, txOrigin, foreignCoin, withdrawalEvent) if err != nil { return err } } else { - inbound, err = k.newCallInbound(ctx, from, txOrigin, foreignCoin, gatewayEvent) + inbound, err = k.newCallInbound(ctx, txOrigin, foreignCoin, gatewayEvent) if err != nil { return err } @@ -159,7 +158,6 @@ func (k Keeper) parseGatewayCallEvent( // https://github.com/zeta-chain/node/issues/2658 func (k Keeper) newWithdrawalInbound( ctx sdk.Context, - from ethcommon.Address, txOrigin string, foreignCoin fungibletypes.ForeignCoins, event *gatewayzevm.GatewayZEVMWithdrawn, @@ -183,7 +181,7 @@ func (k Keeper) newWithdrawalInbound( return nil, errors.Wrapf(err, "cannot encode address %v", event.Receiver) } - gasLimit := event.GasLimit.Uint64() + gasLimit := event.CallOptions.GasLimit.Uint64() if gasLimit == 0 { gasLimitQueried, err := k.fungibleKeeper.QueryGasLimit( ctx, @@ -197,7 +195,7 @@ func (k Keeper) newWithdrawalInbound( return types.NewMsgVoteInbound( "", - from.Hex(), + event.Sender.Hex(), senderChain.ChainId, txOrigin, toAddr, @@ -211,6 +209,7 @@ func (k Keeper) newWithdrawalInbound( foreignCoin.Asset, event.Raw.Index, types.ProtocolContractVersion_V2, + event.CallOptions.IsArbitraryCall, types.WithZEVMRevertOptions(event.RevertOptions), ), nil } @@ -221,7 +220,6 @@ func (k Keeper) newWithdrawalInbound( // https://github.com/zeta-chain/node/issues/2658 func (k Keeper) newCallInbound( ctx sdk.Context, - from ethcommon.Address, txOrigin string, foreignCoin fungibletypes.ForeignCoins, event *gatewayzevm.GatewayZEVMCalled, @@ -245,7 +243,7 @@ func (k Keeper) newCallInbound( return nil, errors.Wrapf(err, "cannot encode address %v", event.Receiver) } - gasLimit := event.GasLimit.Uint64() + gasLimit := event.CallOptions.GasLimit.Uint64() if gasLimit == 0 { gasLimitQueried, err := k.fungibleKeeper.QueryGasLimit( ctx, @@ -259,7 +257,7 @@ func (k Keeper) newCallInbound( return types.NewMsgVoteInbound( "", - from.Hex(), + event.Sender.Hex(), senderChain.ChainId, txOrigin, toAddr, @@ -273,6 +271,7 @@ func (k Keeper) newCallInbound( "", event.Raw.Index, types.ProtocolContractVersion_V2, + event.CallOptions.IsArbitraryCall, types.WithZEVMRevertOptions(event.RevertOptions), ), nil } diff --git a/x/crosschain/types/cctx.go b/x/crosschain/types/cctx.go index 90b398210d..0a235dffae 100644 --- a/x/crosschain/types/cctx.go +++ b/x/crosschain/types/cctx.go @@ -40,10 +40,19 @@ func (m CrossChainTx) GetEVMAbortAddress() ethcommon.Address { // OutboundParams[0] is the original outbound, if it reverts, then // OutboundParams[1] is the new outbound. func (m CrossChainTx) GetCurrentOutboundParam() *OutboundParams { + // TODO: Deprecated (V21) gasLimit should be removed and CallOptions should be mandatory + // this should never happen, but since it is optional, adding it just in case if len(m.OutboundParams) == 0 { - return &OutboundParams{} + return &OutboundParams{CallOptions: &CallOptions{}} } - return m.OutboundParams[len(m.OutboundParams)-1] + + outboundParams := m.OutboundParams[len(m.OutboundParams)-1] + if outboundParams.CallOptions == nil { + outboundParams.CallOptions = &CallOptions{ + GasLimit: outboundParams.GasLimit, + } + } + return outboundParams } // IsCurrentOutboundRevert returns true if the current outbound is the revert tx. @@ -120,8 +129,10 @@ func (m *CrossChainTx) AddRevertOutbound(gasLimit uint64) error { Receiver: revertReceiver, ReceiverChainId: m.InboundParams.SenderChainId, Amount: m.GetCurrentOutboundParam().Amount, - GasLimit: gasLimit, - TssPubkey: m.GetCurrentOutboundParam().TssPubkey, + CallOptions: &CallOptions{ + GasLimit: gasLimit, + }, + TssPubkey: m.GetCurrentOutboundParam().TssPubkey, } // The original outbound has been finalized, the new outbound is pending m.GetCurrentOutboundParam().TxFinalizationStatus = TxFinalizationStatus_Executed @@ -229,11 +240,14 @@ func NewCCTX(ctx sdk.Context, msg MsgVoteInbound, tssPubkey string) (CrossChainT } outboundParams := &OutboundParams{ - Receiver: msg.Receiver, - ReceiverChainId: msg.ReceiverChain, - Hash: "", - TssNonce: 0, - GasLimit: msg.GasLimit, + Receiver: msg.Receiver, + ReceiverChainId: msg.ReceiverChain, + Hash: "", + TssNonce: 0, + CallOptions: &CallOptions{ + IsArbitraryCall: msg.CallOptions.IsArbitraryCall, + GasLimit: msg.CallOptions.GasLimit, + }, GasPrice: "", GasPriorityFee: "", BallotIndex: "", diff --git a/x/crosschain/types/cctx_test.go b/x/crosschain/types/cctx_test.go index 6317161196..0f2f84ac7b 100644 --- a/x/crosschain/types/cctx_test.go +++ b/x/crosschain/types/cctx_test.go @@ -81,16 +81,18 @@ func Test_NewCCTX(t *testing.T) { cointType := coin.CoinType_ERC20 tss := sample.Tss() msg := types.MsgVoteInbound{ - Creator: creator, - Sender: sender.String(), - SenderChainId: senderChain.ChainId, - Receiver: receiver.String(), - ReceiverChain: receiverChain.ChainId, - Amount: amount, - Message: message, - InboundHash: inboundHash.String(), - InboundBlockHeight: inboundBlockHeight, - GasLimit: gasLimit, + Creator: creator, + Sender: sender.String(), + SenderChainId: senderChain.ChainId, + Receiver: receiver.String(), + ReceiverChain: receiverChain.ChainId, + Amount: amount, + Message: message, + InboundHash: inboundHash.String(), + InboundBlockHeight: inboundBlockHeight, + CallOptions: &types.CallOptions{ + GasLimit: gasLimit, + }, CoinType: cointType, TxOrigin: sender.String(), Asset: asset, @@ -107,7 +109,7 @@ func Test_NewCCTX(t *testing.T) { require.Equal(t, message, cctx.RelayedMessage) require.Equal(t, inboundHash.String(), cctx.GetInboundParams().ObservedHash) require.Equal(t, inboundBlockHeight, cctx.GetInboundParams().ObservedExternalHeight) - require.Equal(t, gasLimit, cctx.GetCurrentOutboundParam().GasLimit) + require.Equal(t, gasLimit, cctx.GetCurrentOutboundParam().CallOptions.GasLimit) require.Equal(t, asset, cctx.GetInboundParams().Asset) require.Equal(t, cointType, cctx.InboundParams.CoinType) require.Equal(t, uint64(0), cctx.GetCurrentOutboundParam().TssNonce) @@ -143,11 +145,13 @@ func Test_NewCCTX(t *testing.T) { Message: message, InboundHash: inboundHash.String(), InboundBlockHeight: inboundBlockHeight, - GasLimit: gasLimit, - CoinType: cointType, - TxOrigin: sender.String(), - Asset: asset, - EventIndex: eventIndex, + CallOptions: &types.CallOptions{ + GasLimit: gasLimit, + }, + CoinType: cointType, + TxOrigin: sender.String(), + Asset: asset, + EventIndex: eventIndex, } _, err := types.NewCCTX(ctx, msg, tss.TssPubkey) require.ErrorContains(t, err, "sender cannot be empty") @@ -184,7 +188,7 @@ func TestCrossChainTx_GetCurrentOutboundParam(t *testing.T) { cctx := sample.CrossChainTx(t, "foo") cctx.OutboundParams = []*types.OutboundParams{} - require.Equal(t, &types.OutboundParams{}, cctx.GetCurrentOutboundParam()) + require.Equal(t, &types.OutboundParams{CallOptions: &types.CallOptions{}}, cctx.GetCurrentOutboundParam()) cctx.OutboundParams = []*types.OutboundParams{sample.OutboundParams(r)} require.Equal(t, cctx.OutboundParams[0], cctx.GetCurrentOutboundParam()) @@ -291,7 +295,7 @@ func Test_SetRevertOutboundValues(t *testing.T) { require.Equal(t, cctx.GetCurrentOutboundParam().Receiver, cctx.InboundParams.Sender) require.Equal(t, cctx.GetCurrentOutboundParam().ReceiverChainId, cctx.InboundParams.SenderChainId) require.Equal(t, cctx.GetCurrentOutboundParam().Amount, cctx.OutboundParams[0].Amount) - require.Equal(t, cctx.GetCurrentOutboundParam().GasLimit, uint64(100)) + require.Equal(t, cctx.GetCurrentOutboundParam().CallOptions.GasLimit, uint64(100)) require.Equal(t, cctx.GetCurrentOutboundParam().TssPubkey, cctx.OutboundParams[0].TssPubkey) require.Equal(t, types.TxFinalizationStatus_Executed, cctx.OutboundParams[0].TxFinalizationStatus) }) diff --git a/x/crosschain/types/cmd_cctxs.go b/x/crosschain/types/cmd_cctxs.go index 71ecaaf384..c2f01a9f1e 100644 --- a/x/crosschain/types/cmd_cctxs.go +++ b/x/crosschain/types/cmd_cctxs.go @@ -298,10 +298,12 @@ func newCmdCCTX( ReceiverChainId: chainID, CoinType: coin.CoinType_Cmd, Amount: amount, - GasLimit: gasLimit, - GasPrice: medianGasPrice, - GasPriorityFee: priorityFee, - TssPubkey: tssPubKey, + CallOptions: &CallOptions{ + GasLimit: gasLimit, + }, + GasPrice: medianGasPrice, + GasPriorityFee: priorityFee, + TssPubkey: tssPubKey, }, }, } diff --git a/x/crosschain/types/cmd_cctxs_test.go b/x/crosschain/types/cmd_cctxs_test.go index 1712989000..e7d02b9786 100644 --- a/x/crosschain/types/cmd_cctxs_test.go +++ b/x/crosschain/types/cmd_cctxs_test.go @@ -1,8 +1,10 @@ package types_test import ( - sdkmath "cosmossdk.io/math" "fmt" + "testing" + + sdkmath "cosmossdk.io/math" "github.com/stretchr/testify/require" "github.com/zeta-chain/node/pkg/chains" "github.com/zeta-chain/node/pkg/coin" @@ -10,7 +12,6 @@ import ( "github.com/zeta-chain/node/pkg/gas" "github.com/zeta-chain/node/testutil/sample" "github.com/zeta-chain/node/x/crosschain/types" - "testing" ) func TestMigrateERC20CustodyFundsCmdCCTX(t *testing.T) { @@ -93,7 +94,7 @@ func TestMigrateERC20CustodyFundsCmdCCTX(t *testing.T) { require.EqualValues(t, chainID, cctx.OutboundParams[0].ReceiverChainId) require.EqualValues(t, coin.CoinType_Cmd, cctx.OutboundParams[0].CoinType) require.EqualValues(t, sdkmath.NewUint(0), cctx.OutboundParams[0].Amount) - require.EqualValues(t, 100_000, cctx.OutboundParams[0].GasLimit) + require.EqualValues(t, 100_000, cctx.OutboundParams[0].CallOptions.GasLimit) require.EqualValues(t, gasPrice, cctx.OutboundParams[0].GasPrice) require.EqualValues(t, priorityFee, cctx.OutboundParams[0].GasPriorityFee) require.EqualValues(t, tssPubKey, cctx.OutboundParams[0].TssPubkey) @@ -222,7 +223,7 @@ func TestUpdateERC20CustodyPauseStatusCmdCCTX(t *testing.T) { require.EqualValues(t, chainID, cctx.OutboundParams[0].ReceiverChainId) require.EqualValues(t, coin.CoinType_Cmd, cctx.OutboundParams[0].CoinType) require.EqualValues(t, sdkmath.NewUint(0), cctx.OutboundParams[0].Amount) - require.EqualValues(t, 100_000, cctx.OutboundParams[0].GasLimit) + require.EqualValues(t, 100_000, cctx.OutboundParams[0].CallOptions.GasLimit) require.EqualValues(t, gasPrice, cctx.OutboundParams[0].GasPrice) require.EqualValues(t, priorityFee, cctx.OutboundParams[0].GasPriorityFee) require.EqualValues(t, tssPubKey, cctx.OutboundParams[0].TssPubkey) @@ -317,7 +318,7 @@ func TestWhitelistERC20CmdCCTX(t *testing.T) { require.EqualValues(t, chainID, cctx.OutboundParams[0].ReceiverChainId) require.EqualValues(t, coin.CoinType_Cmd, cctx.OutboundParams[0].CoinType) require.EqualValues(t, sdkmath.NewUint(0), cctx.OutboundParams[0].Amount) - require.EqualValues(t, 100_000, cctx.OutboundParams[0].GasLimit) + require.EqualValues(t, 100_000, cctx.OutboundParams[0].CallOptions.GasLimit) require.EqualValues(t, gasPrice, cctx.OutboundParams[0].GasPrice) require.EqualValues(t, priorityFee, cctx.OutboundParams[0].GasPriorityFee) require.EqualValues(t, tssPubKey, cctx.OutboundParams[0].TssPubkey) @@ -371,7 +372,7 @@ func TestMigrateFundCmdCCTX(t *testing.T) { require.EqualValues(t, chains.Ethereum.ChainId, cctx.OutboundParams[0].ReceiverChainId) require.EqualValues(t, coin.CoinType_Cmd, cctx.OutboundParams[0].CoinType) require.False(t, cctx.OutboundParams[0].Amount.IsZero()) - require.EqualValues(t, gas.EVMSend, cctx.OutboundParams[0].GasLimit) + require.EqualValues(t, gas.EVMSend, cctx.OutboundParams[0].CallOptions.GasLimit) require.NotEmpty(t, cctx.OutboundParams[0].GasPrice) require.NotEmpty(t, cctx.OutboundParams[0].GasPriorityFee) }) @@ -419,7 +420,7 @@ func TestMigrateFundCmdCCTX(t *testing.T) { require.EqualValues(t, chains.BitcoinMainnet.ChainId, cctx.OutboundParams[0].ReceiverChainId) require.EqualValues(t, coin.CoinType_Cmd, cctx.OutboundParams[0].CoinType) require.False(t, cctx.OutboundParams[0].Amount.IsZero()) - require.EqualValues(t, uint64(1_000_000), cctx.OutboundParams[0].GasLimit) + require.EqualValues(t, uint64(1_000_000), cctx.OutboundParams[0].CallOptions.GasLimit) require.NotEmpty(t, cctx.OutboundParams[0].GasPrice) require.NotEmpty(t, cctx.OutboundParams[0].GasPriorityFee) }) diff --git a/x/crosschain/types/cross_chain_tx.pb.go b/x/crosschain/types/cross_chain_tx.pb.go index a0fbdab126..842ba310ba 100644 --- a/x/crosschain/types/cross_chain_tx.pb.go +++ b/x/crosschain/types/cross_chain_tx.pb.go @@ -274,15 +274,68 @@ func (m *ZetaAccounting) XXX_DiscardUnknown() { var xxx_messageInfo_ZetaAccounting proto.InternalMessageInfo +type CallOptions struct { + GasLimit uint64 `protobuf:"varint,1,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty"` + IsArbitraryCall bool `protobuf:"varint,2,opt,name=is_arbitrary_call,json=isArbitraryCall,proto3" json:"is_arbitrary_call,omitempty"` +} + +func (m *CallOptions) Reset() { *m = CallOptions{} } +func (m *CallOptions) String() string { return proto.CompactTextString(m) } +func (*CallOptions) ProtoMessage() {} +func (*CallOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_d4c1966807fb5cb2, []int{2} +} +func (m *CallOptions) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CallOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CallOptions.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *CallOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_CallOptions.Merge(m, src) +} +func (m *CallOptions) XXX_Size() int { + return m.Size() +} +func (m *CallOptions) XXX_DiscardUnknown() { + xxx_messageInfo_CallOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_CallOptions proto.InternalMessageInfo + +func (m *CallOptions) GetGasLimit() uint64 { + if m != nil { + return m.GasLimit + } + return 0 +} + +func (m *CallOptions) GetIsArbitraryCall() bool { + if m != nil { + return m.IsArbitraryCall + } + return false +} + type OutboundParams struct { Receiver string `protobuf:"bytes,1,opt,name=receiver,proto3" json:"receiver,omitempty"` ReceiverChainId int64 `protobuf:"varint,2,opt,name=receiver_chainId,json=receiverChainId,proto3" json:"receiver_chainId,omitempty"` CoinType coin.CoinType `protobuf:"varint,3,opt,name=coin_type,json=coinType,proto3,enum=zetachain.zetacore.pkg.coin.CoinType" json:"coin_type,omitempty"` Amount github_com_cosmos_cosmos_sdk_types.Uint `protobuf:"bytes,4,opt,name=amount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Uint" json:"amount"` TssNonce uint64 `protobuf:"varint,5,opt,name=tss_nonce,json=tssNonce,proto3" json:"tss_nonce,omitempty"` - GasLimit uint64 `protobuf:"varint,6,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty"` - GasPrice string `protobuf:"bytes,7,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"` - GasPriorityFee string `protobuf:"bytes,23,opt,name=gas_priority_fee,json=gasPriorityFee,proto3" json:"gas_priority_fee,omitempty"` + // Deprecated (v21), use CallOptions + GasLimit uint64 `protobuf:"varint,6,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty"` + GasPrice string `protobuf:"bytes,7,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"` + GasPriorityFee string `protobuf:"bytes,23,opt,name=gas_priority_fee,json=gasPriorityFee,proto3" json:"gas_priority_fee,omitempty"` // the above are commands for zetaclients // the following fields are used when the outbound tx is mined Hash string `protobuf:"bytes,8,opt,name=hash,proto3" json:"hash,omitempty"` @@ -293,13 +346,14 @@ type OutboundParams struct { EffectiveGasLimit uint64 `protobuf:"varint,22,opt,name=effective_gas_limit,json=effectiveGasLimit,proto3" json:"effective_gas_limit,omitempty"` TssPubkey string `protobuf:"bytes,11,opt,name=tss_pubkey,json=tssPubkey,proto3" json:"tss_pubkey,omitempty"` TxFinalizationStatus TxFinalizationStatus `protobuf:"varint,12,opt,name=tx_finalization_status,json=txFinalizationStatus,proto3,enum=zetachain.zetacore.crosschain.TxFinalizationStatus" json:"tx_finalization_status,omitempty"` + CallOptions *CallOptions `protobuf:"bytes,24,opt,name=call_options,json=callOptions,proto3" json:"call_options,omitempty"` } func (m *OutboundParams) Reset() { *m = OutboundParams{} } func (m *OutboundParams) String() string { return proto.CompactTextString(m) } func (*OutboundParams) ProtoMessage() {} func (*OutboundParams) Descriptor() ([]byte, []int) { - return fileDescriptor_d4c1966807fb5cb2, []int{2} + return fileDescriptor_d4c1966807fb5cb2, []int{3} } func (m *OutboundParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -426,6 +480,13 @@ func (m *OutboundParams) GetTxFinalizationStatus() TxFinalizationStatus { return TxFinalizationStatus_NotFinalized } +func (m *OutboundParams) GetCallOptions() *CallOptions { + if m != nil { + return m.CallOptions + } + return nil +} + type Status struct { Status CctxStatus `protobuf:"varint,1,opt,name=status,proto3,enum=zetachain.zetacore.crosschain.CctxStatus" json:"status,omitempty"` StatusMessage string `protobuf:"bytes,2,opt,name=status_message,json=statusMessage,proto3" json:"status_message,omitempty"` @@ -439,7 +500,7 @@ func (m *Status) Reset() { *m = Status{} } func (m *Status) String() string { return proto.CompactTextString(m) } func (*Status) ProtoMessage() {} func (*Status) Descriptor() ([]byte, []int) { - return fileDescriptor_d4c1966807fb5cb2, []int{3} + return fileDescriptor_d4c1966807fb5cb2, []int{4} } func (m *Status) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -516,7 +577,7 @@ func (m *RevertOptions) Reset() { *m = RevertOptions{} } func (m *RevertOptions) String() string { return proto.CompactTextString(m) } func (*RevertOptions) ProtoMessage() {} func (*RevertOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_d4c1966807fb5cb2, []int{4} + return fileDescriptor_d4c1966807fb5cb2, []int{5} } func (m *RevertOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -589,7 +650,7 @@ func (m *CrossChainTx) Reset() { *m = CrossChainTx{} } func (m *CrossChainTx) String() string { return proto.CompactTextString(m) } func (*CrossChainTx) ProtoMessage() {} func (*CrossChainTx) Descriptor() ([]byte, []int) { - return fileDescriptor_d4c1966807fb5cb2, []int{5} + return fileDescriptor_d4c1966807fb5cb2, []int{6} } func (m *CrossChainTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -680,6 +741,7 @@ func init() { proto.RegisterEnum("zetachain.zetacore.crosschain.ProtocolContractVersion", ProtocolContractVersion_name, ProtocolContractVersion_value) proto.RegisterType((*InboundParams)(nil), "zetachain.zetacore.crosschain.InboundParams") proto.RegisterType((*ZetaAccounting)(nil), "zetachain.zetacore.crosschain.ZetaAccounting") + proto.RegisterType((*CallOptions)(nil), "zetachain.zetacore.crosschain.CallOptions") proto.RegisterType((*OutboundParams)(nil), "zetachain.zetacore.crosschain.OutboundParams") proto.RegisterType((*Status)(nil), "zetachain.zetacore.crosschain.Status") proto.RegisterType((*RevertOptions)(nil), "zetachain.zetacore.crosschain.RevertOptions") @@ -691,88 +753,92 @@ func init() { } var fileDescriptor_d4c1966807fb5cb2 = []byte{ - // 1291 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcf, 0x6f, 0x13, 0xc7, - 0x17, 0xcf, 0x26, 0x8e, 0x63, 0x3f, 0xff, 0xc8, 0x32, 0x31, 0x61, 0xc9, 0x57, 0x98, 0x7c, 0xdd, - 0x02, 0x86, 0x36, 0xb6, 0x08, 0x52, 0x55, 0xf5, 0x96, 0x44, 0x04, 0xd2, 0x16, 0x12, 0x2d, 0x01, - 0x09, 0x0e, 0xdd, 0x8e, 0x77, 0x5f, 0xd6, 0xa3, 0xd8, 0x3b, 0xee, 0xce, 0x38, 0x72, 0x50, 0x6f, - 0x3d, 0x57, 0x6a, 0xff, 0x87, 0x1e, 0x7a, 0xec, 0x9f, 0xc1, 0x91, 0x63, 0xd5, 0x03, 0xaa, 0xe0, - 0x3f, 0xe8, 0xb9, 0x87, 0x6a, 0x7e, 0xac, 0x1d, 0xa3, 0x34, 0xa1, 0xb4, 0xa7, 0x9d, 0xf9, 0xbc, - 0x79, 0x9f, 0x37, 0xfb, 0xe6, 0xf3, 0xde, 0x0c, 0xac, 0x3f, 0x47, 0x49, 0xc3, 0x2e, 0x65, 0x49, - 0x5b, 0x8f, 0x78, 0x8a, 0xed, 0x30, 0xe5, 0x42, 0x18, 0x4c, 0x0f, 0x03, 0x3d, 0x0e, 0xe4, 0xa8, - 0x35, 0x48, 0xb9, 0xe4, 0xe4, 0xca, 0xd8, 0xa7, 0x95, 0xf9, 0xb4, 0x26, 0x3e, 0x2b, 0xb5, 0x98, - 0xc7, 0x5c, 0xaf, 0x6c, 0xab, 0x91, 0x71, 0x5a, 0xb9, 0x7e, 0x4a, 0xa0, 0xc1, 0x61, 0xdc, 0x0e, - 0xb9, 0x0a, 0xc3, 0x59, 0x62, 0xd6, 0x35, 0x7e, 0xc9, 0x41, 0x65, 0x27, 0xe9, 0xf0, 0x61, 0x12, - 0xed, 0xd1, 0x94, 0xf6, 0x05, 0x59, 0x86, 0xbc, 0xc0, 0x24, 0xc2, 0xd4, 0x73, 0x56, 0x9d, 0x66, - 0xd1, 0xb7, 0x33, 0x72, 0x1d, 0x16, 0xcd, 0xc8, 0xee, 0x8f, 0x45, 0xde, 0xec, 0xaa, 0xd3, 0x9c, - 0xf3, 0x2b, 0x06, 0xde, 0x52, 0xe8, 0x4e, 0x44, 0xfe, 0x07, 0x45, 0x39, 0x0a, 0x78, 0xca, 0x62, - 0x96, 0x78, 0x73, 0x9a, 0xa2, 0x20, 0x47, 0xbb, 0x7a, 0x4e, 0x36, 0xa1, 0xa8, 0x82, 0x07, 0xf2, - 0x78, 0x80, 0x5e, 0x6e, 0xd5, 0x69, 0x56, 0xd7, 0xaf, 0xb5, 0x4e, 0xf9, 0xbf, 0xc1, 0x61, 0xdc, - 0xd2, 0xbb, 0xdc, 0xe2, 0x2c, 0xd9, 0x3f, 0x1e, 0xa0, 0x5f, 0x08, 0xed, 0x88, 0xd4, 0x60, 0x9e, - 0x0a, 0x81, 0xd2, 0x9b, 0xd7, 0xe4, 0x66, 0x42, 0xee, 0x41, 0x9e, 0xf6, 0xf9, 0x30, 0x91, 0x5e, - 0x5e, 0xc1, 0x9b, 0xed, 0x17, 0xaf, 0xae, 0xce, 0xfc, 0xf6, 0xea, 0xea, 0x8d, 0x98, 0xc9, 0xee, - 0xb0, 0xd3, 0x0a, 0x79, 0xbf, 0x1d, 0x72, 0xd1, 0xe7, 0xc2, 0x7e, 0xd6, 0x44, 0x74, 0xd8, 0x56, - 0xfb, 0x10, 0xad, 0xc7, 0x2c, 0x91, 0xbe, 0x75, 0x27, 0x1f, 0x40, 0x85, 0x77, 0x04, 0xa6, 0x47, - 0x18, 0x05, 0x5d, 0x2a, 0xba, 0xde, 0x82, 0x0e, 0x53, 0xce, 0xc0, 0xfb, 0x54, 0x74, 0xc9, 0xa7, - 0xe0, 0x8d, 0x17, 0xe1, 0x48, 0x62, 0x9a, 0xd0, 0x5e, 0xd0, 0x45, 0x16, 0x77, 0xa5, 0x57, 0x58, - 0x75, 0x9a, 0x39, 0x7f, 0x39, 0xb3, 0xdf, 0xb5, 0xe6, 0xfb, 0xda, 0x4a, 0xfe, 0x0f, 0xe5, 0x0e, - 0xed, 0xf5, 0xb8, 0x0c, 0x58, 0x12, 0xe1, 0xc8, 0x2b, 0x6a, 0xf6, 0x92, 0xc1, 0x76, 0x14, 0x44, - 0xd6, 0xe1, 0xe2, 0x01, 0x4b, 0x68, 0x8f, 0x3d, 0xc7, 0x28, 0x50, 0x29, 0xc9, 0x98, 0x41, 0x33, - 0x2f, 0x8d, 0x8d, 0xcf, 0x50, 0x52, 0x4b, 0xcb, 0x60, 0x59, 0x8e, 0x02, 0x6b, 0xa1, 0x92, 0xf1, - 0x24, 0x10, 0x92, 0xca, 0xa1, 0xf0, 0x4a, 0x3a, 0xcb, 0x77, 0x5a, 0x67, 0xaa, 0xa8, 0xb5, 0x3f, - 0xda, 0x3e, 0xe1, 0xfb, 0x48, 0xbb, 0xfa, 0x35, 0x79, 0x0a, 0xda, 0xf8, 0x06, 0xaa, 0x2a, 0xf0, - 0x46, 0x18, 0xaa, 0x7c, 0xb1, 0x24, 0x26, 0x01, 0x2c, 0xd1, 0x0e, 0x4f, 0x65, 0xb6, 0x5d, 0x7b, - 0x10, 0xce, 0xfb, 0x1d, 0xc4, 0x05, 0xcb, 0xa5, 0x83, 0x68, 0xa6, 0xc6, 0x8f, 0x79, 0xa8, 0xee, - 0x0e, 0xe5, 0x49, 0x99, 0xae, 0x40, 0x21, 0xc5, 0x10, 0xd9, 0xd1, 0x58, 0xa8, 0xe3, 0x39, 0xb9, - 0x09, 0x6e, 0x36, 0x36, 0x62, 0xdd, 0xc9, 0xb4, 0xba, 0x98, 0xe1, 0x99, 0x5a, 0xa7, 0x04, 0x39, - 0xf7, 0x7e, 0x82, 0x9c, 0x48, 0x2f, 0xf7, 0xef, 0xa4, 0xa7, 0x4a, 0x47, 0x88, 0x20, 0xe1, 0x49, - 0x88, 0x5a, 0xdd, 0x39, 0xbf, 0x20, 0x85, 0x78, 0xa8, 0xe6, 0xca, 0x18, 0x53, 0x11, 0xf4, 0x58, - 0x9f, 0x19, 0x8d, 0xe7, 0xfc, 0x42, 0x4c, 0xc5, 0x97, 0x6a, 0x9e, 0x19, 0x07, 0x29, 0x0b, 0xd1, - 0x0a, 0x56, 0x19, 0xf7, 0xd4, 0x9c, 0x34, 0xc1, 0xb5, 0x46, 0x9e, 0x32, 0x79, 0x1c, 0x1c, 0x20, - 0x7a, 0x97, 0xf4, 0x9a, 0xaa, 0x59, 0xa3, 0xe1, 0x6d, 0x44, 0x42, 0x20, 0xa7, 0x25, 0x5f, 0xd0, - 0x56, 0x3d, 0x7e, 0x17, 0xc1, 0x9e, 0x55, 0x0d, 0x70, 0x66, 0x35, 0x5c, 0x06, 0xb5, 0xcd, 0x60, - 0x28, 0x30, 0xf2, 0x6a, 0x7a, 0xe5, 0x42, 0x4c, 0xc5, 0x63, 0x81, 0x11, 0xf9, 0x0a, 0x96, 0xf0, - 0xe0, 0x00, 0x43, 0xc9, 0x8e, 0x30, 0x98, 0xfc, 0xdc, 0x45, 0x9d, 0xe2, 0x96, 0x4d, 0xf1, 0xf5, - 0x77, 0x48, 0xf1, 0x8e, 0xd2, 0xd4, 0x98, 0xea, 0x5e, 0x96, 0x95, 0xd6, 0xdb, 0xfc, 0x26, 0xb3, - 0xcb, 0x7a, 0x17, 0x53, 0xeb, 0x4d, 0x8a, 0xaf, 0x00, 0xa8, 0xc3, 0x19, 0x0c, 0x3b, 0x87, 0x78, - 0xac, 0xab, 0xaa, 0xe8, 0xab, 0xe3, 0xda, 0xd3, 0xc0, 0x19, 0x05, 0x58, 0xfe, 0x8f, 0x0b, 0xf0, - 0xf3, 0x5c, 0xa1, 0xe2, 0xd6, 0x1a, 0x7f, 0x3a, 0x90, 0x37, 0x00, 0xd9, 0x80, 0xbc, 0x8d, 0xe5, - 0xe8, 0x58, 0x37, 0xcf, 0x89, 0xb5, 0x15, 0xca, 0x91, 0x8d, 0x60, 0x1d, 0xc9, 0x35, 0xa8, 0x9a, - 0x51, 0xd0, 0x47, 0x21, 0x68, 0x8c, 0xba, 0x60, 0x8a, 0x7e, 0xc5, 0xa0, 0x0f, 0x0c, 0x48, 0x6e, - 0x43, 0xad, 0x47, 0x85, 0x7c, 0x3c, 0x88, 0xa8, 0xc4, 0x40, 0xb2, 0x3e, 0x0a, 0x49, 0xfb, 0x03, - 0x5d, 0x39, 0x73, 0xfe, 0xd2, 0xc4, 0xb6, 0x9f, 0x99, 0x48, 0x13, 0x16, 0x99, 0xd8, 0x50, 0x25, - 0xed, 0xe3, 0xc1, 0x30, 0x89, 0x30, 0xd2, 0x65, 0x52, 0xf0, 0xdf, 0x86, 0xc9, 0x47, 0x70, 0x21, - 0x4c, 0x91, 0xaa, 0x36, 0x32, 0x61, 0x9e, 0xd7, 0xcc, 0xae, 0x35, 0x8c, 0x69, 0x1b, 0xdf, 0xcd, - 0x42, 0xc5, 0xc7, 0x23, 0x4c, 0xe5, 0xee, 0x40, 0xe5, 0x46, 0xff, 0x42, 0xaa, 0x81, 0x80, 0x46, - 0x51, 0x8a, 0x42, 0xd8, 0xbe, 0x50, 0x31, 0xe8, 0x86, 0x01, 0xc9, 0x87, 0x50, 0x0d, 0x69, 0xaf, - 0x17, 0xf0, 0x24, 0x30, 0x06, 0xfd, 0xa7, 0x05, 0xbf, 0xac, 0xd0, 0xdd, 0xc4, 0x70, 0xaa, 0x5b, - 0x40, 0xb7, 0xa1, 0x31, 0x97, 0xb9, 0xc9, 0xca, 0x1a, 0xcc, 0xa8, 0x26, 0x11, 0xb3, 0xa4, 0xa9, - 0x3f, 0x2b, 0x67, 0x11, 0xb3, 0xa4, 0x3d, 0x55, 0xed, 0x48, 0x2f, 0x9b, 0xc8, 0x6c, 0xfe, 0xfd, - 0x3a, 0x85, 0x8d, 0x97, 0x89, 0xb2, 0xf1, 0xfd, 0x3c, 0x94, 0xb7, 0xd4, 0xc1, 0xea, 0x7e, 0xb6, - 0x3f, 0x22, 0x1e, 0x2c, 0xe8, 0x54, 0xf1, 0xac, 0x2b, 0x66, 0x53, 0x75, 0x6d, 0x9a, 0x02, 0x36, - 0x07, 0x6b, 0x26, 0xe4, 0x6b, 0x28, 0xea, 0x96, 0x7d, 0x80, 0x28, 0xec, 0xa6, 0xb6, 0xfe, 0xe1, - 0xa6, 0xfe, 0x78, 0x75, 0xd5, 0x3d, 0xa6, 0xfd, 0xde, 0x67, 0x8d, 0x31, 0x53, 0xc3, 0x2f, 0xa8, - 0xf1, 0x36, 0xa2, 0x20, 0x37, 0x60, 0x31, 0xc5, 0x1e, 0x3d, 0xc6, 0x68, 0x9c, 0xa5, 0xbc, 0x69, - 0x3e, 0x16, 0xce, 0xd2, 0xb4, 0x0d, 0xa5, 0x30, 0x94, 0xa3, 0xac, 0x6c, 0x54, 0x0f, 0x2a, 0x9d, - 0xde, 0x8c, 0x4f, 0x48, 0xd9, 0xca, 0x18, 0xc2, 0xb1, 0xa4, 0xc9, 0x23, 0xa8, 0x32, 0xf3, 0xa2, - 0x09, 0x06, 0xfa, 0xae, 0xd0, 0x2d, 0xab, 0xb4, 0xfe, 0xf1, 0x39, 0x54, 0x53, 0xcf, 0x20, 0xbf, - 0xc2, 0xa6, 0x5e, 0x45, 0x4f, 0x60, 0x91, 0xdb, 0x0b, 0x28, 0x63, 0x85, 0xd5, 0xb9, 0x66, 0x69, - 0x7d, 0xed, 0x1c, 0xd6, 0xe9, 0x6b, 0xcb, 0xaf, 0xf2, 0xe9, 0x6b, 0x2c, 0x85, 0xcb, 0xfa, 0x21, - 0x16, 0xf2, 0x5e, 0x10, 0xf2, 0x44, 0xa6, 0x34, 0x94, 0xc1, 0x11, 0xa6, 0x82, 0xf1, 0xc4, 0x5e, - 0xdd, 0x9f, 0x9c, 0x13, 0x61, 0xcf, 0xfa, 0x6f, 0x59, 0xf7, 0x27, 0xc6, 0xdb, 0xbf, 0x34, 0x38, - 0xdd, 0x40, 0x9e, 0x8e, 0x65, 0xcb, 0x4d, 0xe9, 0xe8, 0x16, 0x75, 0x7e, 0x82, 0xa6, 0xca, 0x6d, - 0x33, 0xa7, 0x64, 0x92, 0x49, 0xdd, 0x82, 0xb7, 0xbe, 0x05, 0x98, 0x34, 0x17, 0x42, 0xa0, 0xba, - 0x87, 0x49, 0xc4, 0x92, 0xd8, 0xe6, 0xd6, 0x9d, 0x21, 0x4b, 0xb0, 0x68, 0xb1, 0x2c, 0x33, 0xae, - 0x43, 0x2e, 0x40, 0x25, 0x9b, 0x3d, 0x60, 0x09, 0x46, 0xee, 0x9c, 0x82, 0xec, 0x3a, 0x13, 0xd6, - 0xcd, 0x91, 0x32, 0x14, 0xcc, 0x18, 0x23, 0x77, 0x9e, 0x94, 0x60, 0x61, 0xc3, 0x3c, 0x14, 0xdc, - 0xfc, 0x4a, 0xee, 0xe7, 0x9f, 0xea, 0xce, 0xad, 0x2f, 0xa0, 0x76, 0x5a, 0x1b, 0x25, 0x2e, 0x94, - 0x1f, 0x72, 0xb9, 0x9d, 0x3d, 0x9b, 0xdc, 0x19, 0x52, 0x81, 0xe2, 0x64, 0xea, 0x28, 0xe6, 0xbb, - 0x23, 0x0c, 0x87, 0x8a, 0x6c, 0xd6, 0x92, 0xb5, 0xe1, 0xd2, 0xdf, 0x64, 0x96, 0xe4, 0x61, 0xf6, - 0xc9, 0x6d, 0x77, 0x46, 0x7f, 0xd7, 0x5d, 0xc7, 0x38, 0x6c, 0xde, 0x7b, 0xf1, 0xba, 0xee, 0xbc, - 0x7c, 0x5d, 0x77, 0x7e, 0x7f, 0x5d, 0x77, 0x7e, 0x78, 0x53, 0x9f, 0x79, 0xf9, 0xa6, 0x3e, 0xf3, - 0xeb, 0x9b, 0xfa, 0xcc, 0xb3, 0xb5, 0x13, 0x95, 0xa4, 0x12, 0xbb, 0x66, 0x1e, 0xe6, 0x09, 0x8f, - 0xb0, 0x3d, 0x3a, 0xf9, 0xfe, 0xd7, 0x45, 0xd5, 0xc9, 0xeb, 0x83, 0xbb, 0xf3, 0x57, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x9b, 0xa4, 0xfd, 0xc5, 0x2d, 0x0c, 0x00, 0x00, + // 1348 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4d, 0x6f, 0x1b, 0x37, + 0x13, 0xf6, 0xda, 0xb2, 0x2c, 0x8d, 0x3e, 0xbc, 0xa6, 0x15, 0x67, 0xe3, 0x17, 0x51, 0xfc, 0xaa, + 0x75, 0xa2, 0xb8, 0xb5, 0x84, 0x28, 0x40, 0x51, 0xf4, 0x66, 0x1b, 0x71, 0xe2, 0xb6, 0x89, 0x8d, + 0x8d, 0x63, 0x20, 0x39, 0x74, 0x4b, 0xed, 0xd2, 0x12, 0xe1, 0xd5, 0x52, 0x5d, 0x52, 0x86, 0x14, + 0xf4, 0xd6, 0x73, 0x81, 0xfe, 0x88, 0x1e, 0x7a, 0xec, 0xcf, 0xc8, 0x31, 0xc7, 0xa2, 0x87, 0x20, + 0x48, 0xfe, 0x41, 0xcf, 0x3d, 0x14, 0xfc, 0x92, 0xac, 0xc0, 0xb5, 0xd3, 0xb4, 0x27, 0x71, 0x66, + 0x38, 0xcf, 0xcc, 0x0e, 0xe7, 0x19, 0x52, 0xd0, 0x7a, 0x4e, 0x04, 0x0e, 0xbb, 0x98, 0x26, 0x4d, + 0xb5, 0x62, 0x29, 0x69, 0x86, 0x29, 0xe3, 0x5c, 0xeb, 0xd4, 0x32, 0x50, 0xeb, 0x40, 0x0c, 0x1b, + 0xfd, 0x94, 0x09, 0x86, 0xae, 0x8f, 0x7d, 0x1a, 0xd6, 0xa7, 0x31, 0xf1, 0x59, 0xad, 0x74, 0x58, + 0x87, 0xa9, 0x9d, 0x4d, 0xb9, 0xd2, 0x4e, 0xab, 0x37, 0xcf, 0x09, 0xd4, 0x3f, 0xe9, 0x34, 0x43, + 0x26, 0xc3, 0x30, 0x9a, 0xe8, 0x7d, 0xb5, 0x5f, 0x33, 0x50, 0xda, 0x4b, 0xda, 0x6c, 0x90, 0x44, + 0x07, 0x38, 0xc5, 0x3d, 0x8e, 0x56, 0x20, 0xcb, 0x49, 0x12, 0x91, 0xd4, 0x73, 0xd6, 0x9c, 0x7a, + 0xde, 0x37, 0x12, 0xba, 0x09, 0x8b, 0x7a, 0x65, 0xf2, 0xa3, 0x91, 0x37, 0xbb, 0xe6, 0xd4, 0xe7, + 0xfc, 0x92, 0x56, 0xef, 0x48, 0xed, 0x5e, 0x84, 0xfe, 0x07, 0x79, 0x31, 0x0c, 0x58, 0x4a, 0x3b, + 0x34, 0xf1, 0xe6, 0x14, 0x44, 0x4e, 0x0c, 0xf7, 0x95, 0x8c, 0xb6, 0x21, 0x2f, 0x83, 0x07, 0x62, + 0xd4, 0x27, 0x5e, 0x66, 0xcd, 0xa9, 0x97, 0x5b, 0xeb, 0x8d, 0x73, 0xbe, 0xaf, 0x7f, 0xd2, 0x69, + 0xa8, 0x2c, 0x77, 0x18, 0x4d, 0x0e, 0x47, 0x7d, 0xe2, 0xe7, 0x42, 0xb3, 0x42, 0x15, 0x98, 0xc7, + 0x9c, 0x13, 0xe1, 0xcd, 0x2b, 0x70, 0x2d, 0xa0, 0xfb, 0x90, 0xc5, 0x3d, 0x36, 0x48, 0x84, 0x97, + 0x95, 0xea, 0xed, 0xe6, 0x8b, 0x57, 0x37, 0x66, 0x7e, 0x7f, 0x75, 0xe3, 0x56, 0x87, 0x8a, 0xee, + 0xa0, 0xdd, 0x08, 0x59, 0xaf, 0x19, 0x32, 0xde, 0x63, 0xdc, 0xfc, 0x6c, 0xf2, 0xe8, 0xa4, 0x29, + 0xf3, 0xe0, 0x8d, 0x27, 0x34, 0x11, 0xbe, 0x71, 0x47, 0x1f, 0x41, 0x89, 0xb5, 0x39, 0x49, 0x4f, + 0x49, 0x14, 0x74, 0x31, 0xef, 0x7a, 0x0b, 0x2a, 0x4c, 0xd1, 0x2a, 0x1f, 0x60, 0xde, 0x45, 0x9f, + 0x83, 0x37, 0xde, 0x44, 0x86, 0x82, 0xa4, 0x09, 0x8e, 0x83, 0x2e, 0xa1, 0x9d, 0xae, 0xf0, 0x72, + 0x6b, 0x4e, 0x3d, 0xe3, 0xaf, 0x58, 0xfb, 0x3d, 0x63, 0x7e, 0xa0, 0xac, 0xe8, 0xff, 0x50, 0x6c, + 0xe3, 0x38, 0x66, 0x22, 0xa0, 0x49, 0x44, 0x86, 0x5e, 0x5e, 0xa1, 0x17, 0xb4, 0x6e, 0x4f, 0xaa, + 0x50, 0x0b, 0xae, 0x1c, 0xd3, 0x04, 0xc7, 0xf4, 0x39, 0x89, 0x02, 0x59, 0x12, 0x8b, 0x0c, 0x0a, + 0x79, 0x79, 0x6c, 0x7c, 0x46, 0x04, 0x36, 0xb0, 0x14, 0x56, 0xc4, 0x30, 0x30, 0x16, 0x2c, 0x28, + 0x4b, 0x02, 0x2e, 0xb0, 0x18, 0x70, 0xaf, 0xa0, 0xaa, 0x7c, 0xb7, 0x71, 0x61, 0x17, 0x35, 0x0e, + 0x87, 0xbb, 0x67, 0x7c, 0x1f, 0x2b, 0x57, 0xbf, 0x22, 0xce, 0xd1, 0xd6, 0xbe, 0x83, 0xb2, 0x0c, + 0xbc, 0x15, 0x86, 0xb2, 0x5e, 0x34, 0xe9, 0xa0, 0x00, 0x96, 0x71, 0x9b, 0xa5, 0xc2, 0xa6, 0x6b, + 0x0e, 0xc2, 0xf9, 0xb0, 0x83, 0x58, 0x32, 0x58, 0x2a, 0x88, 0x42, 0xaa, 0x1d, 0x41, 0x61, 0x07, + 0xc7, 0xf1, 0x7e, 0x5f, 0xa6, 0xc1, 0x65, 0x8b, 0x75, 0x30, 0x0f, 0x62, 0xda, 0xa3, 0x3a, 0x4a, + 0xc6, 0xcf, 0x75, 0x30, 0xff, 0x5a, 0xca, 0x68, 0x03, 0x96, 0x28, 0x0f, 0x70, 0xda, 0xa6, 0x22, + 0xc5, 0xe9, 0x28, 0x08, 0x71, 0x1c, 0xab, 0x4e, 0xcd, 0xf9, 0x8b, 0x94, 0x6f, 0x59, 0xbd, 0xc4, + 0xab, 0xbd, 0xce, 0x42, 0x79, 0x7f, 0x20, 0xce, 0xb6, 0xff, 0x2a, 0xe4, 0x52, 0x12, 0x12, 0x7a, + 0x3a, 0x26, 0xc0, 0x58, 0x46, 0xb7, 0xc1, 0xb5, 0x6b, 0x4d, 0x82, 0x3d, 0xcb, 0x81, 0x45, 0xab, + 0xb7, 0x2c, 0x98, 0x6a, 0xf4, 0xb9, 0x0f, 0x6b, 0xf4, 0x49, 0x4b, 0x67, 0xfe, 0x5d, 0x4b, 0x4b, + 0x4a, 0x72, 0x1e, 0x24, 0x2c, 0x09, 0x89, 0x62, 0x4d, 0xc6, 0xcf, 0x09, 0xce, 0x1f, 0x49, 0x79, + 0xba, 0x98, 0xd9, 0x77, 0x8a, 0x69, 0x8c, 0xfd, 0x94, 0x86, 0xc4, 0x10, 0x41, 0x1a, 0x0f, 0xa4, + 0x8c, 0xea, 0xe0, 0x1a, 0x23, 0x4b, 0xa9, 0x18, 0x05, 0xc7, 0x84, 0x78, 0x57, 0xd5, 0x9e, 0xb2, + 0xde, 0xa3, 0xd4, 0xbb, 0x84, 0x20, 0x04, 0x19, 0x45, 0xa5, 0x9c, 0xb2, 0xaa, 0xf5, 0xfb, 0x10, + 0xe1, 0x22, 0x96, 0xc1, 0x85, 0x2c, 0xbb, 0x06, 0x32, 0xcd, 0x60, 0xc0, 0x49, 0xe4, 0x55, 0xd4, + 0xce, 0x85, 0x0e, 0xe6, 0x4f, 0x38, 0x89, 0xd0, 0x37, 0xb0, 0x4c, 0x8e, 0x8f, 0x49, 0x28, 0xe8, + 0x29, 0x09, 0x26, 0x1f, 0x77, 0x45, 0x95, 0xb8, 0x61, 0x4a, 0x7c, 0xf3, 0x3d, 0x4a, 0xbc, 0x27, + 0x7b, 0x75, 0x0c, 0x75, 0xdf, 0x56, 0xa5, 0xf1, 0x2e, 0xbe, 0xae, 0xec, 0x8a, 0xca, 0x62, 0x6a, + 0xbf, 0x2e, 0xf1, 0x75, 0x00, 0x79, 0x38, 0xfd, 0x41, 0xfb, 0x84, 0x8c, 0x14, 0x5b, 0xf3, 0xbe, + 0x3c, 0xae, 0x03, 0xa5, 0xb8, 0x80, 0xd8, 0xc5, 0xff, 0x98, 0xd8, 0xe8, 0x21, 0x14, 0x25, 0x59, + 0x02, 0xa6, 0x69, 0xe6, 0x79, 0x6b, 0x4e, 0xbd, 0xd0, 0xda, 0xb8, 0x24, 0xc0, 0x19, 0x62, 0xfa, + 0x85, 0x70, 0x22, 0x7c, 0x99, 0xc9, 0x95, 0xdc, 0x4a, 0xed, 0x4f, 0x07, 0xb2, 0x06, 0x7f, 0x0b, + 0xb2, 0x26, 0x75, 0x47, 0xa5, 0x7e, 0xfb, 0x32, 0xe4, 0x50, 0x0c, 0x4d, 0xc2, 0xc6, 0x11, 0xad, + 0x43, 0x59, 0xaf, 0x82, 0x1e, 0xe1, 0x1c, 0x77, 0x88, 0xe2, 0x5f, 0xde, 0x2f, 0x69, 0xed, 0x43, + 0xad, 0x44, 0x77, 0xa0, 0x12, 0x63, 0x2e, 0x9e, 0xf4, 0x23, 0x2c, 0x48, 0x20, 0x68, 0x8f, 0x70, + 0x81, 0x7b, 0x7d, 0x45, 0xc4, 0x39, 0x7f, 0x79, 0x62, 0x3b, 0xb4, 0x26, 0x54, 0x07, 0x39, 0x1d, + 0xe4, 0xe4, 0xf1, 0xc9, 0xf1, 0x20, 0x89, 0x48, 0xa4, 0x58, 0xa7, 0x87, 0xc6, 0x59, 0x35, 0xfa, + 0x04, 0x96, 0xc2, 0x94, 0x60, 0x39, 0xed, 0x26, 0xc8, 0xf3, 0x0a, 0xd9, 0x35, 0x86, 0x31, 0x6c, + 0xed, 0x87, 0x59, 0x28, 0xf9, 0xe4, 0x94, 0xa4, 0xc2, 0x0e, 0xaf, 0x75, 0x28, 0xa7, 0x4a, 0x11, + 0xe0, 0x28, 0x4a, 0x09, 0xe7, 0x66, 0xcc, 0x94, 0xb4, 0x76, 0x4b, 0x2b, 0xd1, 0xc7, 0x50, 0xd6, + 0x87, 0x91, 0x04, 0xda, 0x60, 0x66, 0x98, 0x3a, 0xa2, 0xfd, 0x44, 0x63, 0xca, 0xcb, 0x4a, 0x4d, + 0xcb, 0x31, 0x96, 0xbe, 0x70, 0x8b, 0x4a, 0x69, 0xa1, 0x26, 0x11, 0x6d, 0xd1, 0xe4, 0x97, 0x15, + 0x6d, 0x44, 0x5b, 0xb4, 0xa7, 0x72, 0xba, 0xa9, 0x6d, 0x93, 0xae, 0x9d, 0xff, 0xb0, 0xc1, 0x63, + 0xe2, 0xd9, 0x1e, 0xaf, 0xfd, 0x38, 0x0f, 0xc5, 0x1d, 0x79, 0xb0, 0x6a, 0x3c, 0x1e, 0x0e, 0x91, + 0x07, 0x0b, 0xaa, 0x54, 0xcc, 0x0e, 0x59, 0x2b, 0xca, 0xdb, 0x5d, 0xcf, 0x03, 0x7d, 0xb0, 0x5a, + 0x40, 0xdf, 0x42, 0x5e, 0xdd, 0x2c, 0xc7, 0x84, 0x70, 0x93, 0xd4, 0xce, 0x3f, 0x4c, 0xea, 0x8f, + 0x57, 0x37, 0xdc, 0x11, 0xee, 0xc5, 0x5f, 0xd4, 0xc6, 0x48, 0x35, 0x3f, 0x27, 0xd7, 0xbb, 0x84, + 0x70, 0x74, 0x0b, 0x16, 0x53, 0x12, 0xe3, 0x11, 0x89, 0xc6, 0x55, 0xca, 0xea, 0x59, 0x66, 0xd4, + 0xb6, 0x4c, 0xbb, 0x50, 0x08, 0x43, 0x31, 0xb4, 0x2c, 0xcc, 0x29, 0x92, 0xac, 0x5f, 0xd2, 0xca, + 0xa6, 0x8d, 0x21, 0x1c, 0xb7, 0x34, 0x7a, 0x0c, 0x65, 0xaa, 0x1f, 0x5e, 0x41, 0x5f, 0x5d, 0x3d, + 0x6a, 0x02, 0x16, 0x5a, 0x9f, 0x5e, 0x02, 0x35, 0xf5, 0x5a, 0xf3, 0x4b, 0x74, 0xea, 0xf1, 0x76, + 0x04, 0x8b, 0xcc, 0xdc, 0x67, 0x16, 0x15, 0xd6, 0xe6, 0xea, 0x85, 0xd6, 0xe6, 0x25, 0xa8, 0xd3, + 0xb7, 0xa0, 0x5f, 0x66, 0xd3, 0xb7, 0x62, 0x0a, 0xd7, 0xd4, 0x7b, 0x31, 0x64, 0x71, 0x10, 0xb2, + 0x44, 0xa4, 0x38, 0x14, 0xc1, 0x29, 0x49, 0x39, 0x65, 0x89, 0x79, 0x61, 0x7c, 0x76, 0x49, 0x84, + 0x03, 0xe3, 0xbf, 0x63, 0xdc, 0x8f, 0xb4, 0xb7, 0x7f, 0xb5, 0x7f, 0xbe, 0x01, 0x3d, 0x1d, 0xb7, + 0xad, 0x1d, 0x48, 0xc5, 0xf7, 0x2a, 0xd0, 0x14, 0xdd, 0xb6, 0x33, 0xb2, 0x4d, 0x6c, 0xab, 0x1b, + 0xe5, 0xc6, 0xf7, 0x00, 0x93, 0xe1, 0x82, 0x10, 0x94, 0x0f, 0x48, 0x12, 0xd1, 0xa4, 0x63, 0x6a, + 0xeb, 0xce, 0xa0, 0x65, 0x58, 0x34, 0x3a, 0x5b, 0x19, 0xd7, 0x41, 0x4b, 0x50, 0xb2, 0xd2, 0x43, + 0x9a, 0x90, 0xc8, 0x9d, 0x93, 0x2a, 0xb3, 0x4f, 0x87, 0x75, 0x33, 0xa8, 0x08, 0x39, 0xbd, 0x26, + 0x91, 0x3b, 0x8f, 0x0a, 0xb0, 0xb0, 0xa5, 0xdf, 0x33, 0x6e, 0x76, 0x35, 0xf3, 0xcb, 0xcf, 0x55, + 0x67, 0xe3, 0x2b, 0xa8, 0x9c, 0x37, 0x95, 0x91, 0x0b, 0xc5, 0x47, 0x4c, 0xec, 0xda, 0xd7, 0x9d, + 0x3b, 0x83, 0x4a, 0x90, 0x9f, 0x88, 0x8e, 0x44, 0xbe, 0x37, 0x24, 0xe1, 0x40, 0x82, 0xcd, 0x1a, + 0xb0, 0x26, 0x5c, 0xfd, 0x9b, 0xca, 0xa2, 0x2c, 0xcc, 0x1e, 0xdd, 0x71, 0x67, 0xd4, 0x6f, 0xcb, + 0x75, 0xb4, 0xc3, 0xf6, 0xfd, 0x17, 0x6f, 0xaa, 0xce, 0xcb, 0x37, 0x55, 0xe7, 0xf5, 0x9b, 0xaa, + 0xf3, 0xd3, 0xdb, 0xea, 0xcc, 0xcb, 0xb7, 0xd5, 0x99, 0xdf, 0xde, 0x56, 0x67, 0x9e, 0x6d, 0x9e, + 0x61, 0x92, 0x2c, 0xec, 0xa6, 0xfe, 0xff, 0x90, 0xb0, 0x88, 0x34, 0x87, 0x67, 0xff, 0xa6, 0x28, + 0x52, 0xb5, 0xb3, 0xea, 0xe0, 0xee, 0xfe, 0x15, 0x00, 0x00, 0xff, 0xff, 0x94, 0x4b, 0x30, 0xb4, + 0xd4, 0x0c, 0x00, 0x00, } func (m *InboundParams) Marshal() (dAtA []byte, err error) { @@ -901,6 +967,44 @@ func (m *ZetaAccounting) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *CallOptions) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CallOptions) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CallOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.IsArbitraryCall { + i-- + if m.IsArbitraryCall { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if m.GasLimit != 0 { + i = encodeVarintCrossChainTx(dAtA, i, uint64(m.GasLimit)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *OutboundParams) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -921,6 +1025,20 @@ func (m *OutboundParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.CallOptions != nil { + { + size, err := m.CallOptions.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCrossChainTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xc2 + } if len(m.GasPriorityFee) > 0 { i -= len(m.GasPriorityFee) copy(dAtA[i:], m.GasPriorityFee) @@ -1328,6 +1446,21 @@ func (m *ZetaAccounting) Size() (n int) { return n } +func (m *CallOptions) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.GasLimit != 0 { + n += 1 + sovCrossChainTx(uint64(m.GasLimit)) + } + if m.IsArbitraryCall { + n += 2 + } + return n +} + func (m *OutboundParams) Size() (n int) { if m == nil { return 0 @@ -1386,6 +1519,10 @@ func (m *OutboundParams) Size() (n int) { if l > 0 { n += 2 + l + sovCrossChainTx(uint64(l)) } + if m.CallOptions != nil { + l = m.CallOptions.Size() + n += 2 + l + sovCrossChainTx(uint64(l)) + } return n } @@ -1911,6 +2048,95 @@ func (m *ZetaAccounting) Unmarshal(dAtA []byte) error { } return nil } +func (m *CallOptions) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrossChainTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CallOptions: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CallOptions: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GasLimit", wireType) + } + m.GasLimit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrossChainTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.GasLimit |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsArbitraryCall", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrossChainTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsArbitraryCall = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipCrossChainTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCrossChainTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *OutboundParams) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -2352,6 +2578,42 @@ func (m *OutboundParams) Unmarshal(dAtA []byte) error { } m.GasPriorityFee = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 24: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CallOptions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrossChainTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCrossChainTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCrossChainTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.CallOptions == nil { + m.CallOptions = &CallOptions{} + } + if err := m.CallOptions.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCrossChainTx(dAtA[iNdEx:]) diff --git a/x/crosschain/types/message_vote_inbound.go b/x/crosschain/types/message_vote_inbound.go index 8592b7e607..c73c9a24d4 100644 --- a/x/crosschain/types/message_vote_inbound.go +++ b/x/crosschain/types/message_vote_inbound.go @@ -56,20 +56,24 @@ func NewMsgVoteInbound( asset string, eventIndex uint, protocolContractVersion ProtocolContractVersion, + isArbitraryCall bool, options ...InboundVoteOption, ) *MsgVoteInbound { msg := &MsgVoteInbound{ - Creator: creator, - Sender: sender, - SenderChainId: senderChain, - TxOrigin: txOrigin, - Receiver: receiver, - ReceiverChain: receiverChain, - Amount: amount, - Message: message, - InboundHash: inboundHash, - InboundBlockHeight: inboundBlockHeight, - GasLimit: gasLimit, + Creator: creator, + Sender: sender, + SenderChainId: senderChain, + TxOrigin: txOrigin, + Receiver: receiver, + ReceiverChain: receiverChain, + Amount: amount, + Message: message, + InboundHash: inboundHash, + InboundBlockHeight: inboundBlockHeight, + CallOptions: &CallOptions{ + GasLimit: gasLimit, + IsArbitraryCall: isArbitraryCall, + }, CoinType: coinType, Asset: asset, EventIndex: uint64(eventIndex), diff --git a/x/crosschain/types/message_vote_inbound_test.go b/x/crosschain/types/message_vote_inbound_test.go index c7fbcbb531..77631f20fd 100644 --- a/x/crosschain/types/message_vote_inbound_test.go +++ b/x/crosschain/types/message_vote_inbound_test.go @@ -1,12 +1,13 @@ package types_test import ( - "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayevm.sol" - "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol" "math/big" "math/rand" "testing" + "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayevm.sol" + "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol" + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -36,6 +37,7 @@ func TestNewMsgVoteInbound(t *testing.T) { sample.String(), 42, types.ProtocolContractVersion_V1, + true, ) require.EqualValues(t, types.NewEmptyRevertOptions(), msg.RevertOptions) }) @@ -61,6 +63,7 @@ func TestNewMsgVoteInbound(t *testing.T) { sample.String(), 42, types.ProtocolContractVersion_V1, + true, types.WithZEVMRevertOptions(gatewayzevm.RevertOptions{ RevertAddress: revertAddress, CallOnRevert: true, @@ -94,6 +97,7 @@ func TestNewMsgVoteInbound(t *testing.T) { sample.String(), 42, types.ProtocolContractVersion_V1, + true, types.WithZEVMRevertOptions(gatewayzevm.RevertOptions{ RevertAddress: revertAddress, CallOnRevert: true, @@ -131,6 +135,7 @@ func TestNewMsgVoteInbound(t *testing.T) { sample.String(), 42, types.ProtocolContractVersion_V1, + true, types.WithEVMRevertOptions(gatewayevm.RevertOptions{ RevertAddress: revertAddress, CallOnRevert: true, @@ -163,6 +168,7 @@ func TestNewMsgVoteInbound(t *testing.T) { sample.String(), 42, types.ProtocolContractVersion_V1, + true, types.WithEVMRevertOptions(gatewayevm.RevertOptions{ RevertAddress: revertAddress, CallOnRevert: true, @@ -206,6 +212,7 @@ func TestMsgVoteInbound_ValidateBasic(t *testing.T) { sample.String(), 42, types.ProtocolContractVersion_V1, + true, ), }, { @@ -226,6 +233,7 @@ func TestMsgVoteInbound_ValidateBasic(t *testing.T) { sample.String(), 42, types.ProtocolContractVersion_V1, + true, ), err: sdkerrors.ErrInvalidAddress, }, @@ -247,6 +255,7 @@ func TestMsgVoteInbound_ValidateBasic(t *testing.T) { sample.String(), 42, types.ProtocolContractVersion_V1, + true, ), err: types.ErrInvalidChainID, }, @@ -268,6 +277,7 @@ func TestMsgVoteInbound_ValidateBasic(t *testing.T) { sample.String(), 42, types.ProtocolContractVersion_V1, + true, ), err: types.ErrInvalidChainID, }, @@ -289,6 +299,7 @@ func TestMsgVoteInbound_ValidateBasic(t *testing.T) { sample.String(), 42, types.ProtocolContractVersion_V1, + true, ), err: sdkerrors.ErrInvalidRequest, }, @@ -309,17 +320,19 @@ func TestMsgVoteInbound_Digest(t *testing.T) { r := rand.New(rand.NewSource(42)) msg := types.MsgVoteInbound{ - Creator: sample.AccAddress(), - Sender: sample.AccAddress(), - SenderChainId: 42, - TxOrigin: sample.String(), - Receiver: sample.String(), - ReceiverChain: 42, - Amount: math.NewUint(42), - Message: sample.String(), - InboundHash: sample.String(), - InboundBlockHeight: 42, - GasLimit: 42, + Creator: sample.AccAddress(), + Sender: sample.AccAddress(), + SenderChainId: 42, + TxOrigin: sample.String(), + Receiver: sample.String(), + ReceiverChain: 42, + Amount: math.NewUint(42), + Message: sample.String(), + InboundHash: sample.String(), + InboundBlockHeight: 42, + CallOptions: &types.CallOptions{ + GasLimit: 42, + }, CoinType: coin.CoinType_Zeta, Asset: sample.String(), EventIndex: 42, @@ -390,7 +403,7 @@ func TestMsgVoteInbound_Digest(t *testing.T) { // gas limit used msg = msg - msg.GasLimit = 43 + msg.CallOptions.GasLimit = 43 hash2 = msg.Digest() require.NotEqual(t, hash, hash2, "gas limit should change hash") diff --git a/x/crosschain/types/tx.pb.go b/x/crosschain/types/tx.pb.go index 6c75354214..7496f74404 100644 --- a/x/crosschain/types/tx.pb.go +++ b/x/crosschain/types/tx.pb.go @@ -988,19 +988,21 @@ type MsgVoteInbound struct { // string zeta_burnt = 6; Amount github_com_cosmos_cosmos_sdk_types.Uint `protobuf:"bytes,6,opt,name=amount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Uint" json:"amount"` // string mMint = 7; - Message string `protobuf:"bytes,8,opt,name=message,proto3" json:"message,omitempty"` - InboundHash string `protobuf:"bytes,9,opt,name=inbound_hash,json=inboundHash,proto3" json:"inbound_hash,omitempty"` - InboundBlockHeight uint64 `protobuf:"varint,10,opt,name=inbound_block_height,json=inboundBlockHeight,proto3" json:"inbound_block_height,omitempty"` - GasLimit uint64 `protobuf:"varint,11,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty"` - CoinType coin.CoinType `protobuf:"varint,12,opt,name=coin_type,json=coinType,proto3,enum=zetachain.zetacore.pkg.coin.CoinType" json:"coin_type,omitempty"` - TxOrigin string `protobuf:"bytes,13,opt,name=tx_origin,json=txOrigin,proto3" json:"tx_origin,omitempty"` - Asset string `protobuf:"bytes,14,opt,name=asset,proto3" json:"asset,omitempty"` + Message string `protobuf:"bytes,8,opt,name=message,proto3" json:"message,omitempty"` + InboundHash string `protobuf:"bytes,9,opt,name=inbound_hash,json=inboundHash,proto3" json:"inbound_hash,omitempty"` + InboundBlockHeight uint64 `protobuf:"varint,10,opt,name=inbound_block_height,json=inboundBlockHeight,proto3" json:"inbound_block_height,omitempty"` + // Deprecated (v21), use CallOptions + GasLimit uint64 `protobuf:"varint,11,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty"` + CoinType coin.CoinType `protobuf:"varint,12,opt,name=coin_type,json=coinType,proto3,enum=zetachain.zetacore.pkg.coin.CoinType" json:"coin_type,omitempty"` + TxOrigin string `protobuf:"bytes,13,opt,name=tx_origin,json=txOrigin,proto3" json:"tx_origin,omitempty"` + Asset string `protobuf:"bytes,14,opt,name=asset,proto3" json:"asset,omitempty"` // event index of the sent asset in the observed tx EventIndex uint64 `protobuf:"varint,15,opt,name=event_index,json=eventIndex,proto3" json:"event_index,omitempty"` // protocol contract version to use for the cctx workflow ProtocolContractVersion ProtocolContractVersion `protobuf:"varint,16,opt,name=protocol_contract_version,json=protocolContractVersion,proto3,enum=zetachain.zetacore.crosschain.ProtocolContractVersion" json:"protocol_contract_version,omitempty"` // revert options provided by the sender RevertOptions RevertOptions `protobuf:"bytes,17,opt,name=revert_options,json=revertOptions,proto3" json:"revert_options"` + CallOptions *CallOptions `protobuf:"bytes,18,opt,name=call_options,json=callOptions,proto3" json:"call_options,omitempty"` } func (m *MsgVoteInbound) Reset() { *m = MsgVoteInbound{} } @@ -1141,6 +1143,13 @@ func (m *MsgVoteInbound) GetRevertOptions() RevertOptions { return RevertOptions{} } +func (m *MsgVoteInbound) GetCallOptions() *CallOptions { + if m != nil { + return m.CallOptions + } + return nil +} + type MsgVoteInboundResponse struct { } @@ -1706,119 +1715,120 @@ func init() { } var fileDescriptor_15f0860550897740 = []byte{ - // 1782 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0xcd, 0x6f, 0xdb, 0xc8, - 0x15, 0x37, 0xd7, 0xb2, 0x2c, 0x3d, 0xd9, 0xb2, 0xcd, 0x75, 0x6c, 0x99, 0x5e, 0xcb, 0x8e, 0xd2, - 0xb8, 0x46, 0x11, 0x4b, 0xae, 0xb2, 0x4d, 0xb7, 0xde, 0xa2, 0xdb, 0x58, 0xbb, 0xf1, 0xba, 0x88, - 0x12, 0x83, 0xeb, 0x6c, 0x3f, 0x2e, 0x04, 0x45, 0x8e, 0x69, 0xc2, 0x12, 0x47, 0xe0, 0x8c, 0xb4, - 0x72, 0x50, 0xa0, 0x45, 0x81, 0x02, 0x3d, 0xb6, 0x45, 0x4f, 0x39, 0xf4, 0x56, 0xa0, 0xfd, 0x4f, - 0x72, 0x0c, 0x7a, 0x2a, 0x7a, 0x08, 0x8a, 0xe4, 0xd4, 0x5b, 0xdb, 0x6b, 0x2f, 0x05, 0xdf, 0x0c, - 0x19, 0x89, 0xfa, 0xb4, 0x8c, 0x62, 0x2f, 0x16, 0xe7, 0xf1, 0xfd, 0xde, 0xbc, 0xaf, 0x99, 0xf7, - 0x1e, 0x0d, 0xbb, 0xcf, 0x09, 0x37, 0xad, 0x0b, 0xd3, 0xf5, 0x4a, 0xf8, 0x44, 0x7d, 0x52, 0xb2, - 0x7c, 0xca, 0x98, 0xa0, 0xf1, 0x4e, 0xb1, 0xe9, 0x53, 0x4e, 0xd5, 0xad, 0x88, 0xaf, 0x18, 0xf2, - 0x15, 0xdf, 0xf1, 0x69, 0xab, 0x0e, 0x75, 0x28, 0x72, 0x96, 0x82, 0x27, 0x01, 0xd2, 0xbe, 0x35, - 0x40, 0x78, 0xf3, 0xd2, 0x29, 0x21, 0x89, 0xc9, 0x1f, 0xc9, 0xbb, 0x3b, 0x8c, 0x97, 0xba, 0x1e, - 0xfe, 0x19, 0x23, 0xb3, 0xe9, 0x53, 0x7a, 0xce, 0xe4, 0x8f, 0xe4, 0x7d, 0x30, 0xda, 0x38, 0xdf, - 0xe4, 0xc4, 0xa8, 0xbb, 0x0d, 0x97, 0x13, 0xdf, 0x38, 0xaf, 0x9b, 0x4e, 0x88, 0x2b, 0x8f, 0xc6, - 0xe1, 0xa3, 0x81, 0xcf, 0x46, 0xe8, 0xa0, 0xc2, 0xef, 0x15, 0x50, 0xab, 0xcc, 0xa9, 0xba, 0x4e, - 0x20, 0xf6, 0x8c, 0xb1, 0x47, 0x2d, 0xcf, 0x66, 0x6a, 0x0e, 0xe6, 0x2d, 0x9f, 0x98, 0x9c, 0xfa, - 0x39, 0x65, 0x47, 0xd9, 0x4b, 0xeb, 0xe1, 0x52, 0xdd, 0x80, 0x94, 0x10, 0xe1, 0xda, 0xb9, 0xf7, - 0x76, 0x94, 0xbd, 0x59, 0x7d, 0x1e, 0xd7, 0x27, 0xb6, 0x7a, 0x0c, 0x49, 0xb3, 0x41, 0x5b, 0x1e, - 0xcf, 0xcd, 0x06, 0x98, 0xa3, 0xd2, 0xcb, 0xd7, 0xdb, 0x33, 0x7f, 0x7f, 0xbd, 0xfd, 0x4d, 0xc7, - 0xe5, 0x17, 0xad, 0x5a, 0xd1, 0xa2, 0x8d, 0x92, 0x45, 0x59, 0x83, 0x32, 0xf9, 0xb3, 0xcf, 0xec, - 0xcb, 0x12, 0xbf, 0x6a, 0x12, 0x56, 0x7c, 0xe6, 0x7a, 0x5c, 0x97, 0xf0, 0xc2, 0x07, 0xa0, 0xf5, - 0xeb, 0xa4, 0x13, 0xd6, 0xa4, 0x1e, 0x23, 0x85, 0x27, 0xf0, 0x7e, 0x95, 0x39, 0xcf, 0x9a, 0xb6, - 0x78, 0xf9, 0xd0, 0xb6, 0x7d, 0xc2, 0x46, 0xa9, 0xbc, 0x05, 0xc0, 0x19, 0x33, 0x9a, 0xad, 0xda, - 0x25, 0xb9, 0x42, 0xa5, 0xd3, 0x7a, 0x9a, 0x33, 0x76, 0x8a, 0x84, 0xc2, 0x16, 0x6c, 0x0e, 0x90, - 0x17, 0x6d, 0xf7, 0xc7, 0xf7, 0x60, 0xb5, 0xca, 0x9c, 0x87, 0xb6, 0x7d, 0xe2, 0xd5, 0x68, 0xcb, - 0xb3, 0xcf, 0x7c, 0xd3, 0xba, 0x24, 0xfe, 0x74, 0x3e, 0x5a, 0x87, 0x79, 0xde, 0x31, 0x2e, 0x4c, - 0x76, 0x21, 0x9c, 0xa4, 0x27, 0x79, 0xe7, 0x73, 0x93, 0x5d, 0xa8, 0x47, 0x90, 0x0e, 0xd2, 0xc5, - 0x08, 0xdc, 0x91, 0x4b, 0xec, 0x28, 0x7b, 0xd9, 0xf2, 0xdd, 0xe2, 0x80, 0xec, 0x6d, 0x5e, 0x3a, - 0x45, 0xcc, 0xab, 0x0a, 0x75, 0xbd, 0xb3, 0xab, 0x26, 0xd1, 0x53, 0x96, 0x7c, 0x52, 0x0f, 0x61, - 0x0e, 0x13, 0x29, 0x37, 0xb7, 0xa3, 0xec, 0x65, 0xca, 0xdf, 0x18, 0x86, 0x97, 0xd9, 0x76, 0x1a, - 0xfc, 0xe8, 0x02, 0x12, 0x38, 0xa9, 0x56, 0xa7, 0xd6, 0xa5, 0xd0, 0x2d, 0x29, 0x9c, 0x84, 0x14, - 0x54, 0x6f, 0x03, 0x52, 0xbc, 0x63, 0xb8, 0x9e, 0x4d, 0x3a, 0xb9, 0x79, 0x61, 0x12, 0xef, 0x9c, - 0x04, 0xcb, 0x42, 0x1e, 0x3e, 0x18, 0xe4, 0x9f, 0xc8, 0x81, 0x7f, 0x55, 0x60, 0xa5, 0xca, 0x9c, - 0x1f, 0x5f, 0xb8, 0x9c, 0xd4, 0x5d, 0xc6, 0x3f, 0xd3, 0x2b, 0xe5, 0x83, 0x11, 0xde, 0xbb, 0x03, - 0x8b, 0xc4, 0xb7, 0xca, 0x07, 0x86, 0x29, 0x22, 0x21, 0x23, 0xb6, 0x80, 0xc4, 0x30, 0xda, 0xdd, - 0x2e, 0x9e, 0xed, 0x75, 0xb1, 0x0a, 0x09, 0xcf, 0x6c, 0x08, 0x27, 0xa6, 0x75, 0x7c, 0x56, 0xd7, - 0x20, 0xc9, 0xae, 0x1a, 0x35, 0x5a, 0x47, 0xd7, 0xa4, 0x75, 0xb9, 0x52, 0x35, 0x48, 0xd9, 0xc4, - 0x72, 0x1b, 0x66, 0x9d, 0xa1, 0xcd, 0x8b, 0x7a, 0xb4, 0x56, 0x37, 0x21, 0xed, 0x98, 0x4c, 0x9c, - 0x34, 0x69, 0x73, 0xca, 0x31, 0xd9, 0xe3, 0x60, 0x5d, 0x30, 0x60, 0xa3, 0xcf, 0xa6, 0xd0, 0xe2, - 0xc0, 0x82, 0xe7, 0x3d, 0x16, 0x08, 0x0b, 0x17, 0x9e, 0x77, 0x5b, 0xb0, 0x05, 0x60, 0x59, 0x91, - 0x4f, 0x65, 0x56, 0x06, 0x14, 0xe1, 0xd5, 0x7f, 0x2b, 0x70, 0x4b, 0xb8, 0xf5, 0x69, 0x8b, 0xdf, - 0x3c, 0xef, 0x56, 0x61, 0xce, 0xa3, 0x9e, 0x45, 0xd0, 0x59, 0x09, 0x5d, 0x2c, 0xba, 0xb3, 0x31, - 0xd1, 0x93, 0x8d, 0x5f, 0x4f, 0x26, 0xfd, 0x00, 0xb6, 0x06, 0x9a, 0x1c, 0x39, 0x76, 0x0b, 0xc0, - 0x65, 0x86, 0x4f, 0x1a, 0xb4, 0x4d, 0x6c, 0xb4, 0x3e, 0xa5, 0xa7, 0x5d, 0xa6, 0x0b, 0x42, 0x81, - 0x40, 0xae, 0xca, 0x1c, 0xb1, 0xfa, 0xff, 0x79, 0xad, 0x50, 0x80, 0x9d, 0x61, 0xdb, 0x44, 0x49, - 0xff, 0x67, 0x05, 0x96, 0xaa, 0xcc, 0xf9, 0x92, 0x72, 0x72, 0x6c, 0xb2, 0x53, 0xdf, 0xb5, 0xc8, - 0xd4, 0x2a, 0x34, 0x03, 0x74, 0xa8, 0x02, 0x2e, 0xd4, 0xdb, 0xb0, 0xd0, 0xf4, 0x5d, 0xea, 0xbb, - 0xfc, 0xca, 0x38, 0x27, 0x04, 0xbd, 0x9c, 0xd0, 0x33, 0x21, 0xed, 0x11, 0x41, 0x16, 0x11, 0x06, - 0xaf, 0xd5, 0xa8, 0x11, 0x1f, 0x03, 0x9c, 0xd0, 0x33, 0x48, 0x7b, 0x82, 0xa4, 0x1f, 0x25, 0x52, - 0x73, 0xcb, 0xc9, 0xc2, 0x06, 0xac, 0xc7, 0x34, 0x8d, 0xac, 0xf8, 0x53, 0x32, 0xb2, 0x22, 0x34, - 0x74, 0x84, 0x15, 0x9b, 0x80, 0xf9, 0x2b, 0xe2, 0x2e, 0x12, 0x3a, 0x15, 0x10, 0x30, 0xec, 0x1f, - 0xc2, 0x1a, 0xad, 0x31, 0xe2, 0xb7, 0x89, 0x6d, 0x50, 0x29, 0xab, 0xfb, 0x1e, 0x5c, 0x0d, 0xdf, - 0x86, 0x1b, 0x21, 0xaa, 0x02, 0xf9, 0x7e, 0x94, 0xcc, 0x2e, 0xe2, 0x3a, 0x17, 0x5c, 0x9a, 0xb5, - 0x19, 0x47, 0x1f, 0x61, 0xbe, 0x21, 0x8b, 0xfa, 0x31, 0x68, 0xfd, 0x42, 0x82, 0xa3, 0xdd, 0x62, - 0xc4, 0xce, 0x01, 0x0a, 0x58, 0x8f, 0x0b, 0x38, 0x36, 0xd9, 0x33, 0x46, 0x6c, 0xf5, 0x97, 0x0a, - 0xdc, 0xed, 0x47, 0x93, 0xf3, 0x73, 0x62, 0x71, 0xb7, 0x4d, 0x50, 0x8e, 0x08, 0x50, 0x06, 0x8b, - 0x5e, 0x51, 0x16, 0xbd, 0xdd, 0x09, 0x8a, 0xde, 0x89, 0xc7, 0xf5, 0xdb, 0xf1, 0x8d, 0x3f, 0x0b, - 0x45, 0x47, 0x79, 0x73, 0x3a, 0x5e, 0x03, 0x71, 0x49, 0x2d, 0xa0, 0x29, 0x23, 0x25, 0xe2, 0xed, - 0xa5, 0x52, 0xc8, 0xb6, 0xcd, 0x7a, 0x8b, 0x18, 0x3e, 0xb1, 0x88, 0x1b, 0x9c, 0x25, 0xbc, 0x16, - 0x8f, 0x3e, 0xbf, 0x66, 0xc5, 0xfe, 0xcf, 0xeb, 0xed, 0x5b, 0x57, 0x66, 0xa3, 0x7e, 0x58, 0xe8, - 0x15, 0x57, 0xd0, 0x17, 0x91, 0xa0, 0xcb, 0xb5, 0xfa, 0x29, 0x24, 0x19, 0x37, 0x79, 0x4b, 0xdc, - 0xb2, 0xd9, 0xf2, 0xbd, 0xa1, 0xa5, 0x4d, 0x34, 0x57, 0x12, 0xf8, 0x05, 0x62, 0x74, 0x89, 0x55, - 0xef, 0x42, 0x36, 0xb2, 0x1f, 0x19, 0xe5, 0x05, 0xb2, 0x18, 0x52, 0x2b, 0x01, 0x51, 0xbd, 0x07, - 0x6a, 0xc4, 0x16, 0x14, 0x7e, 0x71, 0x84, 0x53, 0xe8, 0x9c, 0xe5, 0xf0, 0xcd, 0x19, 0x63, 0x4f, - 0xf0, 0x0e, 0xec, 0x29, 0xbc, 0xe9, 0xa9, 0x0a, 0x6f, 0xd7, 0x11, 0x0a, 0x7d, 0x1e, 0x1d, 0xa1, - 0x7f, 0xce, 0x41, 0x56, 0xbe, 0x93, 0xf5, 0x71, 0xc4, 0x09, 0x0a, 0xca, 0x14, 0xf1, 0x6c, 0xe2, - 0xcb, 0xe3, 0x23, 0x57, 0xea, 0x2e, 0x2c, 0x89, 0x27, 0x23, 0x56, 0xf4, 0x16, 0x05, 0xb9, 0x22, - 0x2f, 0x0b, 0x0d, 0x52, 0x32, 0x04, 0xbe, 0xbc, 0xd0, 0xa3, 0x75, 0xe0, 0xbc, 0xf0, 0x59, 0x3a, - 0x6f, 0x4e, 0x88, 0x08, 0xa9, 0xc2, 0x79, 0xef, 0x9a, 0xb8, 0xe4, 0x8d, 0x9a, 0xb8, 0xc0, 0xca, - 0x06, 0x61, 0xcc, 0x74, 0x84, 0xeb, 0xd3, 0x7a, 0xb8, 0x0c, 0x6e, 0x26, 0xd7, 0xeb, 0xba, 0x00, - 0xd2, 0xf8, 0x3a, 0x23, 0x69, 0x78, 0xee, 0x0f, 0x60, 0x35, 0x64, 0xe9, 0x39, 0xed, 0xe2, 0xb0, - 0xaa, 0xf2, 0x5d, 0xf7, 0x21, 0xef, 0xa9, 0xd6, 0x19, 0x64, 0x8b, 0xaa, 0x75, 0x6f, 0x8c, 0x17, - 0xa6, 0x6b, 0xae, 0x36, 0x21, 0xcd, 0x3b, 0x06, 0xf5, 0x5d, 0xc7, 0xf5, 0x72, 0x8b, 0xc2, 0xb9, - 0xbc, 0xf3, 0x14, 0xd7, 0xc1, 0x2d, 0x6d, 0x32, 0x46, 0x78, 0x2e, 0x8b, 0x2f, 0xc4, 0x42, 0xdd, - 0x86, 0x0c, 0x69, 0x13, 0x8f, 0xcb, 0x6a, 0xb7, 0x84, 0x5a, 0x01, 0x92, 0xb0, 0xe0, 0xa9, 0x3e, - 0x6c, 0x60, 0x1b, 0x6e, 0xd1, 0xba, 0x61, 0x51, 0x8f, 0xfb, 0xa6, 0xc5, 0x8d, 0x36, 0xf1, 0x99, - 0x4b, 0xbd, 0xdc, 0x32, 0xea, 0xf9, 0xa0, 0x38, 0x72, 0x84, 0x09, 0x4a, 0x2f, 0xe2, 0x2b, 0x12, - 0xfe, 0xa5, 0x40, 0xeb, 0xeb, 0xcd, 0xc1, 0x2f, 0xd4, 0x9f, 0x06, 0x79, 0xd0, 0x26, 0x3e, 0x37, - 0x68, 0x93, 0xbb, 0xd4, 0x63, 0xb9, 0x15, 0xac, 0xf1, 0xf7, 0xc6, 0x6c, 0xa4, 0x23, 0xe8, 0xa9, - 0xc0, 0x1c, 0x25, 0x82, 0xb4, 0x08, 0x72, 0xa7, 0x8b, 0x58, 0xc8, 0xc1, 0x5a, 0x6f, 0xaa, 0x47, - 0xa7, 0xe0, 0x31, 0xb6, 0x80, 0x0f, 0x6b, 0xd4, 0xe7, 0x5f, 0xf0, 0x96, 0x75, 0x59, 0xa9, 0x9c, - 0xfd, 0x64, 0x74, 0xc7, 0x3e, 0xaa, 0x37, 0xda, 0xc4, 0xe6, 0xab, 0x57, 0x5a, 0xb4, 0x55, 0x1b, - 0xdb, 0x75, 0x9d, 0x9c, 0xb7, 0x3c, 0x1b, 0x59, 0x88, 0x7d, 0xa3, 0xdd, 0xc4, 0xc1, 0x09, 0xa4, - 0x45, 0xed, 0x9c, 0xa8, 0x58, 0x8b, 0x82, 0x2a, 0xfb, 0x39, 0xd9, 0x06, 0xf7, 0xed, 0x1b, 0xe9, - 0xf5, 0x42, 0x41, 0xad, 0xc5, 0x9c, 0xa1, 0x9b, 0x9c, 0x3c, 0x16, 0x23, 0xdc, 0xa3, 0x60, 0x82, - 0x1b, 0xa1, 0x9d, 0x05, 0x6a, 0xff, 0xc4, 0x87, 0x5a, 0x66, 0xca, 0xa5, 0x71, 0x31, 0x8b, 0x6d, - 0x23, 0xc3, 0xb6, 0xec, 0xc7, 0xe8, 0x85, 0x3b, 0x70, 0x7b, 0xa8, 0x6e, 0x91, 0x05, 0xff, 0x52, - 0x70, 0x52, 0x92, 0x73, 0x19, 0xb6, 0xbc, 0x95, 0x16, 0xe3, 0xd4, 0xbe, 0xba, 0xc1, 0xd0, 0x58, - 0x84, 0xf7, 0x3d, 0xf2, 0x95, 0x61, 0x09, 0x41, 0x31, 0x17, 0xaf, 0x78, 0xe4, 0x2b, 0xb9, 0x45, - 0xd8, 0x36, 0xf7, 0x4d, 0x07, 0x89, 0x01, 0xd3, 0xc1, 0xbb, 0x4b, 0x6c, 0xee, 0x66, 0x93, 0xe8, - 0xa7, 0x70, 0x67, 0x84, 0xc5, 0xdd, 0x7d, 0x69, 0x57, 0x06, 0x29, 0xf1, 0x7c, 0x6d, 0x60, 0xc3, - 0x28, 0xbc, 0xdb, 0x2d, 0xe4, 0xd4, 0x6c, 0x31, 0x59, 0xe3, 0xa6, 0x6f, 0x0e, 0x03, 0x19, 0xe8, - 0xae, 0x94, 0x2e, 0x16, 0x85, 0x13, 0xd8, 0x1b, 0xb7, 0xdd, 0x84, 0x9a, 0x97, 0xff, 0x9b, 0x85, - 0xd9, 0x2a, 0x73, 0xd4, 0xdf, 0x28, 0xa0, 0x0e, 0x18, 0x45, 0x3e, 0x1c, 0x93, 0x7f, 0x03, 0xbb, - 0x79, 0xed, 0xfb, 0xd3, 0xa0, 0x22, 0x8d, 0x7f, 0xad, 0xc0, 0x4a, 0xff, 0x30, 0x7e, 0x7f, 0x22, - 0x99, 0xbd, 0x20, 0xed, 0xe3, 0x29, 0x40, 0x91, 0x1e, 0xbf, 0x53, 0xe0, 0xd6, 0xe0, 0x51, 0xe3, - 0xbb, 0xe3, 0xc5, 0x0e, 0x04, 0x6a, 0x9f, 0x4c, 0x09, 0x8c, 0x74, 0x6a, 0xc3, 0x42, 0xcf, 0xc4, - 0x51, 0x1c, 0x2f, 0xb0, 0x9b, 0x5f, 0x7b, 0x70, 0x3d, 0xfe, 0xf8, 0xbe, 0xd1, 0x8c, 0x30, 0xe1, - 0xbe, 0x21, 0xff, 0xa4, 0xfb, 0xc6, 0x9b, 0x2b, 0x95, 0x41, 0xa6, 0xbb, 0xb1, 0xda, 0x9f, 0x4c, - 0x8c, 0x64, 0xd7, 0xbe, 0x73, 0x2d, 0xf6, 0x68, 0xd3, 0x9f, 0x43, 0x36, 0xf6, 0x2d, 0xe3, 0x60, - 0xbc, 0xa0, 0x5e, 0x84, 0xf6, 0xd1, 0x75, 0x11, 0xd1, 0xee, 0xbf, 0x52, 0x60, 0xb9, 0xef, 0xdb, - 0x57, 0x79, 0xbc, 0xb8, 0x38, 0x46, 0x3b, 0xbc, 0x3e, 0x26, 0x52, 0xe2, 0x17, 0xb0, 0x14, 0xff, - 0x62, 0xf8, 0xed, 0xf1, 0xe2, 0x62, 0x10, 0xed, 0x7b, 0xd7, 0x86, 0x74, 0xc7, 0x20, 0xd6, 0x4c, - 0x4c, 0x10, 0x83, 0x5e, 0xc4, 0x24, 0x31, 0x18, 0xdc, 0x62, 0xe0, 0x15, 0xd4, 0xdf, 0x60, 0xdc, - 0x9f, 0xe4, 0xf4, 0xc6, 0x40, 0x93, 0x5c, 0x41, 0x43, 0x5b, 0x0a, 0xf5, 0x0f, 0x0a, 0xac, 0x0d, - 0xe9, 0x27, 0x3e, 0x9a, 0x34, 0xba, 0x71, 0xa4, 0xf6, 0xc3, 0x69, 0x91, 0x91, 0x5a, 0x2f, 0x14, - 0xc8, 0x0d, 0x6d, 0x12, 0x0e, 0x27, 0x0e, 0x7a, 0x1f, 0x56, 0x3b, 0x9a, 0x1e, 0x1b, 0x29, 0xf7, - 0x17, 0x05, 0xb6, 0x46, 0x57, 0xe2, 0x4f, 0x26, 0x75, 0xc0, 0x10, 0x01, 0xda, 0xf1, 0x0d, 0x05, - 0x84, 0xba, 0x1e, 0x1d, 0xbf, 0x7c, 0x93, 0x57, 0x5e, 0xbd, 0xc9, 0x2b, 0xff, 0x78, 0x93, 0x57, - 0x7e, 0xfb, 0x36, 0x3f, 0xf3, 0xea, 0x6d, 0x7e, 0xe6, 0x6f, 0x6f, 0xf3, 0x33, 0x3f, 0xdb, 0xef, - 0x6a, 0x64, 0x82, 0x2d, 0xf6, 0xc5, 0x27, 0x7e, 0x8f, 0xda, 0xa4, 0xd4, 0xe9, 0xf9, 0x4f, 0x48, - 0xd0, 0xd3, 0xd4, 0x92, 0x38, 0x0c, 0xdc, 0xff, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9e, 0x52, - 0x23, 0x18, 0x37, 0x19, 0x00, 0x00, + // 1807 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0x4f, 0x6f, 0x23, 0x49, + 0x15, 0x4f, 0x6f, 0x1c, 0xc7, 0x7e, 0x4e, 0x9c, 0xa4, 0x37, 0x93, 0x38, 0x9d, 0x8d, 0x93, 0xf1, + 0x30, 0x21, 0x5a, 0x4d, 0xec, 0xe0, 0x59, 0x86, 0x25, 0x8b, 0x58, 0x26, 0xde, 0x9d, 0x6c, 0xd0, + 0x78, 0x26, 0xea, 0xcd, 0x2c, 0x7f, 0x2e, 0xad, 0x76, 0x77, 0xa5, 0xd3, 0x8a, 0xdd, 0x65, 0x75, + 0x95, 0xbd, 0xce, 0x08, 0x09, 0x84, 0x84, 0xc4, 0x11, 0x10, 0xa7, 0x3d, 0x70, 0x43, 0x82, 0x6f, + 0xc0, 0x47, 0xd8, 0xe3, 0x88, 0x13, 0xe2, 0x30, 0x42, 0x33, 0x5f, 0x00, 0xb8, 0x72, 0x41, 0xfd, + 0xaa, 0xba, 0x63, 0xb7, 0xff, 0xc6, 0x11, 0xe2, 0x92, 0xee, 0x7a, 0xfd, 0x7e, 0xef, 0x5f, 0xbd, + 0xaa, 0xf7, 0x9e, 0x03, 0xbb, 0x2f, 0x09, 0x37, 0xad, 0x0b, 0xd3, 0xf5, 0x4a, 0xf8, 0x46, 0x7d, + 0x52, 0xb2, 0x7c, 0xca, 0x98, 0xa0, 0xf1, 0x4e, 0xb1, 0xe9, 0x53, 0x4e, 0xd5, 0xad, 0x88, 0xaf, + 0x18, 0xf2, 0x15, 0xaf, 0xf9, 0xb4, 0x55, 0x87, 0x3a, 0x14, 0x39, 0x4b, 0xc1, 0x9b, 0x00, 0x69, + 0xef, 0x0f, 0x10, 0xde, 0xbc, 0x74, 0x4a, 0x48, 0x62, 0xf2, 0x21, 0x79, 0x77, 0x87, 0xf1, 0x52, + 0xd7, 0xc3, 0x3f, 0x63, 0x64, 0x36, 0x7d, 0x4a, 0xcf, 0x99, 0x7c, 0x48, 0xde, 0x47, 0xa3, 0x9d, + 0xf3, 0x4d, 0x4e, 0x8c, 0xba, 0xdb, 0x70, 0x39, 0xf1, 0x8d, 0xf3, 0xba, 0xe9, 0x84, 0xb8, 0xf2, + 0x68, 0x1c, 0xbe, 0x1a, 0xf8, 0x6e, 0x84, 0x01, 0x2a, 0xfc, 0x4e, 0x01, 0xb5, 0xca, 0x9c, 0xaa, + 0xeb, 0x04, 0x62, 0xcf, 0x18, 0x7b, 0xd2, 0xf2, 0x6c, 0xa6, 0xe6, 0x60, 0xde, 0xf2, 0x89, 0xc9, + 0xa9, 0x9f, 0x53, 0x76, 0x94, 0xbd, 0xb4, 0x1e, 0x2e, 0xd5, 0x0d, 0x48, 0x09, 0x11, 0xae, 0x9d, + 0x7b, 0x67, 0x47, 0xd9, 0x9b, 0xd5, 0xe7, 0x71, 0x7d, 0x62, 0xab, 0xc7, 0x90, 0x34, 0x1b, 0xb4, + 0xe5, 0xf1, 0xdc, 0x6c, 0x80, 0x39, 0x2a, 0x7d, 0xfd, 0x7a, 0x7b, 0xe6, 0xef, 0xaf, 0xb7, 0xbf, + 0xe9, 0xb8, 0xfc, 0xa2, 0x55, 0x2b, 0x5a, 0xb4, 0x51, 0xb2, 0x28, 0x6b, 0x50, 0x26, 0x1f, 0xfb, + 0xcc, 0xbe, 0x2c, 0xf1, 0xab, 0x26, 0x61, 0xc5, 0x17, 0xae, 0xc7, 0x75, 0x09, 0x2f, 0xbc, 0x07, + 0x5a, 0xbf, 0x4d, 0x3a, 0x61, 0x4d, 0xea, 0x31, 0x52, 0x78, 0x06, 0xef, 0x56, 0x99, 0xf3, 0xa2, + 0x69, 0x8b, 0x8f, 0x8f, 0x6d, 0xdb, 0x27, 0x6c, 0x94, 0xc9, 0x5b, 0x00, 0x9c, 0x31, 0xa3, 0xd9, + 0xaa, 0x5d, 0x92, 0x2b, 0x34, 0x3a, 0xad, 0xa7, 0x39, 0x63, 0xa7, 0x48, 0x28, 0x6c, 0xc1, 0xe6, + 0x00, 0x79, 0x91, 0xba, 0x3f, 0xbc, 0x03, 0xab, 0x55, 0xe6, 0x3c, 0xb6, 0xed, 0x13, 0xaf, 0x46, + 0x5b, 0x9e, 0x7d, 0xe6, 0x9b, 0xd6, 0x25, 0xf1, 0xa7, 0x8b, 0xd1, 0x3a, 0xcc, 0xf3, 0x8e, 0x71, + 0x61, 0xb2, 0x0b, 0x11, 0x24, 0x3d, 0xc9, 0x3b, 0x9f, 0x99, 0xec, 0x42, 0x3d, 0x82, 0x74, 0x90, + 0x2e, 0x46, 0x10, 0x8e, 0x5c, 0x62, 0x47, 0xd9, 0xcb, 0x96, 0xef, 0x17, 0x07, 0x64, 0x6f, 0xf3, + 0xd2, 0x29, 0x62, 0x5e, 0x55, 0xa8, 0xeb, 0x9d, 0x5d, 0x35, 0x89, 0x9e, 0xb2, 0xe4, 0x9b, 0x7a, + 0x08, 0x73, 0x98, 0x48, 0xb9, 0xb9, 0x1d, 0x65, 0x2f, 0x53, 0xfe, 0xc6, 0x30, 0xbc, 0xcc, 0xb6, + 0xd3, 0xe0, 0xa1, 0x0b, 0x48, 0x10, 0xa4, 0x5a, 0x9d, 0x5a, 0x97, 0xc2, 0xb6, 0xa4, 0x08, 0x12, + 0x52, 0xd0, 0xbc, 0x0d, 0x48, 0xf1, 0x8e, 0xe1, 0x7a, 0x36, 0xe9, 0xe4, 0xe6, 0x85, 0x4b, 0xbc, + 0x73, 0x12, 0x2c, 0x0b, 0x79, 0x78, 0x6f, 0x50, 0x7c, 0xa2, 0x00, 0xfe, 0x55, 0x81, 0x95, 0x2a, + 0x73, 0x7e, 0x74, 0xe1, 0x72, 0x52, 0x77, 0x19, 0xff, 0x54, 0xaf, 0x94, 0x0f, 0x46, 0x44, 0xef, + 0x1e, 0x2c, 0x12, 0xdf, 0x2a, 0x1f, 0x18, 0xa6, 0xd8, 0x09, 0xb9, 0x63, 0x0b, 0x48, 0x0c, 0x77, + 0xbb, 0x3b, 0xc4, 0xb3, 0xbd, 0x21, 0x56, 0x21, 0xe1, 0x99, 0x0d, 0x11, 0xc4, 0xb4, 0x8e, 0xef, + 0xea, 0x1a, 0x24, 0xd9, 0x55, 0xa3, 0x46, 0xeb, 0x18, 0x9a, 0xb4, 0x2e, 0x57, 0xaa, 0x06, 0x29, + 0x9b, 0x58, 0x6e, 0xc3, 0xac, 0x33, 0xf4, 0x79, 0x51, 0x8f, 0xd6, 0xea, 0x26, 0xa4, 0x1d, 0x93, + 0x89, 0x93, 0x26, 0x7d, 0x4e, 0x39, 0x26, 0x7b, 0x1a, 0xac, 0x0b, 0x06, 0x6c, 0xf4, 0xf9, 0x14, + 0x7a, 0x1c, 0x78, 0xf0, 0xb2, 0xc7, 0x03, 0xe1, 0xe1, 0xc2, 0xcb, 0x6e, 0x0f, 0xb6, 0x00, 0x2c, + 0x2b, 0x8a, 0xa9, 0xcc, 0xca, 0x80, 0x22, 0xa2, 0xfa, 0x2f, 0x05, 0xee, 0x88, 0xb0, 0x3e, 0x6f, + 0xf1, 0xdb, 0xe7, 0xdd, 0x2a, 0xcc, 0x79, 0xd4, 0xb3, 0x08, 0x06, 0x2b, 0xa1, 0x8b, 0x45, 0x77, + 0x36, 0x26, 0x7a, 0xb2, 0xf1, 0xff, 0x93, 0x49, 0xdf, 0x87, 0xad, 0x81, 0x2e, 0x47, 0x81, 0xdd, + 0x02, 0x70, 0x99, 0xe1, 0x93, 0x06, 0x6d, 0x13, 0x1b, 0xbd, 0x4f, 0xe9, 0x69, 0x97, 0xe9, 0x82, + 0x50, 0x20, 0x90, 0xab, 0x32, 0x47, 0xac, 0xfe, 0x77, 0x51, 0x2b, 0x14, 0x60, 0x67, 0x98, 0x9a, + 0x28, 0xe9, 0xff, 0xa4, 0xc0, 0x52, 0x95, 0x39, 0x5f, 0x50, 0x4e, 0x8e, 0x4d, 0x76, 0xea, 0xbb, + 0x16, 0x99, 0xda, 0x84, 0x66, 0x80, 0x0e, 0x4d, 0xc0, 0x85, 0x7a, 0x17, 0x16, 0x9a, 0xbe, 0x4b, + 0x7d, 0x97, 0x5f, 0x19, 0xe7, 0x84, 0x60, 0x94, 0x13, 0x7a, 0x26, 0xa4, 0x3d, 0x21, 0xc8, 0x22, + 0xb6, 0xc1, 0x6b, 0x35, 0x6a, 0xc4, 0xc7, 0x0d, 0x4e, 0xe8, 0x19, 0xa4, 0x3d, 0x43, 0xd2, 0x0f, + 0x13, 0xa9, 0xb9, 0xe5, 0x64, 0x61, 0x03, 0xd6, 0x63, 0x96, 0x46, 0x5e, 0xfc, 0x31, 0x19, 0x79, + 0x11, 0x3a, 0x3a, 0xc2, 0x8b, 0x4d, 0xc0, 0xfc, 0x15, 0xfb, 0x2e, 0x12, 0x3a, 0x15, 0x10, 0x70, + 0xdb, 0x3f, 0x80, 0x35, 0x5a, 0x63, 0xc4, 0x6f, 0x13, 0xdb, 0xa0, 0x52, 0x56, 0xf7, 0x3d, 0xb8, + 0x1a, 0x7e, 0x0d, 0x15, 0x21, 0xaa, 0x02, 0xf9, 0x7e, 0x94, 0xcc, 0x2e, 0xe2, 0x3a, 0x17, 0x5c, + 0xba, 0xb5, 0x19, 0x47, 0x1f, 0x61, 0xbe, 0x21, 0x8b, 0xfa, 0x11, 0x68, 0xfd, 0x42, 0x82, 0xa3, + 0xdd, 0x62, 0xc4, 0xce, 0x01, 0x0a, 0x58, 0x8f, 0x0b, 0x38, 0x36, 0xd9, 0x0b, 0x46, 0x6c, 0xf5, + 0x17, 0x0a, 0xdc, 0xef, 0x47, 0x93, 0xf3, 0x73, 0x62, 0x71, 0xb7, 0x4d, 0x50, 0x8e, 0xd8, 0xa0, + 0x0c, 0x16, 0xbd, 0xa2, 0x2c, 0x7a, 0xbb, 0x13, 0x14, 0xbd, 0x13, 0x8f, 0xeb, 0x77, 0xe3, 0x8a, + 0x3f, 0x0d, 0x45, 0x47, 0x79, 0x73, 0x3a, 0xde, 0x02, 0x71, 0x49, 0x2d, 0xa0, 0x2b, 0x23, 0x25, + 0xe2, 0xed, 0xa5, 0x52, 0xc8, 0xb6, 0xcd, 0x7a, 0x8b, 0x18, 0x3e, 0xb1, 0x88, 0x1b, 0x9c, 0x25, + 0xbc, 0x16, 0x8f, 0x3e, 0xbb, 0x61, 0xc5, 0xfe, 0xf7, 0xeb, 0xed, 0x3b, 0x57, 0x66, 0xa3, 0x7e, + 0x58, 0xe8, 0x15, 0x57, 0xd0, 0x17, 0x91, 0xa0, 0xcb, 0xb5, 0xfa, 0x09, 0x24, 0x19, 0x37, 0x79, + 0x4b, 0xdc, 0xb2, 0xd9, 0xf2, 0x83, 0xa1, 0xa5, 0x4d, 0x34, 0x57, 0x12, 0xf8, 0x39, 0x62, 0x74, + 0x89, 0x55, 0xef, 0x43, 0x36, 0xf2, 0x1f, 0x19, 0xe5, 0x05, 0xb2, 0x18, 0x52, 0x2b, 0x01, 0x51, + 0x7d, 0x00, 0x6a, 0xc4, 0x16, 0x14, 0x7e, 0x71, 0x84, 0x53, 0x18, 0x9c, 0xe5, 0xf0, 0xcb, 0x19, + 0x63, 0xcf, 0xf0, 0x0e, 0xec, 0x29, 0xbc, 0xe9, 0xa9, 0x0a, 0x6f, 0xd7, 0x11, 0x0a, 0x63, 0x1e, + 0x1d, 0xa1, 0xbf, 0x24, 0x21, 0x2b, 0xbf, 0xc9, 0xfa, 0x38, 0xe2, 0x04, 0x05, 0x65, 0x8a, 0x78, + 0x36, 0xf1, 0xe5, 0xf1, 0x91, 0x2b, 0x75, 0x17, 0x96, 0xc4, 0x9b, 0x11, 0x2b, 0x7a, 0x8b, 0x82, + 0x5c, 0x91, 0x97, 0x85, 0x06, 0x29, 0xb9, 0x05, 0xbe, 0xbc, 0xd0, 0xa3, 0x75, 0x10, 0xbc, 0xf0, + 0x5d, 0x06, 0x6f, 0x4e, 0x88, 0x08, 0xa9, 0x22, 0x78, 0xd7, 0x4d, 0x5c, 0xf2, 0x56, 0x4d, 0x5c, + 0xe0, 0x65, 0x83, 0x30, 0x66, 0x3a, 0x22, 0xf4, 0x69, 0x3d, 0x5c, 0x06, 0x37, 0x93, 0xeb, 0x75, + 0x5d, 0x00, 0x69, 0xfc, 0x9c, 0x91, 0x34, 0x3c, 0xf7, 0x07, 0xb0, 0x1a, 0xb2, 0xf4, 0x9c, 0x76, + 0x71, 0x58, 0x55, 0xf9, 0xad, 0xfb, 0x90, 0xf7, 0x54, 0xeb, 0x0c, 0xb2, 0x45, 0xd5, 0xba, 0x77, + 0x8f, 0x17, 0xa6, 0x6b, 0xae, 0x36, 0x21, 0xcd, 0x3b, 0x06, 0xf5, 0x5d, 0xc7, 0xf5, 0x72, 0x8b, + 0x22, 0xb8, 0xbc, 0xf3, 0x1c, 0xd7, 0xc1, 0x2d, 0x6d, 0x32, 0x46, 0x78, 0x2e, 0x8b, 0x1f, 0xc4, + 0x42, 0xdd, 0x86, 0x0c, 0x69, 0x13, 0x8f, 0xcb, 0x6a, 0xb7, 0x84, 0x56, 0x01, 0x92, 0xb0, 0xe0, + 0xa9, 0x3e, 0x6c, 0x60, 0x1b, 0x6e, 0xd1, 0xba, 0x61, 0x51, 0x8f, 0xfb, 0xa6, 0xc5, 0x8d, 0x36, + 0xf1, 0x99, 0x4b, 0xbd, 0xdc, 0x32, 0xda, 0xf9, 0xa8, 0x38, 0x72, 0x84, 0x09, 0x4a, 0x2f, 0xe2, + 0x2b, 0x12, 0xfe, 0x85, 0x40, 0xeb, 0xeb, 0xcd, 0xc1, 0x1f, 0xd4, 0x9f, 0x04, 0x79, 0xd0, 0x26, + 0x3e, 0x37, 0x68, 0x93, 0xbb, 0xd4, 0x63, 0xb9, 0x15, 0xac, 0xf1, 0x0f, 0xc6, 0x28, 0xd2, 0x11, + 0xf4, 0x5c, 0x60, 0x8e, 0x12, 0x41, 0x5a, 0x04, 0xb9, 0xd3, 0x45, 0x54, 0xab, 0xb0, 0x60, 0x99, + 0xf5, 0x7a, 0x24, 0x58, 0x45, 0xc1, 0xef, 0x8f, 0x11, 0x5c, 0x31, 0xeb, 0x75, 0x29, 0x41, 0xcf, + 0x58, 0xd7, 0x8b, 0x42, 0x0e, 0xd6, 0x7a, 0x4f, 0x4e, 0x74, 0xa8, 0x9e, 0x62, 0x47, 0xf9, 0xb8, + 0x46, 0x7d, 0xfe, 0x39, 0x6f, 0x59, 0x97, 0x95, 0xca, 0xd9, 0x8f, 0x47, 0x0f, 0x00, 0xa3, 0x5a, + 0xad, 0x4d, 0xec, 0xe5, 0x7a, 0xa5, 0x45, 0xaa, 0xda, 0xd8, 0xfd, 0xeb, 0xe4, 0xbc, 0xe5, 0xd9, + 0xc8, 0x42, 0xec, 0x5b, 0x69, 0x13, 0xe7, 0x30, 0x90, 0x16, 0x75, 0x87, 0xa2, 0x00, 0x2e, 0x0a, + 0xaa, 0x6c, 0x0f, 0x65, 0x57, 0xdd, 0xa7, 0x37, 0xb2, 0xeb, 0x2b, 0x05, 0xad, 0x16, 0x63, 0x8b, + 0x6e, 0x72, 0xf2, 0x54, 0x4c, 0x84, 0x4f, 0x82, 0x81, 0x70, 0x84, 0x75, 0x16, 0xa8, 0xfd, 0x03, + 0x24, 0x5a, 0x99, 0x29, 0x97, 0xc6, 0xa5, 0x40, 0x4c, 0x8d, 0xcc, 0x82, 0x65, 0x3f, 0x46, 0x2f, + 0xdc, 0x83, 0xbb, 0x43, 0x6d, 0x8b, 0x3c, 0xf8, 0xa7, 0x82, 0x83, 0x97, 0x1c, 0xf3, 0xb0, 0x83, + 0xae, 0xb4, 0x18, 0xa7, 0xf6, 0xd5, 0x2d, 0x66, 0xd0, 0x22, 0xbc, 0xeb, 0x91, 0x2f, 0x0d, 0x4b, + 0x08, 0x8a, 0x85, 0x78, 0xc5, 0x23, 0x5f, 0x4a, 0x15, 0x61, 0x17, 0xde, 0x37, 0x6c, 0x24, 0x06, + 0x0c, 0x1b, 0xd7, 0x77, 0xe2, 0xdc, 0xed, 0x06, 0xdb, 0x4f, 0xe0, 0xde, 0x08, 0x8f, 0xbb, 0xdb, + 0xdc, 0xae, 0x0c, 0x52, 0xe2, 0xf9, 0xda, 0xc0, 0xfe, 0x53, 0x44, 0xb7, 0x5b, 0xc8, 0xa9, 0xd9, + 0x62, 0xb2, 0x64, 0x4e, 0xdf, 0x6b, 0x06, 0x32, 0x30, 0x5c, 0x29, 0x5d, 0x2c, 0x0a, 0x27, 0xb0, + 0x37, 0x4e, 0xdd, 0x84, 0x96, 0x97, 0xff, 0x93, 0x85, 0xd9, 0x2a, 0x73, 0xd4, 0x5f, 0x2b, 0xa0, + 0x0e, 0x98, 0x6c, 0x3e, 0x18, 0x93, 0x7f, 0x03, 0x87, 0x03, 0xed, 0x7b, 0xd3, 0xa0, 0x22, 0x8b, + 0x7f, 0xa5, 0xc0, 0x4a, 0xff, 0x6c, 0xff, 0x70, 0x22, 0x99, 0xbd, 0x20, 0xed, 0xa3, 0x29, 0x40, + 0x91, 0x1d, 0xbf, 0x55, 0xe0, 0xce, 0xe0, 0xc9, 0xe5, 0x3b, 0xe3, 0xc5, 0x0e, 0x04, 0x6a, 0x1f, + 0x4f, 0x09, 0x8c, 0x6c, 0x6a, 0xc3, 0x42, 0xcf, 0x00, 0x53, 0x1c, 0x2f, 0xb0, 0x9b, 0x5f, 0x7b, + 0x74, 0x33, 0xfe, 0xb8, 0xde, 0x68, 0xe4, 0x98, 0x50, 0x6f, 0xc8, 0x3f, 0xa9, 0xde, 0x78, 0xaf, + 0xa6, 0x32, 0xc8, 0x74, 0xf7, 0x69, 0xfb, 0x93, 0x89, 0x91, 0xec, 0xda, 0xb7, 0x6f, 0xc4, 0x1e, + 0x29, 0xfd, 0x19, 0x64, 0x63, 0x3f, 0x8d, 0x1c, 0x8c, 0x17, 0xd4, 0x8b, 0xd0, 0x3e, 0xbc, 0x29, + 0x22, 0xd2, 0xfe, 0x4b, 0x05, 0x96, 0xfb, 0x7e, 0x4a, 0x2b, 0x8f, 0x17, 0x17, 0xc7, 0x68, 0x87, + 0x37, 0xc7, 0x44, 0x46, 0xfc, 0x1c, 0x96, 0xe2, 0x3f, 0x40, 0x7e, 0x6b, 0xbc, 0xb8, 0x18, 0x44, + 0xfb, 0xee, 0x8d, 0x21, 0xdd, 0x7b, 0x10, 0x6b, 0x26, 0x26, 0xd8, 0x83, 0x5e, 0xc4, 0x24, 0x7b, + 0x30, 0xb8, 0xc5, 0xc0, 0x2b, 0xa8, 0xbf, 0xc1, 0x78, 0x38, 0xc9, 0xe9, 0x8d, 0x81, 0x26, 0xb9, + 0x82, 0x86, 0xb6, 0x14, 0xea, 0xef, 0x15, 0x58, 0x1b, 0xd2, 0x4f, 0x7c, 0x38, 0xe9, 0xee, 0xc6, + 0x91, 0xda, 0x0f, 0xa6, 0x45, 0x46, 0x66, 0x7d, 0xa5, 0x40, 0x6e, 0x68, 0x93, 0x70, 0x38, 0xf1, + 0xa6, 0xf7, 0x61, 0xb5, 0xa3, 0xe9, 0xb1, 0x91, 0x71, 0x7f, 0x56, 0x60, 0x6b, 0x74, 0x25, 0xfe, + 0x78, 0xd2, 0x00, 0x0c, 0x11, 0xa0, 0x1d, 0xdf, 0x52, 0x40, 0x68, 0xeb, 0xd1, 0xf1, 0xd7, 0x6f, + 0xf2, 0xca, 0xab, 0x37, 0x79, 0xe5, 0x1f, 0x6f, 0xf2, 0xca, 0x6f, 0xde, 0xe6, 0x67, 0x5e, 0xbd, + 0xcd, 0xcf, 0xfc, 0xed, 0x6d, 0x7e, 0xe6, 0xa7, 0xfb, 0x5d, 0x8d, 0x4c, 0xa0, 0x62, 0x5f, 0xfc, + 0xc7, 0xc0, 0xa3, 0x36, 0x29, 0x75, 0x7a, 0xfe, 0xb1, 0x12, 0xf4, 0x34, 0xb5, 0x24, 0xce, 0x16, + 0x0f, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x68, 0xfd, 0xc9, 0x86, 0x19, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3076,6 +3086,20 @@ func (m *MsgVoteInbound) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.CallOptions != nil { + { + size, err := m.CallOptions.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x92 + } { size, err := m.RevertOptions.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -3944,6 +3968,10 @@ func (m *MsgVoteInbound) Size() (n int) { } l = m.RevertOptions.Size() n += 2 + l + sovTx(uint64(l)) + if m.CallOptions != nil { + l = m.CallOptions.Size() + n += 2 + l + sovTx(uint64(l)) + } return n } @@ -6637,6 +6665,42 @@ func (m *MsgVoteInbound) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 18: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CallOptions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.CallOptions == nil { + m.CallOptions = &CallOptions{} + } + if err := m.CallOptions.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/zetaclient/chains/bitcoin/signer/signer.go b/zetaclient/chains/bitcoin/signer/signer.go index 128b75b537..7e49d4d675 100644 --- a/zetaclient/chains/bitcoin/signer/signer.go +++ b/zetaclient/chains/bitcoin/signer/signer.go @@ -384,7 +384,7 @@ func (signer *Signer) TryProcessOutbound( } // get size limit and gas price - sizelimit := params.GasLimit + sizelimit := params.CallOptions.GasLimit gasprice, ok := new(big.Int).SetString(params.GasPrice, 10) if !ok || gasprice.Cmp(big.NewInt(0)) < 0 { logger.Error().Msgf("cannot convert gas price %s ", params.GasPrice) diff --git a/zetaclient/chains/evm/observer/v2_inbound.go b/zetaclient/chains/evm/observer/v2_inbound.go index 8259abf28b..246dda603a 100644 --- a/zetaclient/chains/evm/observer/v2_inbound.go +++ b/zetaclient/chains/evm/observer/v2_inbound.go @@ -191,6 +191,7 @@ func (ob *Observer) newDepositInboundVote(event *gatewayevm.GatewayEVMDeposited) event.Asset.Hex(), event.Raw.Index, types.ProtocolContractVersion_V2, + false, // currently not relevant since calls are not arbitrary types.WithEVMRevertOptions(event.RevertOptions), ) } @@ -325,6 +326,7 @@ func (ob *Observer) newCallInboundVote(event *gatewayevm.GatewayEVMCalled) types "", event.Raw.Index, types.ProtocolContractVersion_V2, + false, // currently not relevant since calls are not arbitrary types.WithEVMRevertOptions(event.RevertOptions), ) } diff --git a/zetaclient/chains/evm/signer/gas.go b/zetaclient/chains/evm/signer/gas.go index 932900f46c..540302b91c 100644 --- a/zetaclient/chains/evm/signer/gas.go +++ b/zetaclient/chains/evm/signer/gas.go @@ -64,20 +64,20 @@ func (g Gas) isLegacy() bool { func gasFromCCTX(cctx *types.CrossChainTx, logger zerolog.Logger) (Gas, error) { var ( params = cctx.GetCurrentOutboundParam() - limit = params.GasLimit + limit = params.CallOptions.GasLimit ) switch { case limit < minGasLimit: limit = minGasLimit logger.Warn(). - Uint64("cctx.initial_gas_limit", params.GasLimit). + Uint64("cctx.initial_gas_limit", params.CallOptions.GasLimit). Uint64("cctx.gas_limit", limit). Msgf("Gas limit is too low. Setting to the minimum (%d)", minGasLimit) case limit > maxGasLimit: limit = maxGasLimit logger.Warn(). - Uint64("cctx.initial_gas_limit", params.GasLimit). + Uint64("cctx.initial_gas_limit", params.CallOptions.GasLimit). Uint64("cctx.gas_limit", limit). Msgf("Gas limit is too high; Setting to the maximum (%d)", maxGasLimit) } diff --git a/zetaclient/chains/evm/signer/gas_test.go b/zetaclient/chains/evm/signer/gas_test.go index 5b75ad39bf..71bbf97b5d 100644 --- a/zetaclient/chains/evm/signer/gas_test.go +++ b/zetaclient/chains/evm/signer/gas_test.go @@ -14,7 +14,7 @@ func TestGasFromCCTX(t *testing.T) { makeCCTX := func(gasLimit uint64, price, priorityFee string) *types.CrossChainTx { cctx := getCCTX(t) - cctx.GetOutboundParams()[0].GasLimit = gasLimit + cctx.GetOutboundParams()[0].CallOptions.GasLimit = gasLimit cctx.GetOutboundParams()[0].GasPrice = price cctx.GetOutboundParams()[0].GasPriorityFee = priorityFee diff --git a/zetaclient/chains/evm/signer/outbound_data.go b/zetaclient/chains/evm/signer/outbound_data.go index 8315b89d94..0cc65c19e2 100644 --- a/zetaclient/chains/evm/signer/outbound_data.go +++ b/zetaclient/chains/evm/signer/outbound_data.go @@ -191,7 +191,7 @@ func getDestination(cctx *types.CrossChainTx, logger zerolog.Logger) (ethcommon. } func validateParams(params *types.OutboundParams) error { - if params == nil || params.GasLimit == 0 { + if params == nil || params.CallOptions.GasLimit == 0 { return errors.New("outboundParams is empty") } diff --git a/zetaclient/chains/evm/signer/v2_sign.go b/zetaclient/chains/evm/signer/v2_sign.go index 9a3bf3ba89..81702d2aba 100644 --- a/zetaclient/chains/evm/signer/v2_sign.go +++ b/zetaclient/chains/evm/signer/v2_sign.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" erc20custodyv2 "github.com/zeta-chain/protocol-contracts/v2/pkg/erc20custody.sol" @@ -16,15 +17,31 @@ import ( // function execute // address destination, // bytes calldata data -func (signer *Signer) signGatewayExecute(ctx context.Context, txData *OutboundData) (*ethtypes.Transaction, error) { +func (signer *Signer) signGatewayExecute( + ctx context.Context, + sender string, + txData *OutboundData, +) (*ethtypes.Transaction, error) { gatewayABI, err := gatewayevm.GatewayEVMMetaData.GetAbi() if err != nil { return nil, errors.Wrap(err, "unable to get GatewayEVMMetaData ABI") } - data, err := gatewayABI.Pack("execute", txData.to, txData.message) - if err != nil { - return nil, fmt.Errorf("execute pack error: %w", err) + var data []byte + + if txData.outboundParams.CallOptions.IsArbitraryCall { + data, err = gatewayABI.Pack("execute", txData.to, txData.message) + if err != nil { + return nil, fmt.Errorf("execute pack error: %w", err) + } + } else { + messageContext := gatewayevm.MessageContext{ + Sender: common.HexToAddress(sender), + } + data, err = gatewayABI.Pack("execute0", messageContext, txData.to, txData.message) + if err != nil { + return nil, fmt.Errorf("execute0 pack error: %w", err) + } } tx, _, _, err := signer.Sign( diff --git a/zetaclient/chains/evm/signer/v2_signer.go b/zetaclient/chains/evm/signer/v2_signer.go index 2de0ecc9d5..b3a06a19c2 100644 --- a/zetaclient/chains/evm/signer/v2_signer.go +++ b/zetaclient/chains/evm/signer/v2_signer.go @@ -27,7 +27,7 @@ func (signer *Signer) SignOutboundFromCCTXV2( case evm.OutboundTypeGasWithdrawAndCall, evm.OutboundTypeCall: // both gas withdraw and call and no-asset call uses gateway execute // no-asset call simply hash msg.value == 0 - return signer.signGatewayExecute(ctx, outboundData) + return signer.signGatewayExecute(ctx, cctx.InboundParams.Sender, outboundData) case evm.OutboundTypeGasWithdrawRevertAndCallOnRevert: return signer.signGatewayExecuteRevert(ctx, outboundData) case evm.OutboundTypeERC20WithdrawRevertAndCallOnRevert: diff --git a/zetaclient/testdata/cctx/chain_1337_cctx_14.go b/zetaclient/testdata/cctx/chain_1337_cctx_14.go index 634a0346a4..785c5496e9 100644 --- a/zetaclient/testdata/cctx/chain_1337_cctx_14.go +++ b/zetaclient/testdata/cctx/chain_1337_cctx_14.go @@ -30,11 +30,13 @@ var chain_1337_cctx_14 = &crosschaintypes.CrossChainTx{ }, OutboundParams: []*crosschaintypes.OutboundParams{ { - Receiver: "0xbff76e77d56b3c1202107f059425d56f0aef87ed", - ReceiverChainId: 1337, - Amount: sdkmath.NewUintFromString("7999999999995486459"), - TssNonce: 13, - GasLimit: 250000, + Receiver: "0xbff76e77d56b3c1202107f059425d56f0aef87ed", + ReceiverChainId: 1337, + Amount: sdkmath.NewUintFromString("7999999999995486459"), + TssNonce: 13, + CallOptions: &crosschaintypes.CallOptions{ + GasLimit: 250000, + }, GasPrice: "18", Hash: "0x19f99459da6cb08f917f9b0ee2dac94a7be328371dff788ad46e64a24e8c06c9", ObservedExternalHeight: 187, @@ -45,11 +47,13 @@ var chain_1337_cctx_14 = &crosschaintypes.CrossChainTx{ TxFinalizationStatus: crosschaintypes.TxFinalizationStatus_Executed, }, { - Receiver: "0xBFF76e77D56B3C1202107f059425D56f0AEF87Ed", - ReceiverChainId: 1337, - Amount: sdkmath.NewUintFromString("5999999999990972918"), - TssNonce: 14, - GasLimit: 250000, + Receiver: "0xBFF76e77D56B3C1202107f059425D56f0AEF87Ed", + ReceiverChainId: 1337, + Amount: sdkmath.NewUintFromString("5999999999990972918"), + TssNonce: 14, + CallOptions: &crosschaintypes.CallOptions{ + GasLimit: 250000, + }, GasPrice: "18", Hash: "0x1487e6a31dd430306667250b72bf15b8390b73108b69f3de5c1b2efe456036a7", BallotIndex: "0xc36c689fdaf09a9b80a614420cd4fea4fec15044790df60080cdefca0090a9dc", diff --git a/zetaclient/testdata/cctx/chain_1_cctx_6270.go b/zetaclient/testdata/cctx/chain_1_cctx_6270.go index 7692837803..fbfd4a8c0c 100644 --- a/zetaclient/testdata/cctx/chain_1_cctx_6270.go +++ b/zetaclient/testdata/cctx/chain_1_cctx_6270.go @@ -34,12 +34,14 @@ var chain_1_cctx_6270 = &crosschaintypes.CrossChainTx{ }, OutboundParams: []*crosschaintypes.OutboundParams{ { - Receiver: "0x18D0E2c38b4188D8Ae07008C3BeeB1c80748b41c", - ReceiverChainId: 1, - CoinType: coin.CoinType_Gas, - Amount: sdkmath.NewUint(9831832641427386), - TssNonce: 6270, - GasLimit: 21000, + Receiver: "0x18D0E2c38b4188D8Ae07008C3BeeB1c80748b41c", + ReceiverChainId: 1, + CoinType: coin.CoinType_Gas, + Amount: sdkmath.NewUint(9831832641427386), + TssNonce: 6270, + CallOptions: &crosschaintypes.CallOptions{ + GasLimit: 21000, + }, GasPrice: "69197693654", Hash: "0x20104d41e042db754cf7908c5441914e581b498eedbca40979c9853f4b7f8460", BallotIndex: "0x346a1d00a4d26a2065fe1dc7d5af59a49ad6a8af25853ae2ec976c07349f48c1", diff --git a/zetaclient/testdata/cctx/chain_1_cctx_7260.go b/zetaclient/testdata/cctx/chain_1_cctx_7260.go index 7704acf0f7..777645a4b1 100644 --- a/zetaclient/testdata/cctx/chain_1_cctx_7260.go +++ b/zetaclient/testdata/cctx/chain_1_cctx_7260.go @@ -34,12 +34,14 @@ var chain_1_cctx_7260 = &crosschaintypes.CrossChainTx{ }, OutboundParams: []*crosschaintypes.OutboundParams{ { - Receiver: "0x8E62e3e6FbFF3E21F725395416A20EA4E2DeF015", - ReceiverChainId: 1, - CoinType: coin.CoinType_Gas, - Amount: sdkmath.NewUint(42635427434588308), - TssNonce: 7260, - GasLimit: 21000, + Receiver: "0x8E62e3e6FbFF3E21F725395416A20EA4E2DeF015", + ReceiverChainId: 1, + CoinType: coin.CoinType_Gas, + Amount: sdkmath.NewUint(42635427434588308), + TssNonce: 7260, + CallOptions: &crosschaintypes.CallOptions{ + GasLimit: 21000, + }, GasPrice: "236882693686", Hash: "0xd13b593eb62b5500a00e288cc2fb2c8af1339025c0e6bc6183b8bef2ebbed0d3", BallotIndex: "0x96e2f6f6956a7617cce6385e42169621254172ec4ddb9d3b2d8740263861a456", diff --git a/zetaclient/testdata/cctx/chain_1_cctx_8014.go b/zetaclient/testdata/cctx/chain_1_cctx_8014.go index 2a4901d407..71f8912b81 100644 --- a/zetaclient/testdata/cctx/chain_1_cctx_8014.go +++ b/zetaclient/testdata/cctx/chain_1_cctx_8014.go @@ -34,12 +34,14 @@ var chain_1_cctx_8014 = &crosschaintypes.CrossChainTx{ }, OutboundParams: []*crosschaintypes.OutboundParams{ { - Receiver: "0x8d8D67A8B71c141492825CAE5112Ccd8581073f2", - ReceiverChainId: 1, - CoinType: coin.CoinType_ERC20, - Amount: sdkmath.NewUint(23726342442), - TssNonce: 8014, - GasLimit: 100000, + Receiver: "0x8d8D67A8B71c141492825CAE5112Ccd8581073f2", + ReceiverChainId: 1, + CoinType: coin.CoinType_ERC20, + Amount: sdkmath.NewUint(23726342442), + TssNonce: 8014, + CallOptions: &crosschaintypes.CallOptions{ + GasLimit: 100000, + }, GasPrice: "58619665744", Hash: "0xd2eba7ac3da1b62800165414ea4bcaf69a3b0fb9b13a0fc32f4be11bfef79146", BallotIndex: "0x4213f2c335758301b8bbb09d9891949ed6ffeea5dd95e5d9eaa8d410baaa0884", diff --git a/zetaclient/testdata/cctx/chain_1_cctx_9718.go b/zetaclient/testdata/cctx/chain_1_cctx_9718.go index 526518f445..eb68fcf58a 100644 --- a/zetaclient/testdata/cctx/chain_1_cctx_9718.go +++ b/zetaclient/testdata/cctx/chain_1_cctx_9718.go @@ -34,12 +34,14 @@ var chain_1_cctx_9718 = &crosschaintypes.CrossChainTx{ }, OutboundParams: []*crosschaintypes.OutboundParams{ { - Receiver: "0x30735c88fa430f11499b0edcfcc25246fb9182e3", - ReceiverChainId: 1, - CoinType: coin.CoinType_Zeta, - Amount: sdkmath.NewUint(474493998697236392), - TssNonce: 9718, - GasLimit: 90000, + Receiver: "0x30735c88fa430f11499b0edcfcc25246fb9182e3", + ReceiverChainId: 1, + CoinType: coin.CoinType_Zeta, + Amount: sdkmath.NewUint(474493998697236392), + TssNonce: 9718, + CallOptions: &crosschaintypes.CallOptions{ + GasLimit: 90000, + }, GasPrice: "112217884384", Hash: "0x81342051b8a85072d3e3771c1a57c7bdb5318e8caf37f5a687b7a91e50a7257f", BallotIndex: "0xff07eaa34ca02a08bca1558e5f6220cbfc734061f083622b24923e032f0c480f", diff --git a/zetaclient/testdata/cctx/chain_1_cctx_inbound_ERC20_0x4ea69a0e2ff36f7548ab75791c3b990e076e2a4bffeb616035b239b7d33843da.go b/zetaclient/testdata/cctx/chain_1_cctx_inbound_ERC20_0x4ea69a0e2ff36f7548ab75791c3b990e076e2a4bffeb616035b239b7d33843da.go index c59632355f..8fb1fb9cd9 100644 --- a/zetaclient/testdata/cctx/chain_1_cctx_inbound_ERC20_0x4ea69a0e2ff36f7548ab75791c3b990e076e2a4bffeb616035b239b7d33843da.go +++ b/zetaclient/testdata/cctx/chain_1_cctx_inbound_ERC20_0x4ea69a0e2ff36f7548ab75791c3b990e076e2a4bffeb616035b239b7d33843da.go @@ -28,18 +28,20 @@ var chain_1_cctx_inbound_ERC20_0x4ea69a0 = &crosschaintypes.CrossChainTx{ Amount: sdkmath.NewUintFromString("9992000000"), ObservedHash: "0x4ea69a0e2ff36f7548ab75791c3b990e076e2a4bffeb616035b239b7d33843da", ObservedExternalHeight: 19320188, - BallotIndex: "0xc3d0dab7b2a34e3bfa2430963ff776ef2357c41f3164a28ab5d6380d7a438938", + BallotIndex: "0x97101937e3927e124dffcaed1349af2599a8420ff34315288e96eac7f0033048", FinalizedZetaHeight: 1944675, TxFinalizationStatus: crosschaintypes.TxFinalizationStatus_Executed, }, OutboundParams: []*crosschaintypes.OutboundParams{ { - Receiver: "0x56bf8d4a6e7b59d2c0e40cba2409a4a30ab4fbe2", - ReceiverChainId: 7000, - CoinType: coin.CoinType_ERC20, - Amount: sdkmath.NewUintFromString("0"), - TssNonce: 0, - GasLimit: 1500000, + Receiver: "0x56bf8d4a6e7b59d2c0e40cba2409a4a30ab4fbe2", + ReceiverChainId: 7000, + CoinType: coin.CoinType_ERC20, + Amount: sdkmath.NewUintFromString("0"), + TssNonce: 0, + CallOptions: &crosschaintypes.CallOptions{ + GasLimit: 1500000, + }, GasPrice: "", Hash: "0xf63eaa3e01af477673aa9e86fb634df15d30a00734dab7450cb0fc28dbc9d11b", BallotIndex: "", diff --git a/zetaclient/testdata/cctx/chain_1_cctx_inbound_Gas_0xeaec67d5dd5d85f27b21bef83e01cbdf59154fd793ea7a22c297f7c3a722c532.go b/zetaclient/testdata/cctx/chain_1_cctx_inbound_Gas_0xeaec67d5dd5d85f27b21bef83e01cbdf59154fd793ea7a22c297f7c3a722c532.go index 673ff70433..53a736b228 100644 --- a/zetaclient/testdata/cctx/chain_1_cctx_inbound_Gas_0xeaec67d5dd5d85f27b21bef83e01cbdf59154fd793ea7a22c297f7c3a722c532.go +++ b/zetaclient/testdata/cctx/chain_1_cctx_inbound_Gas_0xeaec67d5dd5d85f27b21bef83e01cbdf59154fd793ea7a22c297f7c3a722c532.go @@ -28,18 +28,20 @@ var chain_1_cctx_inbound_Gas_0xeaec67d = &crosschaintypes.CrossChainTx{ Amount: sdkmath.NewUintFromString("4000000000000000"), ObservedHash: "0xeaec67d5dd5d85f27b21bef83e01cbdf59154fd793ea7a22c297f7c3a722c532", ObservedExternalHeight: 19330473, - BallotIndex: "0x79f6a3da92d085b2f3c682a2eb1606ef89e53a7db4fdbbb397b3e0f54884cfb0", + BallotIndex: "0xdb5daf6a8471bc5a8f17c7e717dc6532719a89f082bd80694aebd654b7069609", FinalizedZetaHeight: 1965579, TxFinalizationStatus: crosschaintypes.TxFinalizationStatus_Executed, }, OutboundParams: []*crosschaintypes.OutboundParams{ { - Receiver: "0xF829fa7069680b8C37A8086b37d4a24697E5003b", - ReceiverChainId: 7000, - CoinType: coin.CoinType_Gas, - Amount: sdkmath.NewUint(0), - TssNonce: 0, - GasLimit: 90000, + Receiver: "0xF829fa7069680b8C37A8086b37d4a24697E5003b", + ReceiverChainId: 7000, + CoinType: coin.CoinType_Gas, + Amount: sdkmath.NewUint(0), + TssNonce: 0, + CallOptions: &crosschaintypes.CallOptions{ + GasLimit: 90000, + }, GasPrice: "", Hash: "0x3b8c1dab5aa21ff90ddb569f2f962ff2d4aa8d914c9177900102e745955e6f35", BallotIndex: "", diff --git a/zetaclient/testdata/cctx/chain_1_cctx_inbound_Zeta_0xf3935200c80f98502d5edc7e871ffc40ca898e134525c42c2ae3cbc5725f9d76.go b/zetaclient/testdata/cctx/chain_1_cctx_inbound_Zeta_0xf3935200c80f98502d5edc7e871ffc40ca898e134525c42c2ae3cbc5725f9d76.go index 900fb63d24..7a39dcd3a7 100644 --- a/zetaclient/testdata/cctx/chain_1_cctx_inbound_Zeta_0xf3935200c80f98502d5edc7e871ffc40ca898e134525c42c2ae3cbc5725f9d76.go +++ b/zetaclient/testdata/cctx/chain_1_cctx_inbound_Zeta_0xf3935200c80f98502d5edc7e871ffc40ca898e134525c42c2ae3cbc5725f9d76.go @@ -28,18 +28,20 @@ var chain_1_cctx_inbound_Zeta_0xf393520 = &crosschaintypes.CrossChainTx{ Amount: sdkmath.NewUintFromString("20000000000000000000"), ObservedHash: "0xf3935200c80f98502d5edc7e871ffc40ca898e134525c42c2ae3cbc5725f9d76", ObservedExternalHeight: 19273702, - BallotIndex: "0xa4efd2d7293e1c2c557eb527c7ad7f2f8754cce413d3f72929a17e02b537b0af", + BallotIndex: "0x611f8fea15d26d318c06b04e41bcc16ef212048eddbbf62641c1e3e42b376009", FinalizedZetaHeight: 1851403, TxFinalizationStatus: crosschaintypes.TxFinalizationStatus_Executed, }, OutboundParams: []*crosschaintypes.OutboundParams{ { - Receiver: "0x2f993766e8e1ef9288b1f33f6aa244911a0a77a7", - ReceiverChainId: 7000, - CoinType: coin.CoinType_Zeta, - Amount: sdkmath.ZeroUint(), - TssNonce: 0, - GasLimit: 100000, + Receiver: "0x2f993766e8e1ef9288b1f33f6aa244911a0a77a7", + ReceiverChainId: 7000, + CoinType: coin.CoinType_Zeta, + Amount: sdkmath.ZeroUint(), + TssNonce: 0, + CallOptions: &crosschaintypes.CallOptions{ + GasLimit: 100000, + }, GasPrice: "", Hash: "0x947434364da7c74d7e896a389aa8cb3122faf24bbcba64b141cb5acd7838209c", BallotIndex: "", diff --git a/zetaclient/testdata/cctx/chain_56_cctx_68270.go b/zetaclient/testdata/cctx/chain_56_cctx_68270.go index c74daef92a..3693774c9b 100644 --- a/zetaclient/testdata/cctx/chain_56_cctx_68270.go +++ b/zetaclient/testdata/cctx/chain_56_cctx_68270.go @@ -34,12 +34,14 @@ var chain_56_cctx_68270 = &crosschaintypes.CrossChainTx{ }, OutboundParams: []*crosschaintypes.OutboundParams{ { - Receiver: "0xb0C04e07A301927672A8A7a874DB6930576C90B8", - ReceiverChainId: 56, - CoinType: coin.CoinType_Gas, - Amount: sdkmath.NewUint(657177295293237048), - TssNonce: 68270, - GasLimit: 21000, + Receiver: "0xb0C04e07A301927672A8A7a874DB6930576C90B8", + ReceiverChainId: 56, + CoinType: coin.CoinType_Gas, + Amount: sdkmath.NewUint(657177295293237048), + TssNonce: 68270, + CallOptions: &crosschaintypes.CallOptions{ + GasLimit: 21000, + }, GasPrice: "6000000000", Hash: "0xeb2b183ece6638688b9df9223180b13a67208cd744bbdadeab8de0482d7f4e3c", BallotIndex: "0xa4600c952934f797e162d637d70859a611757407908d96bc53e45a81c80b006b", diff --git a/zetaclient/testdata/cctx/chain_8332_cctx_148.go b/zetaclient/testdata/cctx/chain_8332_cctx_148.go index f69c76cf1e..7b084b9a28 100644 --- a/zetaclient/testdata/cctx/chain_8332_cctx_148.go +++ b/zetaclient/testdata/cctx/chain_8332_cctx_148.go @@ -34,12 +34,14 @@ var chain_8332_cctx_148 = &crosschaintypes.CrossChainTx{ }, OutboundParams: []*crosschaintypes.OutboundParams{ { - Receiver: "bc1qpsdlklfcmlcfgm77c43x65ddtrt7n0z57hsyjp", - ReceiverChainId: 8332, - CoinType: coin.CoinType_Gas, - Amount: sdkmath.NewUint(12000), - TssNonce: 148, - GasLimit: 254, + Receiver: "bc1qpsdlklfcmlcfgm77c43x65ddtrt7n0z57hsyjp", + ReceiverChainId: 8332, + CoinType: coin.CoinType_Gas, + Amount: sdkmath.NewUint(12000), + TssNonce: 148, + CallOptions: &crosschaintypes.CallOptions{ + GasLimit: 254, + }, GasPrice: "46", Hash: "030cd813443f7b70cc6d8a544d320c6d8465e4528fc0f3410b599dc0b26753a0", ObservedExternalHeight: 150, diff --git a/zetaclient/zetacore/constant.go b/zetaclient/zetacore/constant.go index a068db9a8b..1457dd0c58 100644 --- a/zetaclient/zetacore/constant.go +++ b/zetaclient/zetacore/constant.go @@ -19,7 +19,7 @@ const ( PostTSSGasLimit = 500_000 // PostVoteInboundExecutionGasLimit is the gas limit for voting on observed inbound tx and executing it - PostVoteInboundExecutionGasLimit = 6_500_000 + PostVoteInboundExecutionGasLimit = 7_000_000 // PostVoteInboundMessagePassingExecutionGasLimit is the gas limit for voting on, and executing ,observed inbound tx related to message passing (coin_type == zeta) PostVoteInboundMessagePassingExecutionGasLimit = 4_000_000 diff --git a/zetaclient/zetacore/tx.go b/zetaclient/zetacore/tx.go index 64379bad2a..bb7b106fd5 100644 --- a/zetaclient/zetacore/tx.go +++ b/zetaclient/zetacore/tx.go @@ -51,6 +51,7 @@ func GetInboundVoteMessage( asset, eventIndex, types.ProtocolContractVersion_V1, + false, // not relevant for v1 ) return msg } From 1af05a879c6a1d3030fead27f83139680642ae70 Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Fri, 27 Sep 2024 13:56:30 +0200 Subject: [PATCH 04/14] feat!: bank precompile (#2860) * feat: bank precompile * feat: add deposit * feat: extend deposit * PoC: spend amount on behalf of EOA * feat: expand deposit with transferFrom * use CallEVM instead on ZRC20 bindings * divide the contract into different files * initialize e2e testing * remove duplicated funding * add codecov * expand e2e * fix: wait for deposit tx to be mined * apply first round of reviews * cover al error types test * fixes using time.Since * Include CallContract interface * fix eth events in deposit precompile method * emit Deposit event * add withdraw function * finalize withdraw * pack event arguments generically * add high level event function * first round of review fixes * second round of reviews * create bank account when instantiating bank * e2e: add good and bad scenarios * modify fmt * chore: group input into eventData struct * docs: document bank's methods * chore: generate files with suffix .gen.go * chore: assert errors with errorIs * chore: reset e2e test by resetting allowance * test: add first batch of unit test * test: cover all cases * test: complete unit test cases * include review suggestions * include e2e through contract * test: add e2e through contract complete * test: revert balance between tests * Update precompiles/bank/const.go Co-authored-by: Lucas Bertrand * fix: changed coin denom --------- Co-authored-by: skosito Co-authored-by: Lucas Bertrand --- Dockerfile-localnet | 4 +- app/app.go | 1 + changelog.md | 1 + cmd/zetae2e/local/local.go | 3 + cmd/zetae2e/local/precompiles.go | 4 + codecov.yml | 3 +- .../localnet/orchestrator/start-zetae2e.sh | 12 +- e2e/contracts/testbank/TestBank.abi | 87 +++ e2e/contracts/testbank/TestBank.bin | 1 + e2e/contracts/testbank/TestBank.go | 318 ++++++++ e2e/contracts/testbank/TestBank.json | 90 +++ e2e/contracts/testbank/TestBank.sol | 61 ++ e2e/contracts/testbank/bindings.go | 8 + e2e/e2etests/e2etests.go | 21 + e2e/e2etests/test_precompiles_bank.go | 203 +++++ .../test_precompiles_bank_through_contract.go | 186 +++++ e2e/e2etests/test_rate_limiter.go | 4 +- e2e/e2etests/test_stress_btc_deposit.go | 2 +- e2e/e2etests/test_stress_btc_withdraw.go | 2 +- e2e/e2etests/test_stress_eth_deposit.go | 2 +- e2e/e2etests/test_stress_eth_withdraw.go | 2 +- e2e/utils/require.go | 4 + precompiles/bank/IBank.abi | 148 ++++ precompiles/bank/IBank.gen.go | 582 ++++++++++++++ precompiles/bank/IBank.json | 150 ++++ precompiles/bank/IBank.sol | 71 ++ precompiles/bank/bank.go | 216 ++++++ precompiles/bank/bank_test.go | 156 ++++ precompiles/bank/bindings.go | 7 + precompiles/bank/coin.go | 43 ++ precompiles/bank/coin_test.go | 29 + precompiles/bank/const.go | 22 + precompiles/bank/logs.go | 50 ++ precompiles/bank/method_balance_of.go | 80 ++ precompiles/bank/method_deposit.go | 215 ++++++ precompiles/bank/method_test.go | 730 ++++++++++++++++++ precompiles/bank/method_withdraw.go | 198 +++++ precompiles/logs/logs.go | 38 +- precompiles/precompiles.go | 13 + precompiles/precompiles_test.go | 2 +- .../{IPrototype.go => IPrototype.gen.go} | 0 precompiles/prototype/bindings.go | 2 +- .../staking/{IStaking.go => IStaking.gen.go} | 0 precompiles/staking/bindings.go | 2 +- precompiles/staking/logs.go | 12 +- precompiles/types/errors.go | 70 +- precompiles/types/errors_test.go | 81 +- precompiles/types/types.go | 64 ++ scripts/bindings-stateful-precompiles.sh | 1 + 49 files changed, 3954 insertions(+), 47 deletions(-) create mode 100644 e2e/contracts/testbank/TestBank.abi create mode 100644 e2e/contracts/testbank/TestBank.bin create mode 100644 e2e/contracts/testbank/TestBank.go create mode 100644 e2e/contracts/testbank/TestBank.json create mode 100644 e2e/contracts/testbank/TestBank.sol create mode 100644 e2e/contracts/testbank/bindings.go create mode 100644 e2e/e2etests/test_precompiles_bank.go create mode 100644 e2e/e2etests/test_precompiles_bank_through_contract.go create mode 100644 precompiles/bank/IBank.abi create mode 100644 precompiles/bank/IBank.gen.go create mode 100644 precompiles/bank/IBank.json create mode 100644 precompiles/bank/IBank.sol create mode 100644 precompiles/bank/bank.go create mode 100644 precompiles/bank/bank_test.go create mode 100644 precompiles/bank/bindings.go create mode 100644 precompiles/bank/coin.go create mode 100644 precompiles/bank/coin_test.go create mode 100644 precompiles/bank/const.go create mode 100644 precompiles/bank/logs.go create mode 100644 precompiles/bank/method_balance_of.go create mode 100644 precompiles/bank/method_deposit.go create mode 100644 precompiles/bank/method_test.go create mode 100644 precompiles/bank/method_withdraw.go rename precompiles/prototype/{IPrototype.go => IPrototype.gen.go} (100%) rename precompiles/staking/{IStaking.go => IStaking.gen.go} (100%) diff --git a/Dockerfile-localnet b/Dockerfile-localnet index 6be3ba3e03..cfe5e19a48 100644 --- a/Dockerfile-localnet +++ b/Dockerfile-localnet @@ -59,7 +59,7 @@ EXPOSE 22 FROM base-runtime AS latest-runtime COPY --from=cosmovisor-build /go/bin/cosmovisor /usr/local/bin -COPY --from=latest-build /go/bin/zetacored /go/bin/zetaclientd /go/bin/zetaclientd-supervisor /go/bin/zetae2e /usr/local/bin +COPY --from=latest-build /go/bin/zetacored /go/bin/zetaclientd /go/bin/zetaclientd-supervisor /go/bin/zetae2e /usr/local/bin/ # Optional old version build (from source). This old build is used as the genesis version in the upgrade tests. # Use --target latest-runtime to skip. @@ -75,7 +75,7 @@ RUN cd node && make install FROM base-runtime AS old-runtime-source COPY --from=cosmovisor-build /go/bin/cosmovisor /usr/local/bin -COPY --from=old-build-source /go/bin/zetacored /go/bin/zetaclientd /usr/local/bin +COPY --from=old-build-source /go/bin/zetacored /go/bin/zetaclientd /usr/local/bin/ COPY --from=latest-build /go/bin/zetaclientd-supervisor /usr/local/bin # Optional old version build (from binary). diff --git a/app/app.go b/app/app.go index 7c4186af5c..cc271fc35f 100644 --- a/app/app.go +++ b/app/app.go @@ -570,6 +570,7 @@ func New( precompiles.StatefulContracts( &app.FungibleKeeper, app.StakingKeeper, + app.BankKeeper, appCodec, storetypes.TransientGasConfig(), ), diff --git a/changelog.md b/changelog.md index f7fa79185d..3a43031bb4 100644 --- a/changelog.md +++ b/changelog.md @@ -9,6 +9,7 @@ * [2784](https://github.com/zeta-chain/node/pull/2784) - staking precompiled contract * [2795](https://github.com/zeta-chain/node/pull/2795) - support restricted address in Solana * [2861](https://github.com/zeta-chain/node/pull/2861) - emit events from staking precompile +* [2860](https://github.com/zeta-chain/node/pull/2860) - bank precompiled contract * [2870](https://github.com/zeta-chain/node/pull/2870) - support for multiple Bitcoin chains in the zetaclient * [2883](https://github.com/zeta-chain/node/pull/2883) - add chain static information for btc signet testnet * [2907](https://github.com/zeta-chain/node/pull/2907) - derive Bitcoin tss address by chain id and added more Signet static info diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index d84a4ba9a4..ced848aadc 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -322,6 +322,9 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestPrecompilesPrototypeThroughContractName, e2etests.TestPrecompilesStakingName, e2etests.TestPrecompilesStakingThroughContractName, + e2etests.TestPrecompilesBankName, + e2etests.TestPrecompilesBankFailName, + e2etests.TestPrecompilesBankThroughContractName, } } diff --git a/cmd/zetae2e/local/precompiles.go b/cmd/zetae2e/local/precompiles.go index 400db0d973..46668c9f44 100644 --- a/cmd/zetae2e/local/precompiles.go +++ b/cmd/zetae2e/local/precompiles.go @@ -35,6 +35,10 @@ func statefulPrecompilesTestRoutine( precompileRunner.Logger.Print("🏃 starting stateful precompiled contracts tests") startTime := time.Now() + // Send ERC20 that will be depositted into ERC20ZRC20 tokens. + txERC20Send := deployerRunner.SendERC20OnEvm(account.EVMAddress(), 10000) + precompileRunner.WaitForTxReceiptOnEvm(txERC20Send) + testsToRun, err := precompileRunner.GetE2ETestsToRunByName( e2etests.AllE2ETests, testNames..., diff --git a/codecov.yml b/codecov.yml index fedb830848..fee85c9c04 100644 --- a/codecov.yml +++ b/codecov.yml @@ -80,5 +80,4 @@ ignore: - "precompiles/**/*.abi" - "precompiles/**/*.json" - "precompiles/**/*.sol" - - "precompiles/prototype/IPrototype.go" - - "precompiles/staking/IStaking.go" + - "precompiles/**/*.gen.go" diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index a054845739..9977b7dbd9 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -117,7 +117,7 @@ fund_eth_from_config '.additional_accounts.user_admin.evm_address' 10000 "admin fund_eth_from_config '.additional_accounts.user_migration.evm_address' 10000 "migration tester" # unlock precompile tests accounts -fund_eth_from_config '.additional_accounts.user_precompile.evm_address' 10000 "precompile tester" +fund_eth_from_config '.additional_accounts.user_precompile.evm_address' 10000 "precompiles tester" # unlock v2 ethers tests accounts fund_eth_from_config '.additional_accounts.user_v2_ether.evm_address' 10000 "V2 ethers tester" @@ -131,16 +131,6 @@ fund_eth_from_config '.additional_accounts.user_v2_ether_revert.evm_address' 100 # unlock v2 erc20 revert tests accounts fund_eth_from_config '.additional_accounts.user_v2_erc20_revert.evm_address' 10000 "V2 ERC20 revert tester" -# unlock precompile tests accounts -address=$(yq -r '.additional_accounts.user_precompile.evm_address' config.yml) -echo "funding precompile tester address ${address} with 10000 Ether" -geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null - -# unlock precompile tests accounts -address=$(yq -r '.additional_accounts.user_precompile.evm_address' config.yml) -echo "funding precompile tester address ${address} with 10000 Ether" -geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null - # unlock local solana relayer accounts if host solana > /dev/null; then solana_url=$(config_str '.rpcs.solana') diff --git a/e2e/contracts/testbank/TestBank.abi b/e2e/contracts/testbank/TestBank.abi new file mode 100644 index 0000000000..ac2d961bcc --- /dev/null +++ b/e2e/contracts/testbank/TestBank.abi @@ -0,0 +1,87 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/e2e/contracts/testbank/TestBank.bin b/e2e/contracts/testbank/TestBank.bin new file mode 100644 index 0000000000..fc832db5b6 --- /dev/null +++ b/e2e/contracts/testbank/TestBank.bin @@ -0,0 +1 @@ +60a060405260676000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561005157600080fd5b503373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250506080516106a16100ae6000396000818160fc015281816101fc01526102fc01526106a16000f3fe6080604052600436106100385760003560e01c806347e7ef2414610041578063f3fef3a31461007e578063f7888aec146100bb5761003f565b3661003f57005b005b34801561004d57600080fd5b506100686004803603810190610063919061048f565b6100f8565b60405161007591906104ea565b60405180910390f35b34801561008a57600080fd5b506100a560048036038101906100a0919061048f565b6101f8565b6040516100b291906104ea565b60405180910390f35b3480156100c757600080fd5b506100e260048036038101906100dd9190610505565b6102f8565b6040516100ef9190610554565b60405180910390f35b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461015257600080fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166347e7ef2484846040518363ffffffff1660e01b81526004016101ad92919061057e565b6020604051808303816000875af11580156101cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101f091906105d3565b905092915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461025257600080fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f3fef3a384846040518363ffffffff1660e01b81526004016102ad92919061057e565b6020604051808303816000875af11580156102cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102f091906105d3565b905092915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461035257600080fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f7888aec84846040518363ffffffff1660e01b81526004016103ad929190610600565b602060405180830381865afa1580156103ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ee919061063e565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610426826103fb565b9050919050565b6104368161041b565b811461044157600080fd5b50565b6000813590506104538161042d565b92915050565b6000819050919050565b61046c81610459565b811461047757600080fd5b50565b60008135905061048981610463565b92915050565b600080604083850312156104a6576104a56103f6565b5b60006104b485828601610444565b92505060206104c58582860161047a565b9150509250929050565b60008115159050919050565b6104e4816104cf565b82525050565b60006020820190506104ff60008301846104db565b92915050565b6000806040838503121561051c5761051b6103f6565b5b600061052a85828601610444565b925050602061053b85828601610444565b9150509250929050565b61054e81610459565b82525050565b60006020820190506105696000830184610545565b92915050565b6105788161041b565b82525050565b6000604082019050610593600083018561056f565b6105a06020830184610545565b9392505050565b6105b0816104cf565b81146105bb57600080fd5b50565b6000815190506105cd816105a7565b92915050565b6000602082840312156105e9576105e86103f6565b5b60006105f7848285016105be565b91505092915050565b6000604082019050610615600083018561056f565b610622602083018461056f565b9392505050565b60008151905061063881610463565b92915050565b600060208284031215610654576106536103f6565b5b600061066284828501610629565b9150509291505056fea2646970667358221220c0c585590967d576c91dec72feb553b8a6186d045ddc558ecc1de043c068bcb764736f6c634300080a0033 diff --git a/e2e/contracts/testbank/TestBank.go b/e2e/contracts/testbank/TestBank.go new file mode 100644 index 0000000000..c6533c8865 --- /dev/null +++ b/e2e/contracts/testbank/TestBank.go @@ -0,0 +1,318 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package testbank + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// TestBankMetaData contains all meta data concerning the TestBank contract. +var TestBankMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"zrc20\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"zrc20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"zrc20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x60a060405260676000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561005157600080fd5b503373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250506080516106a16100ae6000396000818160fc015281816101fc01526102fc01526106a16000f3fe6080604052600436106100385760003560e01c806347e7ef2414610041578063f3fef3a31461007e578063f7888aec146100bb5761003f565b3661003f57005b005b34801561004d57600080fd5b506100686004803603810190610063919061048f565b6100f8565b60405161007591906104ea565b60405180910390f35b34801561008a57600080fd5b506100a560048036038101906100a0919061048f565b6101f8565b6040516100b291906104ea565b60405180910390f35b3480156100c757600080fd5b506100e260048036038101906100dd9190610505565b6102f8565b6040516100ef9190610554565b60405180910390f35b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461015257600080fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166347e7ef2484846040518363ffffffff1660e01b81526004016101ad92919061057e565b6020604051808303816000875af11580156101cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101f091906105d3565b905092915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461025257600080fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f3fef3a384846040518363ffffffff1660e01b81526004016102ad92919061057e565b6020604051808303816000875af11580156102cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102f091906105d3565b905092915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461035257600080fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f7888aec84846040518363ffffffff1660e01b81526004016103ad929190610600565b602060405180830381865afa1580156103ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ee919061063e565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610426826103fb565b9050919050565b6104368161041b565b811461044157600080fd5b50565b6000813590506104538161042d565b92915050565b6000819050919050565b61046c81610459565b811461047757600080fd5b50565b60008135905061048981610463565b92915050565b600080604083850312156104a6576104a56103f6565b5b60006104b485828601610444565b92505060206104c58582860161047a565b9150509250929050565b60008115159050919050565b6104e4816104cf565b82525050565b60006020820190506104ff60008301846104db565b92915050565b6000806040838503121561051c5761051b6103f6565b5b600061052a85828601610444565b925050602061053b85828601610444565b9150509250929050565b61054e81610459565b82525050565b60006020820190506105696000830184610545565b92915050565b6105788161041b565b82525050565b6000604082019050610593600083018561056f565b6105a06020830184610545565b9392505050565b6105b0816104cf565b81146105bb57600080fd5b50565b6000815190506105cd816105a7565b92915050565b6000602082840312156105e9576105e86103f6565b5b60006105f7848285016105be565b91505092915050565b6000604082019050610615600083018561056f565b610622602083018461056f565b9392505050565b60008151905061063881610463565b92915050565b600060208284031215610654576106536103f6565b5b600061066284828501610629565b9150509291505056fea2646970667358221220c0c585590967d576c91dec72feb553b8a6186d045ddc558ecc1de043c068bcb764736f6c634300080a0033", +} + +// TestBankABI is the input ABI used to generate the binding from. +// Deprecated: Use TestBankMetaData.ABI instead. +var TestBankABI = TestBankMetaData.ABI + +// TestBankBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TestBankMetaData.Bin instead. +var TestBankBin = TestBankMetaData.Bin + +// DeployTestBank deploys a new Ethereum contract, binding an instance of TestBank to it. +func DeployTestBank(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TestBank, error) { + parsed, err := TestBankMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TestBankBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &TestBank{TestBankCaller: TestBankCaller{contract: contract}, TestBankTransactor: TestBankTransactor{contract: contract}, TestBankFilterer: TestBankFilterer{contract: contract}}, nil +} + +// TestBank is an auto generated Go binding around an Ethereum contract. +type TestBank struct { + TestBankCaller // Read-only binding to the contract + TestBankTransactor // Write-only binding to the contract + TestBankFilterer // Log filterer for contract events +} + +// TestBankCaller is an auto generated read-only Go binding around an Ethereum contract. +type TestBankCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TestBankTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TestBankTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TestBankFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TestBankFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TestBankSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TestBankSession struct { + Contract *TestBank // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TestBankCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TestBankCallerSession struct { + Contract *TestBankCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TestBankTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TestBankTransactorSession struct { + Contract *TestBankTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TestBankRaw is an auto generated low-level Go binding around an Ethereum contract. +type TestBankRaw struct { + Contract *TestBank // Generic contract binding to access the raw methods on +} + +// TestBankCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TestBankCallerRaw struct { + Contract *TestBankCaller // Generic read-only contract binding to access the raw methods on +} + +// TestBankTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TestBankTransactorRaw struct { + Contract *TestBankTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTestBank creates a new instance of TestBank, bound to a specific deployed contract. +func NewTestBank(address common.Address, backend bind.ContractBackend) (*TestBank, error) { + contract, err := bindTestBank(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TestBank{TestBankCaller: TestBankCaller{contract: contract}, TestBankTransactor: TestBankTransactor{contract: contract}, TestBankFilterer: TestBankFilterer{contract: contract}}, nil +} + +// NewTestBankCaller creates a new read-only instance of TestBank, bound to a specific deployed contract. +func NewTestBankCaller(address common.Address, caller bind.ContractCaller) (*TestBankCaller, error) { + contract, err := bindTestBank(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TestBankCaller{contract: contract}, nil +} + +// NewTestBankTransactor creates a new write-only instance of TestBank, bound to a specific deployed contract. +func NewTestBankTransactor(address common.Address, transactor bind.ContractTransactor) (*TestBankTransactor, error) { + contract, err := bindTestBank(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TestBankTransactor{contract: contract}, nil +} + +// NewTestBankFilterer creates a new log filterer instance of TestBank, bound to a specific deployed contract. +func NewTestBankFilterer(address common.Address, filterer bind.ContractFilterer) (*TestBankFilterer, error) { + contract, err := bindTestBank(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TestBankFilterer{contract: contract}, nil +} + +// bindTestBank binds a generic wrapper to an already deployed contract. +func bindTestBank(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TestBankMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TestBank *TestBankRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TestBank.Contract.TestBankCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TestBank *TestBankRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TestBank.Contract.TestBankTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TestBank *TestBankRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TestBank.Contract.TestBankTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TestBank *TestBankCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TestBank.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TestBank *TestBankTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TestBank.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TestBank *TestBankTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TestBank.Contract.contract.Transact(opts, method, params...) +} + +// BalanceOf is a free data retrieval call binding the contract method 0xf7888aec. +// +// Solidity: function balanceOf(address zrc20, address user) view returns(uint256) +func (_TestBank *TestBankCaller) BalanceOf(opts *bind.CallOpts, zrc20 common.Address, user common.Address) (*big.Int, error) { + var out []interface{} + err := _TestBank.contract.Call(opts, &out, "balanceOf", zrc20, user) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0xf7888aec. +// +// Solidity: function balanceOf(address zrc20, address user) view returns(uint256) +func (_TestBank *TestBankSession) BalanceOf(zrc20 common.Address, user common.Address) (*big.Int, error) { + return _TestBank.Contract.BalanceOf(&_TestBank.CallOpts, zrc20, user) +} + +// BalanceOf is a free data retrieval call binding the contract method 0xf7888aec. +// +// Solidity: function balanceOf(address zrc20, address user) view returns(uint256) +func (_TestBank *TestBankCallerSession) BalanceOf(zrc20 common.Address, user common.Address) (*big.Int, error) { + return _TestBank.Contract.BalanceOf(&_TestBank.CallOpts, zrc20, user) +} + +// Deposit is a paid mutator transaction binding the contract method 0x47e7ef24. +// +// Solidity: function deposit(address zrc20, uint256 amount) returns(bool) +func (_TestBank *TestBankTransactor) Deposit(opts *bind.TransactOpts, zrc20 common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestBank.contract.Transact(opts, "deposit", zrc20, amount) +} + +// Deposit is a paid mutator transaction binding the contract method 0x47e7ef24. +// +// Solidity: function deposit(address zrc20, uint256 amount) returns(bool) +func (_TestBank *TestBankSession) Deposit(zrc20 common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestBank.Contract.Deposit(&_TestBank.TransactOpts, zrc20, amount) +} + +// Deposit is a paid mutator transaction binding the contract method 0x47e7ef24. +// +// Solidity: function deposit(address zrc20, uint256 amount) returns(bool) +func (_TestBank *TestBankTransactorSession) Deposit(zrc20 common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestBank.Contract.Deposit(&_TestBank.TransactOpts, zrc20, amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0xf3fef3a3. +// +// Solidity: function withdraw(address zrc20, uint256 amount) returns(bool) +func (_TestBank *TestBankTransactor) Withdraw(opts *bind.TransactOpts, zrc20 common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestBank.contract.Transact(opts, "withdraw", zrc20, amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0xf3fef3a3. +// +// Solidity: function withdraw(address zrc20, uint256 amount) returns(bool) +func (_TestBank *TestBankSession) Withdraw(zrc20 common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestBank.Contract.Withdraw(&_TestBank.TransactOpts, zrc20, amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0xf3fef3a3. +// +// Solidity: function withdraw(address zrc20, uint256 amount) returns(bool) +func (_TestBank *TestBankTransactorSession) Withdraw(zrc20 common.Address, amount *big.Int) (*types.Transaction, error) { + return _TestBank.Contract.Withdraw(&_TestBank.TransactOpts, zrc20, amount) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_TestBank *TestBankTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _TestBank.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_TestBank *TestBankSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _TestBank.Contract.Fallback(&_TestBank.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_TestBank *TestBankTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _TestBank.Contract.Fallback(&_TestBank.TransactOpts, calldata) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_TestBank *TestBankTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TestBank.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_TestBank *TestBankSession) Receive() (*types.Transaction, error) { + return _TestBank.Contract.Receive(&_TestBank.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_TestBank *TestBankTransactorSession) Receive() (*types.Transaction, error) { + return _TestBank.Contract.Receive(&_TestBank.TransactOpts) +} diff --git a/e2e/contracts/testbank/TestBank.json b/e2e/contracts/testbank/TestBank.json new file mode 100644 index 0000000000..98b6ac1e68 --- /dev/null +++ b/e2e/contracts/testbank/TestBank.json @@ -0,0 +1,90 @@ +{ + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bin": "60a060405260676000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561005157600080fd5b503373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250506080516106a16100ae6000396000818160fc015281816101fc01526102fc01526106a16000f3fe6080604052600436106100385760003560e01c806347e7ef2414610041578063f3fef3a31461007e578063f7888aec146100bb5761003f565b3661003f57005b005b34801561004d57600080fd5b506100686004803603810190610063919061048f565b6100f8565b60405161007591906104ea565b60405180910390f35b34801561008a57600080fd5b506100a560048036038101906100a0919061048f565b6101f8565b6040516100b291906104ea565b60405180910390f35b3480156100c757600080fd5b506100e260048036038101906100dd9190610505565b6102f8565b6040516100ef9190610554565b60405180910390f35b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461015257600080fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166347e7ef2484846040518363ffffffff1660e01b81526004016101ad92919061057e565b6020604051808303816000875af11580156101cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101f091906105d3565b905092915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461025257600080fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f3fef3a384846040518363ffffffff1660e01b81526004016102ad92919061057e565b6020604051808303816000875af11580156102cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102f091906105d3565b905092915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461035257600080fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f7888aec84846040518363ffffffff1660e01b81526004016103ad929190610600565b602060405180830381865afa1580156103ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ee919061063e565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610426826103fb565b9050919050565b6104368161041b565b811461044157600080fd5b50565b6000813590506104538161042d565b92915050565b6000819050919050565b61046c81610459565b811461047757600080fd5b50565b60008135905061048981610463565b92915050565b600080604083850312156104a6576104a56103f6565b5b60006104b485828601610444565b92505060206104c58582860161047a565b9150509250929050565b60008115159050919050565b6104e4816104cf565b82525050565b60006020820190506104ff60008301846104db565b92915050565b6000806040838503121561051c5761051b6103f6565b5b600061052a85828601610444565b925050602061053b85828601610444565b9150509250929050565b61054e81610459565b82525050565b60006020820190506105696000830184610545565b92915050565b6105788161041b565b82525050565b6000604082019050610593600083018561056f565b6105a06020830184610545565b9392505050565b6105b0816104cf565b81146105bb57600080fd5b50565b6000815190506105cd816105a7565b92915050565b6000602082840312156105e9576105e86103f6565b5b60006105f7848285016105be565b91505092915050565b6000604082019050610615600083018561056f565b610622602083018461056f565b9392505050565b60008151905061063881610463565b92915050565b600060208284031215610654576106536103f6565b5b600061066284828501610629565b9150509291505056fea2646970667358221220c0c585590967d576c91dec72feb553b8a6186d045ddc558ecc1de043c068bcb764736f6c634300080a0033" +} diff --git a/e2e/contracts/testbank/TestBank.sol b/e2e/contracts/testbank/TestBank.sol new file mode 100644 index 0000000000..715e8b4f71 --- /dev/null +++ b/e2e/contracts/testbank/TestBank.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + +// @dev Interface for IBank contract +interface IBank { + function deposit( + address zrc20, + uint256 amount + ) external returns (bool success); + + function withdraw( + address zrc20, + uint256 amount + ) external returns (bool success); + + function balanceOf( + address zrc20, + address user + ) external view returns (uint256 balance); +} + +// @dev Call IBank contract functions +contract TestBank { + IBank bank = IBank(0x0000000000000000000000000000000000000067); + + address immutable owner; + + constructor() { + owner = msg.sender; + } + + modifier onlyOwner() { + require(msg.sender == owner); + _; + } + + function deposit( + address zrc20, + uint256 amount + ) external onlyOwner returns (bool) { + return bank.deposit(zrc20, amount); + } + + function withdraw( + address zrc20, + uint256 amount + ) external onlyOwner returns (bool) { + return bank.withdraw(zrc20, amount); + } + + function balanceOf( + address zrc20, + address user + ) external view onlyOwner returns (uint256) { + return bank.balanceOf(zrc20, user); + } + + fallback() external payable {} + + receive() external payable {} +} diff --git a/e2e/contracts/testbank/bindings.go b/e2e/contracts/testbank/bindings.go new file mode 100644 index 0000000000..5b7846032f --- /dev/null +++ b/e2e/contracts/testbank/bindings.go @@ -0,0 +1,8 @@ +//go:generate sh -c "solc TestBank.sol --combined-json abi,bin | jq '.contracts.\"TestBank.sol:TestBank\"' > TestBank.json" +//go:generate sh -c "cat TestBank.json | jq .abi > TestBank.abi" +//go:generate sh -c "cat TestBank.json | jq .bin | tr -d '\"' > TestBank.bin" +//go:generate sh -c "abigen --abi TestBank.abi --bin TestBank.bin --pkg testbank --type TestBank --out TestBank.go" + +package testbank + +var _ TestBank diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index 08314f9300..29f5a3857a 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -164,6 +164,9 @@ const ( TestPrecompilesPrototypeThroughContractName = "precompile_contracts_prototype_through_contract" TestPrecompilesStakingName = "precompile_contracts_staking" TestPrecompilesStakingThroughContractName = "precompile_contracts_staking_through_contract" + TestPrecompilesBankName = "precompile_contracts_bank" + TestPrecompilesBankFailName = "precompile_contracts_bank_fail" + TestPrecompilesBankThroughContractName = "precompile_contracts_bank_through_contract" ) // AllE2ETests is an ordered list of all e2e tests @@ -918,4 +921,22 @@ var AllE2ETests = []runner.E2ETest{ []runner.ArgDefinition{}, TestPrecompilesStakingThroughContract, ), + runner.NewE2ETest( + TestPrecompilesBankName, + "test stateful precompiled contracts bank with ZRC20 tokens", + []runner.ArgDefinition{}, + TestPrecompilesBank, + ), + runner.NewE2ETest( + TestPrecompilesBankFailName, + "test stateful precompiled contracts bank with non ZRC20 tokens", + []runner.ArgDefinition{}, + TestPrecompilesBankNonZRC20, + ), + runner.NewE2ETest( + TestPrecompilesBankThroughContractName, + "test stateful precompiled contracts bank through contract", + []runner.ArgDefinition{}, + TestPrecompilesBankThroughContract, + ), } diff --git a/e2e/e2etests/test_precompiles_bank.go b/e2e/e2etests/test_precompiles_bank.go new file mode 100644 index 0000000000..2517410339 --- /dev/null +++ b/e2e/e2etests/test_precompiles_bank.go @@ -0,0 +1,203 @@ +package e2etests + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "github.com/zeta-chain/node/e2e/runner" + "github.com/zeta-chain/node/e2e/utils" + "github.com/zeta-chain/node/precompiles/bank" +) + +func TestPrecompilesBank(r *runner.E2ERunner, args []string) { + require.Len(r, args, 0, "No arguments expected") + + totalAmount := big.NewInt(1e3) + depositAmount := big.NewInt(500) + higherBalanceAmount := big.NewInt(1001) + higherAllowanceAmount := big.NewInt(501) + spender := r.EVMAddress() + + // Increase the gasLimit. It's required because of the gas consumed by precompiled functions. + previousGasLimit := r.ZEVMAuth.GasLimit + r.ZEVMAuth.GasLimit = 10_000_000 + defer func() { + r.ZEVMAuth.GasLimit = previousGasLimit + + // Reset the allowance to 0; this is needed when running upgrade tests where + // this test runs twice. + tx, err := r.ERC20ZRC20.Approve(r.ZEVMAuth, bank.ContractAddress, big.NewInt(0)) + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt, "Resetting allowance failed") + + // Reset balance to 0; this is needed when running upgrade tests where this test runs twice. + tx, err = r.ERC20ZRC20.Transfer( + r.ZEVMAuth, + common.HexToAddress("0x000000000000000000000000000000000000dEaD"), + totalAmount, + ) + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt, "Resetting balance failed") + }() + + // Get ERC20ZRC20. + txHash := r.DepositERC20WithAmountAndMessage(r.EVMAddress(), totalAmount, []byte{}) + utils.WaitCctxMinedByInboundHash(r.Ctx, txHash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout) + + // Create a bank contract caller. + bankContract, err := bank.NewIBank(bank.ContractAddress, r.ZEVMClient) + require.NoError(r, err, "Failed to create bank contract caller") + + // Cosmos coin balance should be 0 at this point. + cosmosBalance, err := bankContract.BalanceOf(&bind.CallOpts{Context: r.Ctx}, r.ERC20ZRC20Addr, spender) + require.NoError(r, err, "Call bank.BalanceOf()") + require.Equal(r, uint64(0), cosmosBalance.Uint64(), "spender cosmos coin balance should be 0") + + // Approve allowance of 500 ERC20ZRC20 tokens for the bank contract. Should pass. + tx, err := r.ERC20ZRC20.Approve(r.ZEVMAuth, bank.ContractAddress, depositAmount) + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt, "Approve ETHZRC20 bank allowance tx failed") + + // Deposit 501 ERC20ZRC20 tokens to the bank contract. + // It's higher than allowance but lower than balance, should fail. + tx, err = bankContract.Deposit(r.ZEVMAuth, r.ERC20ZRC20Addr, higherAllowanceAmount) + require.NoError(r, err, "Call bank.Deposit() with amout higher than allowance") + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequiredTxFailed(r, receipt, "Depositting an amount higher than allowed should fail") + + // Approve allowance of 1000 ERC20ZRC20 tokens. + tx, err = r.ERC20ZRC20.Approve(r.ZEVMAuth, bank.ContractAddress, big.NewInt(1e3)) + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt, "Approve ETHZRC20 bank allowance tx failed") + + // Deposit 1001 ERC20ZRC20 tokens to the bank contract. + // It's higher than spender balance but within approved allowance, should fail. + tx, err = bankContract.Deposit(r.ZEVMAuth, r.ERC20ZRC20Addr, higherBalanceAmount) + require.NoError(r, err, "Call bank.Deposit() with amout higher than balance") + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequiredTxFailed(r, receipt, "Depositting an amount higher than balance should fail") + + // Deposit 500 ERC20ZRC20 tokens to the bank contract. Should pass. + tx, err = bankContract.Deposit(r.ZEVMAuth, r.ERC20ZRC20Addr, depositAmount) + require.NoError(r, err, "Call bank.Deposit() with correct amount") + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt, "Depositting a correct amount should pass") + + // Check the deposit event. + eventDeposit, err := bankContract.ParseDeposit(*receipt.Logs[0]) + require.NoError(r, err, "Parse Deposit event") + require.Equal(r, r.EVMAddress(), eventDeposit.Zrc20Depositor, "Deposit event token should be r.EVMAddress()") + require.Equal(r, r.ERC20ZRC20Addr, eventDeposit.Zrc20Token, "Deposit event token should be ERC20ZRC20Addr") + require.Equal(r, depositAmount, eventDeposit.Amount, "Deposit event amount should be 500") + + // Spender: cosmos coin balance should be 500 at this point. + cosmosBalance, err = bankContract.BalanceOf(&bind.CallOpts{Context: r.Ctx}, r.ERC20ZRC20Addr, spender) + require.NoError(r, err, "Call bank.BalanceOf()") + require.Equal(r, uint64(500), cosmosBalance.Uint64(), "spender cosmos coin balance should be 500") + + // Bank: ERC20ZRC20 balance should be 500 tokens locked. + bankZRC20Balance, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{Context: r.Ctx}, bank.ContractAddress) + require.NoError(r, err, "Call ERC20ZRC20.BalanceOf") + require.Equal(r, uint64(500), bankZRC20Balance.Uint64(), "bank ERC20ZRC20 balance should be 500") + + // Try to withdraw 501 ERC20ZRC20 tokens. Should fail. + tx, err = bankContract.Withdraw(r.ZEVMAuth, r.ERC20ZRC20Addr, big.NewInt(501)) + require.NoError(r, err, "Error calling bank.withdraw()") + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequiredTxFailed(r, receipt, "Withdrawing more than cosmos coin balance amount should fail") + + // Bank: ERC20ZRC20 balance should be 500 tokens locked after a failed withdraw. + // No tokens should be unlocked with a failed withdraw. + bankZRC20Balance, err = r.ERC20ZRC20.BalanceOf(&bind.CallOpts{Context: r.Ctx}, bank.ContractAddress) + require.NoError(r, err, "Call ERC20ZRC20.BalanceOf") + require.Equal(r, uint64(500), bankZRC20Balance.Uint64(), "bank ERC20ZRC20 balance should be 500") + + // Try to withdraw 500 ERC20ZRC20 tokens. Should pass. + tx, err = bankContract.Withdraw(r.ZEVMAuth, r.ERC20ZRC20Addr, depositAmount) + require.NoError(r, err, "Error calling bank.withdraw()") + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt, "Withdraw correct amount should pass") + + // Check the withdraw event. + eventWithdraw, err := bankContract.ParseWithdraw(*receipt.Logs[0]) + require.NoError(r, err, "Parse Withdraw event") + require.Equal(r, r.EVMAddress(), eventWithdraw.Zrc20Withdrawer, "Withdrawer should be r.EVMAddress()") + require.Equal(r, r.ERC20ZRC20Addr, eventWithdraw.Zrc20Token, "Withdraw event token should be ERC20ZRC20Addr") + require.Equal(r, depositAmount, eventWithdraw.Amount, "Withdraw event amount should be 500") + + // Spender: cosmos coin balance should be 0 at this point. + cosmosBalance, err = bankContract.BalanceOf(&bind.CallOpts{Context: r.Ctx}, r.ERC20ZRC20Addr, spender) + require.NoError(r, err, "Call bank.BalanceOf()") + require.Equal(r, uint64(0), cosmosBalance.Uint64(), "spender cosmos coin balance should be 0") + + // Spender: ERC20ZRC20 balance should be 1000 at this point. + zrc20Balance, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{Context: r.Ctx}, spender) + require.NoError(r, err, "Call bank.BalanceOf()") + require.Equal(r, uint64(1000), zrc20Balance.Uint64(), "spender ERC20ZRC20 balance should be 1000") + + // Bank: ERC20ZRC20 balance should be 0 tokens locked. + bankZRC20Balance, err = r.ERC20ZRC20.BalanceOf(&bind.CallOpts{Context: r.Ctx}, bank.ContractAddress) + require.NoError(r, err, "Call ERC20ZRC20.BalanceOf") + require.Equal(r, uint64(0), bankZRC20Balance.Uint64(), "bank ERC20ZRC20 balance should be 0") +} + +func TestPrecompilesBankNonZRC20(r *runner.E2ERunner, args []string) { + require.Len(r, args, 0, "No arguments expected") + + // Increase the gasLimit. It's required because of the gas consumed by precompiled functions. + previousGasLimit := r.ZEVMAuth.GasLimit + r.ZEVMAuth.GasLimit = 10_000_000 + defer func() { + r.ZEVMAuth.GasLimit = previousGasLimit + }() + + spender, bankAddr := r.EVMAddress(), bank.ContractAddress + + // Create a bank contract caller. + bankContract, err := bank.NewIBank(bank.ContractAddress, r.ZEVMClient) + require.NoError(r, err, "Failed to create bank contract caller") + + // Deposit and approve 50 WZETA for the test. + approveAmount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(50)) + r.DepositAndApproveWZeta(approveAmount) + + // Non ZRC20 balanceOf check should fail. + _, err = bankContract.BalanceOf(&bind.CallOpts{Context: r.Ctx}, r.WZetaAddr, spender) + require.Error(r, err, "bank.balanceOf() should error out when checking for non ZRC20 balance") + require.Contains( + r, + err.Error(), + "invalid token 0x5F0b1a82749cb4E2278EC87F8BF6B618dC71a8bf: token is not a whitelisted ZRC20", + "Error should be 'token is not a whitelisted ZRC20'", + ) + + // Allow the bank contract to spend 25 WZeta tokens. + tx, err := r.WZeta.Approve(r.ZEVMAuth, bankAddr, big.NewInt(25)) + require.NoError(r, err, "Error approving allowance for bank contract") + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + require.EqualValues(r, uint64(1), receipt.Status, "approve allowance tx failed") + + // Check the allowance of the bank in WZeta tokens. Should be 25. + allowance, err := r.WZeta.Allowance(&bind.CallOpts{Context: r.Ctx}, spender, bankAddr) + require.NoError(r, err, "Error retrieving bank allowance") + require.EqualValues(r, uint64(25), allowance.Uint64(), "Error allowance for bank contract") + + // Call Deposit with 25 Non ZRC20 tokens. Should fail. + tx, err = bankContract.Deposit(r.ZEVMAuth, r.WZetaAddr, big.NewInt(25)) + require.NoError(r, err, "Error calling bank.deposit()") + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + require.Equal(r, uint64(0), receipt.Status, "Non ZRC20 deposit should fail") + + // Call Withdraw with 25 on ZRC20 tokens. Should fail. + tx, err = bankContract.Withdraw(r.ZEVMAuth, r.WZetaAddr, big.NewInt(25)) + require.NoError(r, err, "Error calling bank.withdraw()") + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + require.Equal(r, uint64(0), receipt.Status, "Non ZRC20 withdraw should fail") +} diff --git a/e2e/e2etests/test_precompiles_bank_through_contract.go b/e2e/e2etests/test_precompiles_bank_through_contract.go new file mode 100644 index 0000000000..480663284e --- /dev/null +++ b/e2e/e2etests/test_precompiles_bank_through_contract.go @@ -0,0 +1,186 @@ +package e2etests + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" + + "github.com/zeta-chain/node/e2e/contracts/testbank" + "github.com/zeta-chain/node/e2e/runner" + "github.com/zeta-chain/node/e2e/utils" + "github.com/zeta-chain/node/precompiles/bank" +) + +func TestPrecompilesBankThroughContract(r *runner.E2ERunner, args []string) { + require.Len(r, args, 0, "No arguments expected") + + spender := r.EVMAddress() + zrc20Address := r.ERC20ZRC20Addr + oneThousand := big.NewInt(1e3) + oneThousandOne := big.NewInt(1001) + fiveHundred := big.NewInt(500) + fiveHundredOne := big.NewInt(501) + + // Get ERC20ZRC20. + txHash := r.DepositERC20WithAmountAndMessage(r.EVMAddress(), oneThousand, []byte{}) + utils.WaitCctxMinedByInboundHash(r.Ctx, txHash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout) + + bankPrecompileCaller, err := bank.NewIBank(bank.ContractAddress, r.ZEVMClient) + require.NoError(r, err, "Failed to create bank precompile caller") + + // Deploy the TestBank. Ensure the transaction is successful. + _, tx, testBank, err := testbank.DeployTestBank(r.ZEVMAuth, r.ZEVMClient) + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt, "Deployment of TestBank contract failed") + + previousGasLimit := r.ZEVMAuth.GasLimit + r.ZEVMAuth.GasLimit = 10_000_000 + defer func() { + r.ZEVMAuth.GasLimit = previousGasLimit + + // Reset the allowance to 0; this is needed when running upgrade tests where this test runs twice. + approveAllowance(r, bank.ContractAddress, big.NewInt(0)) + + // Reset balance to 0; this is needed when running upgrade tests where this test runs twice. + tx, err = r.ERC20ZRC20.Transfer( + r.ZEVMAuth, + common.HexToAddress("0x000000000000000000000000000000000000dEaD"), + oneThousand, + ) + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt, "Resetting balance failed") + }() + + // Check initial balances. + balanceShouldBe(r, 0, checkCosmosBalance(r, testBank, zrc20Address, spender)) + balanceShouldBe(r, 1000, checkZRC20Balance(r, spender)) + balanceShouldBe(r, 0, checkZRC20Balance(r, bank.ContractAddress)) + + // Deposit without previous alllowance should fail. + receipt = depositThroughTestBank(r, testBank, zrc20Address, oneThousand) + utils.RequiredTxFailed(r, receipt, "Deposit ERC20ZRC20 without allowance should fail") + + // Check balances, should be the same. + balanceShouldBe(r, 0, checkCosmosBalance(r, testBank, zrc20Address, spender)) + balanceShouldBe(r, 1000, checkZRC20Balance(r, spender)) + balanceShouldBe(r, 0, checkZRC20Balance(r, bank.ContractAddress)) + + // Allow 500 ZRC20 to bank precompile. + approveAllowance(r, bank.ContractAddress, fiveHundred) + + // Deposit 501 ERC20ZRC20 tokens to the bank contract, through TestBank. + // It's higher than allowance but lower than balance, should fail. + receipt = depositThroughTestBank(r, testBank, zrc20Address, fiveHundredOne) + utils.RequiredTxFailed(r, receipt, "Depositting an amount higher than allowed should fail") + + // Balances shouldn't change. + balanceShouldBe(r, 0, checkCosmosBalance(r, testBank, zrc20Address, spender)) + balanceShouldBe(r, 1000, checkZRC20Balance(r, spender)) + balanceShouldBe(r, 0, checkZRC20Balance(r, bank.ContractAddress)) + + // Allow 1000 ZRC20 to bank precompile. + approveAllowance(r, bank.ContractAddress, oneThousand) + + // Deposit 1001 ERC20ZRC20 tokens to the bank contract. + // It's higher than spender balance but within approved allowance, should fail. + receipt = depositThroughTestBank(r, testBank, zrc20Address, oneThousandOne) + utils.RequiredTxFailed(r, receipt, "Depositting an amount higher than balance should fail") + + // Balances shouldn't change. + balanceShouldBe(r, 0, checkCosmosBalance(r, testBank, zrc20Address, spender)) + balanceShouldBe(r, 1000, checkZRC20Balance(r, spender)) + balanceShouldBe(r, 0, checkZRC20Balance(r, bank.ContractAddress)) + + // Deposit 500 ERC20ZRC20 tokens to the bank contract, it's within allowance and balance. Should pass. + receipt = depositThroughTestBank(r, testBank, zrc20Address, fiveHundred) + utils.RequireTxSuccessful(r, receipt, "Depositting a correct amount should pass") + + // Balances should be transferred. Bank now locks 500 ZRC20 tokens. + balanceShouldBe(r, 500, checkCosmosBalance(r, testBank, zrc20Address, spender)) + balanceShouldBe(r, 500, checkZRC20Balance(r, spender)) + balanceShouldBe(r, 500, checkZRC20Balance(r, bank.ContractAddress)) + + // Check the deposit event. + eventDeposit, err := bankPrecompileCaller.ParseDeposit(*receipt.Logs[0]) + require.NoError(r, err, "Parse Deposit event") + require.Equal(r, r.EVMAddress(), eventDeposit.Zrc20Depositor, "Deposit event token should be r.EVMAddress()") + require.Equal(r, r.ERC20ZRC20Addr, eventDeposit.Zrc20Token, "Deposit event token should be ERC20ZRC20Addr") + require.Equal(r, fiveHundred, eventDeposit.Amount, "Deposit event amount should be 500") + + // Should faild to withdraw more than cosmos balance. + receipt = withdrawThroughTestBank(r, testBank, zrc20Address, fiveHundredOne) + utils.RequiredTxFailed(r, receipt, "Withdrawing an amount higher than balance should fail") + + // Balances shouldn't change. + balanceShouldBe(r, 500, checkCosmosBalance(r, testBank, zrc20Address, spender)) + balanceShouldBe(r, 500, checkZRC20Balance(r, spender)) + balanceShouldBe(r, 500, checkZRC20Balance(r, bank.ContractAddress)) + + // Try to withdraw 500 ERC20ZRC20 tokens. Should pass. + receipt = withdrawThroughTestBank(r, testBank, zrc20Address, fiveHundred) + utils.RequireTxSuccessful(r, receipt, "Withdraw correct amount should pass") + + // Balances should be reverted to initial state. + balanceShouldBe(r, 0, checkCosmosBalance(r, testBank, zrc20Address, spender)) + balanceShouldBe(r, 1000, checkZRC20Balance(r, spender)) + balanceShouldBe(r, 0, checkZRC20Balance(r, bank.ContractAddress)) + + // Check the withdraw event. + eventWithdraw, err := bankPrecompileCaller.ParseWithdraw(*receipt.Logs[0]) + require.NoError(r, err, "Parse Withdraw event") + require.Equal(r, r.EVMAddress(), eventWithdraw.Zrc20Withdrawer, "Withdrawer should be r.EVMAddress()") + require.Equal(r, r.ERC20ZRC20Addr, eventWithdraw.Zrc20Token, "Withdraw event token should be ERC20ZRC20Addr") + require.Equal(r, fiveHundred, eventWithdraw.Amount, "Withdraw event amount should be 500") +} + +func approveAllowance(r *runner.E2ERunner, target common.Address, amount *big.Int) { + tx, err := r.ERC20ZRC20.Approve(r.ZEVMAuth, target, amount) + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt, "Approve ERC20ZRC20 allowance tx failed") +} + +func balanceShouldBe(r *runner.E2ERunner, expected uint64, balance *big.Int) { + require.Equal(r, expected, balance.Uint64(), "Balance should be %d, got: %d", expected, balance.Uint64()) +} + +func checkZRC20Balance(r *runner.E2ERunner, target common.Address) *big.Int { + bankZRC20Balance, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{Context: r.Ctx}, target) + require.NoError(r, err, "Call ERC20ZRC20.BalanceOf") + return bankZRC20Balance +} + +func checkCosmosBalance(r *runner.E2ERunner, bank *testbank.TestBank, zrc20, target common.Address) *big.Int { + balance, err := bank.BalanceOf(&bind.CallOpts{Context: r.Ctx, From: r.ZEVMAuth.From}, zrc20, target) + require.NoError(r, err) + return balance +} + +func depositThroughTestBank( + r *runner.E2ERunner, + bank *testbank.TestBank, + zrc20Address common.Address, + amount *big.Int, +) *types.Receipt { + tx, err := bank.Deposit(r.ZEVMAuth, zrc20Address, amount) + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + return receipt +} + +func withdrawThroughTestBank( + r *runner.E2ERunner, + bank *testbank.TestBank, + zrc20Address common.Address, + amount *big.Int, +) *types.Receipt { + tx, err := bank.Withdraw(r.ZEVMAuth, zrc20Address, amount) + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + return receipt +} diff --git a/e2e/e2etests/test_rate_limiter.go b/e2e/e2etests/test_rate_limiter.go index c2e10551aa..e74691e1bd 100644 --- a/e2e/e2etests/test_rate_limiter.go +++ b/e2e/e2etests/test_rate_limiter.go @@ -122,7 +122,7 @@ func createAndWaitWithdraws(r *runner.E2ERunner, withdrawType withdrawType, with return err } - duration := time.Now().Sub(startTime).Seconds() + duration := time.Since(startTime).Seconds() block, err := r.ZEVMClient.BlockNumber(r.Ctx) if err != nil { return fmt.Errorf("error getting block number: %w", err) @@ -155,7 +155,7 @@ func waitForWithdrawMined( } // record the time for completion - duration := time.Now().Sub(startTime).Seconds() + duration := time.Since(startTime).Seconds() block, err := r.ZEVMClient.BlockNumber(ctx) if err != nil { return err diff --git a/e2e/e2etests/test_stress_btc_deposit.go b/e2e/e2etests/test_stress_btc_deposit.go index 25b89088ac..53caea09df 100644 --- a/e2e/e2etests/test_stress_btc_deposit.go +++ b/e2e/e2etests/test_stress_btc_deposit.go @@ -53,7 +53,7 @@ func monitorBTCDeposit(r *runner.E2ERunner, hash *chainhash.Hash, index int, sta cctx.Index, ) } - timeToComplete := time.Now().Sub(startTime) + timeToComplete := time.Since(startTime) r.Logger.Print("index %d: deposit cctx success in %s", index, timeToComplete.String()) return nil diff --git a/e2e/e2etests/test_stress_btc_withdraw.go b/e2e/e2etests/test_stress_btc_withdraw.go index a4fb3143c1..52d60430d2 100644 --- a/e2e/e2etests/test_stress_btc_withdraw.go +++ b/e2e/e2etests/test_stress_btc_withdraw.go @@ -66,7 +66,7 @@ func monitorBTCWithdraw(r *runner.E2ERunner, tx *ethtypes.Transaction, index int cctx.Index, ) } - timeToComplete := time.Now().Sub(startTime) + timeToComplete := time.Since(startTime) r.Logger.Print("index %d: withdraw cctx success in %s", index, timeToComplete.String()) return nil diff --git a/e2e/e2etests/test_stress_eth_deposit.go b/e2e/e2etests/test_stress_eth_deposit.go index 19676c9cba..29abb76ba0 100644 --- a/e2e/e2etests/test_stress_eth_deposit.go +++ b/e2e/e2etests/test_stress_eth_deposit.go @@ -52,7 +52,7 @@ func monitorEtherDeposit(r *runner.E2ERunner, hash ethcommon.Hash, index int, st cctx.Index, ) } - timeToComplete := time.Now().Sub(startTime) + timeToComplete := time.Since(startTime) r.Logger.Print("index %d: deposit cctx success in %s", index, timeToComplete.String()) return nil diff --git a/e2e/e2etests/test_stress_eth_withdraw.go b/e2e/e2etests/test_stress_eth_withdraw.go index 98fa8e8783..337a4d416d 100644 --- a/e2e/e2etests/test_stress_eth_withdraw.go +++ b/e2e/e2etests/test_stress_eth_withdraw.go @@ -70,7 +70,7 @@ func monitorEtherWithdraw(r *runner.E2ERunner, tx *ethtypes.Transaction, index i cctx.Index, ) } - timeToComplete := time.Now().Sub(startTime) + timeToComplete := time.Since(startTime) r.Logger.Print("index %d: withdraw cctx success in %s", index, timeToComplete.String()) return nil diff --git a/e2e/utils/require.go b/e2e/utils/require.go index b139a2cad5..e610219e15 100644 --- a/e2e/utils/require.go +++ b/e2e/utils/require.go @@ -43,5 +43,9 @@ func errSuffix(msgAndArgs ...any) string { template := "; " + msgAndArgs[0].(string) + if len(msgAndArgs) == 1 { + return template + } + return fmt.Sprintf(template, msgAndArgs[1:]) } diff --git a/precompiles/bank/IBank.abi b/precompiles/bank/IBank.abi new file mode 100644 index 0000000000..9806953a39 --- /dev/null +++ b/precompiles/bank/IBank.abi @@ -0,0 +1,148 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "zrc20_depositor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "zrc20_token", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "cosmos_token", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "cosmos_address", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "zrc20_withdrawer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "zrc20_token", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "cosmos_token", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "cosmos_address", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/precompiles/bank/IBank.gen.go b/precompiles/bank/IBank.gen.go new file mode 100644 index 0000000000..5064cc8661 --- /dev/null +++ b/precompiles/bank/IBank.gen.go @@ -0,0 +1,582 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bank + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// IBankMetaData contains all meta data concerning the IBank contract. +var IBankMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"zrc20_depositor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"zrc20_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"cosmos_token\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"cosmos_address\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"zrc20_withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"zrc20_token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"cosmos_token\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"cosmos_address\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"zrc20\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"zrc20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"zrc20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +// IBankABI is the input ABI used to generate the binding from. +// Deprecated: Use IBankMetaData.ABI instead. +var IBankABI = IBankMetaData.ABI + +// IBank is an auto generated Go binding around an Ethereum contract. +type IBank struct { + IBankCaller // Read-only binding to the contract + IBankTransactor // Write-only binding to the contract + IBankFilterer // Log filterer for contract events +} + +// IBankCaller is an auto generated read-only Go binding around an Ethereum contract. +type IBankCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IBankTransactor is an auto generated write-only Go binding around an Ethereum contract. +type IBankTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IBankFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type IBankFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IBankSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type IBankSession struct { + Contract *IBank // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IBankCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type IBankCallerSession struct { + Contract *IBankCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// IBankTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type IBankTransactorSession struct { + Contract *IBankTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IBankRaw is an auto generated low-level Go binding around an Ethereum contract. +type IBankRaw struct { + Contract *IBank // Generic contract binding to access the raw methods on +} + +// IBankCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type IBankCallerRaw struct { + Contract *IBankCaller // Generic read-only contract binding to access the raw methods on +} + +// IBankTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type IBankTransactorRaw struct { + Contract *IBankTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewIBank creates a new instance of IBank, bound to a specific deployed contract. +func NewIBank(address common.Address, backend bind.ContractBackend) (*IBank, error) { + contract, err := bindIBank(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &IBank{IBankCaller: IBankCaller{contract: contract}, IBankTransactor: IBankTransactor{contract: contract}, IBankFilterer: IBankFilterer{contract: contract}}, nil +} + +// NewIBankCaller creates a new read-only instance of IBank, bound to a specific deployed contract. +func NewIBankCaller(address common.Address, caller bind.ContractCaller) (*IBankCaller, error) { + contract, err := bindIBank(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &IBankCaller{contract: contract}, nil +} + +// NewIBankTransactor creates a new write-only instance of IBank, bound to a specific deployed contract. +func NewIBankTransactor(address common.Address, transactor bind.ContractTransactor) (*IBankTransactor, error) { + contract, err := bindIBank(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &IBankTransactor{contract: contract}, nil +} + +// NewIBankFilterer creates a new log filterer instance of IBank, bound to a specific deployed contract. +func NewIBankFilterer(address common.Address, filterer bind.ContractFilterer) (*IBankFilterer, error) { + contract, err := bindIBank(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &IBankFilterer{contract: contract}, nil +} + +// bindIBank binds a generic wrapper to an already deployed contract. +func bindIBank(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := IBankMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IBank *IBankRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IBank.Contract.IBankCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IBank *IBankRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IBank.Contract.IBankTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IBank *IBankRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IBank.Contract.IBankTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IBank *IBankCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IBank.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IBank *IBankTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IBank.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IBank *IBankTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IBank.Contract.contract.Transact(opts, method, params...) +} + +// BalanceOf is a free data retrieval call binding the contract method 0xf7888aec. +// +// Solidity: function balanceOf(address zrc20, address user) view returns(uint256 balance) +func (_IBank *IBankCaller) BalanceOf(opts *bind.CallOpts, zrc20 common.Address, user common.Address) (*big.Int, error) { + var out []interface{} + err := _IBank.contract.Call(opts, &out, "balanceOf", zrc20, user) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0xf7888aec. +// +// Solidity: function balanceOf(address zrc20, address user) view returns(uint256 balance) +func (_IBank *IBankSession) BalanceOf(zrc20 common.Address, user common.Address) (*big.Int, error) { + return _IBank.Contract.BalanceOf(&_IBank.CallOpts, zrc20, user) +} + +// BalanceOf is a free data retrieval call binding the contract method 0xf7888aec. +// +// Solidity: function balanceOf(address zrc20, address user) view returns(uint256 balance) +func (_IBank *IBankCallerSession) BalanceOf(zrc20 common.Address, user common.Address) (*big.Int, error) { + return _IBank.Contract.BalanceOf(&_IBank.CallOpts, zrc20, user) +} + +// Deposit is a paid mutator transaction binding the contract method 0x47e7ef24. +// +// Solidity: function deposit(address zrc20, uint256 amount) returns(bool success) +func (_IBank *IBankTransactor) Deposit(opts *bind.TransactOpts, zrc20 common.Address, amount *big.Int) (*types.Transaction, error) { + return _IBank.contract.Transact(opts, "deposit", zrc20, amount) +} + +// Deposit is a paid mutator transaction binding the contract method 0x47e7ef24. +// +// Solidity: function deposit(address zrc20, uint256 amount) returns(bool success) +func (_IBank *IBankSession) Deposit(zrc20 common.Address, amount *big.Int) (*types.Transaction, error) { + return _IBank.Contract.Deposit(&_IBank.TransactOpts, zrc20, amount) +} + +// Deposit is a paid mutator transaction binding the contract method 0x47e7ef24. +// +// Solidity: function deposit(address zrc20, uint256 amount) returns(bool success) +func (_IBank *IBankTransactorSession) Deposit(zrc20 common.Address, amount *big.Int) (*types.Transaction, error) { + return _IBank.Contract.Deposit(&_IBank.TransactOpts, zrc20, amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0xf3fef3a3. +// +// Solidity: function withdraw(address zrc20, uint256 amount) returns(bool success) +func (_IBank *IBankTransactor) Withdraw(opts *bind.TransactOpts, zrc20 common.Address, amount *big.Int) (*types.Transaction, error) { + return _IBank.contract.Transact(opts, "withdraw", zrc20, amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0xf3fef3a3. +// +// Solidity: function withdraw(address zrc20, uint256 amount) returns(bool success) +func (_IBank *IBankSession) Withdraw(zrc20 common.Address, amount *big.Int) (*types.Transaction, error) { + return _IBank.Contract.Withdraw(&_IBank.TransactOpts, zrc20, amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0xf3fef3a3. +// +// Solidity: function withdraw(address zrc20, uint256 amount) returns(bool success) +func (_IBank *IBankTransactorSession) Withdraw(zrc20 common.Address, amount *big.Int) (*types.Transaction, error) { + return _IBank.Contract.Withdraw(&_IBank.TransactOpts, zrc20, amount) +} + +// IBankDepositIterator is returned from FilterDeposit and is used to iterate over the raw logs and unpacked data for Deposit events raised by the IBank contract. +type IBankDepositIterator struct { + Event *IBankDeposit // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IBankDepositIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IBankDeposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IBankDeposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IBankDepositIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IBankDepositIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IBankDeposit represents a Deposit event raised by the IBank contract. +type IBankDeposit struct { + Zrc20Depositor common.Address + Zrc20Token common.Address + CosmosToken common.Hash + CosmosAddress string + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDeposit is a free log retrieval operation binding the contract event 0xbd7d4de0b30a306221956a420cad57737ae9c1ee63072c96a4f1ab81e6eea264. +// +// Solidity: event Deposit(address indexed zrc20_depositor, address indexed zrc20_token, string indexed cosmos_token, string cosmos_address, uint256 amount) +func (_IBank *IBankFilterer) FilterDeposit(opts *bind.FilterOpts, zrc20_depositor []common.Address, zrc20_token []common.Address, cosmos_token []string) (*IBankDepositIterator, error) { + + var zrc20_depositorRule []interface{} + for _, zrc20_depositorItem := range zrc20_depositor { + zrc20_depositorRule = append(zrc20_depositorRule, zrc20_depositorItem) + } + var zrc20_tokenRule []interface{} + for _, zrc20_tokenItem := range zrc20_token { + zrc20_tokenRule = append(zrc20_tokenRule, zrc20_tokenItem) + } + var cosmos_tokenRule []interface{} + for _, cosmos_tokenItem := range cosmos_token { + cosmos_tokenRule = append(cosmos_tokenRule, cosmos_tokenItem) + } + + logs, sub, err := _IBank.contract.FilterLogs(opts, "Deposit", zrc20_depositorRule, zrc20_tokenRule, cosmos_tokenRule) + if err != nil { + return nil, err + } + return &IBankDepositIterator{contract: _IBank.contract, event: "Deposit", logs: logs, sub: sub}, nil +} + +// WatchDeposit is a free log subscription operation binding the contract event 0xbd7d4de0b30a306221956a420cad57737ae9c1ee63072c96a4f1ab81e6eea264. +// +// Solidity: event Deposit(address indexed zrc20_depositor, address indexed zrc20_token, string indexed cosmos_token, string cosmos_address, uint256 amount) +func (_IBank *IBankFilterer) WatchDeposit(opts *bind.WatchOpts, sink chan<- *IBankDeposit, zrc20_depositor []common.Address, zrc20_token []common.Address, cosmos_token []string) (event.Subscription, error) { + + var zrc20_depositorRule []interface{} + for _, zrc20_depositorItem := range zrc20_depositor { + zrc20_depositorRule = append(zrc20_depositorRule, zrc20_depositorItem) + } + var zrc20_tokenRule []interface{} + for _, zrc20_tokenItem := range zrc20_token { + zrc20_tokenRule = append(zrc20_tokenRule, zrc20_tokenItem) + } + var cosmos_tokenRule []interface{} + for _, cosmos_tokenItem := range cosmos_token { + cosmos_tokenRule = append(cosmos_tokenRule, cosmos_tokenItem) + } + + logs, sub, err := _IBank.contract.WatchLogs(opts, "Deposit", zrc20_depositorRule, zrc20_tokenRule, cosmos_tokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IBankDeposit) + if err := _IBank.contract.UnpackLog(event, "Deposit", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDeposit is a log parse operation binding the contract event 0xbd7d4de0b30a306221956a420cad57737ae9c1ee63072c96a4f1ab81e6eea264. +// +// Solidity: event Deposit(address indexed zrc20_depositor, address indexed zrc20_token, string indexed cosmos_token, string cosmos_address, uint256 amount) +func (_IBank *IBankFilterer) ParseDeposit(log types.Log) (*IBankDeposit, error) { + event := new(IBankDeposit) + if err := _IBank.contract.UnpackLog(event, "Deposit", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// IBankWithdrawIterator is returned from FilterWithdraw and is used to iterate over the raw logs and unpacked data for Withdraw events raised by the IBank contract. +type IBankWithdrawIterator struct { + Event *IBankWithdraw // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IBankWithdrawIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IBankWithdraw) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IBankWithdraw) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IBankWithdrawIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IBankWithdrawIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IBankWithdraw represents a Withdraw event raised by the IBank contract. +type IBankWithdraw struct { + Zrc20Withdrawer common.Address + Zrc20Token common.Address + CosmosToken common.Hash + CosmosAddress string + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterWithdraw is a free log retrieval operation binding the contract event 0x1ad70707c91d850319aeab00514a0166569359f0b8dc5285bdd6e6b9c464b18e. +// +// Solidity: event Withdraw(address indexed zrc20_withdrawer, address indexed zrc20_token, string indexed cosmos_token, string cosmos_address, uint256 amount) +func (_IBank *IBankFilterer) FilterWithdraw(opts *bind.FilterOpts, zrc20_withdrawer []common.Address, zrc20_token []common.Address, cosmos_token []string) (*IBankWithdrawIterator, error) { + + var zrc20_withdrawerRule []interface{} + for _, zrc20_withdrawerItem := range zrc20_withdrawer { + zrc20_withdrawerRule = append(zrc20_withdrawerRule, zrc20_withdrawerItem) + } + var zrc20_tokenRule []interface{} + for _, zrc20_tokenItem := range zrc20_token { + zrc20_tokenRule = append(zrc20_tokenRule, zrc20_tokenItem) + } + var cosmos_tokenRule []interface{} + for _, cosmos_tokenItem := range cosmos_token { + cosmos_tokenRule = append(cosmos_tokenRule, cosmos_tokenItem) + } + + logs, sub, err := _IBank.contract.FilterLogs(opts, "Withdraw", zrc20_withdrawerRule, zrc20_tokenRule, cosmos_tokenRule) + if err != nil { + return nil, err + } + return &IBankWithdrawIterator{contract: _IBank.contract, event: "Withdraw", logs: logs, sub: sub}, nil +} + +// WatchWithdraw is a free log subscription operation binding the contract event 0x1ad70707c91d850319aeab00514a0166569359f0b8dc5285bdd6e6b9c464b18e. +// +// Solidity: event Withdraw(address indexed zrc20_withdrawer, address indexed zrc20_token, string indexed cosmos_token, string cosmos_address, uint256 amount) +func (_IBank *IBankFilterer) WatchWithdraw(opts *bind.WatchOpts, sink chan<- *IBankWithdraw, zrc20_withdrawer []common.Address, zrc20_token []common.Address, cosmos_token []string) (event.Subscription, error) { + + var zrc20_withdrawerRule []interface{} + for _, zrc20_withdrawerItem := range zrc20_withdrawer { + zrc20_withdrawerRule = append(zrc20_withdrawerRule, zrc20_withdrawerItem) + } + var zrc20_tokenRule []interface{} + for _, zrc20_tokenItem := range zrc20_token { + zrc20_tokenRule = append(zrc20_tokenRule, zrc20_tokenItem) + } + var cosmos_tokenRule []interface{} + for _, cosmos_tokenItem := range cosmos_token { + cosmos_tokenRule = append(cosmos_tokenRule, cosmos_tokenItem) + } + + logs, sub, err := _IBank.contract.WatchLogs(opts, "Withdraw", zrc20_withdrawerRule, zrc20_tokenRule, cosmos_tokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IBankWithdraw) + if err := _IBank.contract.UnpackLog(event, "Withdraw", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseWithdraw is a log parse operation binding the contract event 0x1ad70707c91d850319aeab00514a0166569359f0b8dc5285bdd6e6b9c464b18e. +// +// Solidity: event Withdraw(address indexed zrc20_withdrawer, address indexed zrc20_token, string indexed cosmos_token, string cosmos_address, uint256 amount) +func (_IBank *IBankFilterer) ParseWithdraw(log types.Log) (*IBankWithdraw, error) { + event := new(IBankWithdraw) + if err := _IBank.contract.UnpackLog(event, "Withdraw", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/precompiles/bank/IBank.json b/precompiles/bank/IBank.json new file mode 100644 index 0000000000..1ef1654602 --- /dev/null +++ b/precompiles/bank/IBank.json @@ -0,0 +1,150 @@ +{ + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "zrc20_depositor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "zrc20_token", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "cosmos_token", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "cosmos_address", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "zrc20_withdrawer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "zrc20_token", + "type": "address" + }, + { + "indexed": true, + "internalType": "string", + "name": "cosmos_token", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "cosmos_address", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "zrc20", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} diff --git a/precompiles/bank/IBank.sol b/precompiles/bank/IBank.sol new file mode 100644 index 0000000000..4b5d7f2eba --- /dev/null +++ b/precompiles/bank/IBank.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; + +/// @title IBank Interface for Cross-chain Token Deposits and Withdrawals +/// @notice This interface defines the functions for depositing ZRC20 tokens and withdrawing Cosmos tokens, +/// as well as querying the balance of Cosmos tokens corresponding to a given ZRC20 token. +/// @dev This contract interacts with a precompiled contract at a fixed address. + +/// @dev The IBank contract's precompiled address. +address constant IBANK_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000067; // Address 103 + +/// @dev The IBank contract instance using the precompiled address. +IBank constant IBANK_CONTRACT = IBank(IBANK_PRECOMPILE_ADDRESS); + +/// @dev Interface for the IBank contract. +interface IBank { + /// @notice Deposit event is emitted when deposit function is called. + /// @param zrc20_depositor Depositor EVM address. + /// @param zrc20_token ZRC20 address deposited. + /// @param cosmos_token Cosmos token denomination the tokens were converted into. + /// @param cosmos_address Cosmos address the tokens were deposited to. + /// @param amount Amount deposited. + event Deposit( + address indexed zrc20_depositor, + address indexed zrc20_token, + string indexed cosmos_token, + string cosmos_address, + uint256 amount + ); + + /// @notice Withdraw event is emitted when withdraw function is called. + /// @param zrc20_withdrawer Withdrawer EVM address. + /// @param zrc20_token ZRC20 address withdrawn. + /// @param cosmos_token Cosmos token denomination the tokens were converted from. + /// @param cosmos_address Cosmos address the tokens were withdrawn from. + /// @param amount Amount withdrawn. + event Withdraw( + address indexed zrc20_withdrawer, + address indexed zrc20_token, + string indexed cosmos_token, + string cosmos_address, + uint256 amount + ); + + /// @notice Deposit a ZRC20 token and mint the corresponding Cosmos token to the user's account. + /// @param zrc20 The ZRC20 token address to be deposited. + /// @param amount The amount of ZRC20 tokens to deposit. + /// @return success Boolean indicating whether the deposit was successful. + function deposit( + address zrc20, + uint256 amount + ) external returns (bool success); + + /// @notice Withdraw Cosmos tokens and convert them back to the corresponding ZRC20 token for the user. + /// @param zrc20 The ZRC20 token address for the corresponding Cosmos token. + /// @param amount The amount of Cosmos tokens to withdraw. + /// @return success Boolean indicating whether the withdrawal was successful. + function withdraw( + address zrc20, + uint256 amount + ) external returns (bool success); + + /// @notice Retrieve the Cosmos token balance corresponding to a specific ZRC20 token for a given user. + /// @param zrc20 The ZRC20 cosmos token denomination to check the balance for. + /// @param user The address of the user to retrieve the balance for. + /// @return balance The balance of the Cosmos token for the specified ZRC20 token and user. + function balanceOf( + address zrc20, + address user + ) external view returns (uint256 balance); +} diff --git a/precompiles/bank/bank.go b/precompiles/bank/bank.go new file mode 100644 index 0000000000..436364dfa6 --- /dev/null +++ b/precompiles/bank/bank.go @@ -0,0 +1,216 @@ +package bank + +import ( + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + bank "github.com/cosmos/cosmos-sdk/x/bank/keeper" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/zeta-chain/protocol-contracts/v2/pkg/zrc20.sol" + + ptypes "github.com/zeta-chain/node/precompiles/types" + fungiblekeeper "github.com/zeta-chain/node/x/fungible/keeper" +) + +var ( + ABI abi.ABI + ContractAddress = common.HexToAddress("0x0000000000000000000000000000000000000067") + GasRequiredByMethod = map[[4]byte]uint64{} + ViewMethod = map[[4]byte]bool{} +) + +func init() { + initABI() +} + +func initABI() { + if err := ABI.UnmarshalJSON([]byte(IBankMetaData.ABI)); err != nil { + panic(err) + } + + GasRequiredByMethod = map[[4]byte]uint64{} + for methodName := range ABI.Methods { + var methodID [4]byte + copy(methodID[:], ABI.Methods[methodName].ID[:4]) + switch methodName { + case DepositMethodName: + GasRequiredByMethod[methodID] = DepositMethodGas + case WithdrawMethodName: + GasRequiredByMethod[methodID] = WithdrawMethodGas + case BalanceOfMethodName: + GasRequiredByMethod[methodID] = BalanceOfGas + default: + GasRequiredByMethod[methodID] = DefaultGas + } + } +} + +type Contract struct { + ptypes.BaseContract + + bankKeeper bank.Keeper + fungibleKeeper fungiblekeeper.Keeper + zrc20ABI *abi.ABI + cdc codec.Codec + kvGasConfig storetypes.GasConfig +} + +func NewIBankContract( + ctx sdk.Context, + bankKeeper bank.Keeper, + fungibleKeeper fungiblekeeper.Keeper, + cdc codec.Codec, + kvGasConfig storetypes.GasConfig, +) *Contract { + accAddress := sdk.AccAddress(ContractAddress.Bytes()) + if fungibleKeeper.GetAuthKeeper().GetAccount(ctx, accAddress) == nil { + fungibleKeeper.GetAuthKeeper().SetAccount(ctx, authtypes.NewBaseAccount(accAddress, nil, 0, 0)) + } + + // Instantiate the ZRC20 ABI only one time. + // This avoids instantiating it every time deposit or withdraw are called. + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return nil + } + + return &Contract{ + BaseContract: ptypes.NewBaseContract(ContractAddress), + bankKeeper: bankKeeper, + fungibleKeeper: fungibleKeeper, + zrc20ABI: zrc20ABI, + cdc: cdc, + kvGasConfig: kvGasConfig, + } +} + +// Address() is required to implement the PrecompiledContract interface. +func (c *Contract) Address() common.Address { + return ContractAddress +} + +// Abi() is required to implement the PrecompiledContract interface. +func (c *Contract) Abi() abi.ABI { + return ABI +} + +// RequiredGas is required to implement the PrecompiledContract interface. +// The gas has to be calculated deterministically based on the input. +func (c *Contract) RequiredGas(input []byte) uint64 { + // get methodID (first 4 bytes) + var methodID [4]byte + copy(methodID[:], input[:4]) + // base cost to prevent large input size + baseCost := uint64(len(input)) * c.kvGasConfig.WriteCostPerByte + if ViewMethod[methodID] { + baseCost = uint64(len(input)) * c.kvGasConfig.ReadCostPerByte + } + + if requiredGas, ok := GasRequiredByMethod[methodID]; ok { + return requiredGas + baseCost + } + + // Can not happen, but return 0 if the method is not found. + return 0 +} + +// Run is the entrypoint of the precompiled contract, it switches over the input method, +// and execute them accordingly. +func (c *Contract) Run(evm *vm.EVM, contract *vm.Contract, readOnly bool) ([]byte, error) { + method, err := ABI.MethodById(contract.Input[:4]) + if err != nil { + return nil, err + } + + args, err := method.Inputs.Unpack(contract.Input[4:]) + if err != nil { + return nil, err + } + + stateDB := evm.StateDB.(ptypes.ExtStateDB) + + switch method.Name { + // Deposit and Withdraw methods are both not allowed in read-only mode. + case DepositMethodName, WithdrawMethodName: + if readOnly { + return nil, ptypes.ErrUnexpected{ + Got: "method not allowed in read-only mode: " + method.Name, + } + } + + var res []byte + execErr := stateDB.ExecuteNativeAction(contract.Address(), nil, func(ctx sdk.Context) error { + if method.Name == DepositMethodName { + res, err = c.deposit(ctx, evm, contract, method, args) + } else if method.Name == WithdrawMethodName { + res, err = c.withdraw(ctx, evm, contract, method, args) + } + return err + }) + if execErr != nil { + res, errPack := method.Outputs.Pack(false) + if errPack != nil { + return nil, errPack + } + + // Return the proper result (true/false) and the error message. + // This way we make bank compliant with smart contracts which would expect a true/false. + // And also with Go bindings which would expect an error. + return res, err + } + return res, nil + + case BalanceOfMethodName: + var res []byte + execErr := stateDB.ExecuteNativeAction(contract.Address(), nil, func(ctx sdk.Context) error { + res, err = c.balanceOf(ctx, method, args) + return err + }) + if execErr != nil { + return nil, err + } + return res, nil + + default: + return nil, ptypes.ErrInvalidMethod{ + Method: method.Name, + } + } +} + +// getEVMCallerAddress returns the caller address. +// Usually the caller is the contract.CallerAddress, which is the address of the contract that called the precompiled contract. +// If contract.CallerAddress != evm.Origin is true, it means the call was made through a contract, +// on which case there is a need to set the caller to the evm.Origin. +func getEVMCallerAddress(evm *vm.EVM, contract *vm.Contract) (common.Address, error) { + caller := contract.CallerAddress + if contract.CallerAddress != evm.Origin { + caller = evm.Origin + } + + return caller, nil +} + +// getCosmosAddress returns the counterpart cosmos address of the given ethereum address. +// It checks if the address is empty or blocked by the bank keeper. +func getCosmosAddress(bankKeeper bank.Keeper, addr common.Address) (sdk.AccAddress, error) { + toAddr := sdk.AccAddress(addr.Bytes()) + if toAddr.Empty() { + return nil, &ptypes.ErrInvalidAddr{ + Got: toAddr.String(), + Reason: "empty address", + } + } + + if bankKeeper.BlockedAddr(toAddr) { + return nil, &ptypes.ErrInvalidAddr{ + Got: toAddr.String(), + Reason: "destination address blocked by bank keeper", + } + } + + return toAddr, nil +} diff --git a/precompiles/bank/bank_test.go b/precompiles/bank/bank_test.go new file mode 100644 index 0000000000..518c330a7f --- /dev/null +++ b/precompiles/bank/bank_test.go @@ -0,0 +1,156 @@ +package bank + +import ( + "encoding/json" + "math/big" + "testing" + + storetypes "github.com/cosmos/cosmos-sdk/store/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/stretchr/testify/require" + ethermint "github.com/zeta-chain/ethermint/types" + "github.com/zeta-chain/node/testutil/keeper" + "github.com/zeta-chain/node/testutil/sample" +) + +func Test_IBankContract(t *testing.T) { + var encoding ethermint.EncodingConfig + appCodec := encoding.Codec + fungibleKeeper, ctx, keepers, _ := keeper.FungibleKeeper(t) + gasConfig := storetypes.TransientGasConfig() + + t.Run("should create contract and check address and ABI", func(t *testing.T) { + contract := NewIBankContract(ctx, keepers.BankKeeper, *fungibleKeeper, appCodec, gasConfig) + require.NotNil(t, contract, "NewIBankContract() should not return a nil contract") + + address := contract.Address() + require.Equal(t, ContractAddress, address, "contract address should match the precompiled address") + + abi := contract.Abi() + require.NotNil(t, abi, "contract ABI should not be nil") + }) + + t.Run("should check methods are present in ABI", func(t *testing.T) { + contract := NewIBankContract(ctx, keepers.BankKeeper, *fungibleKeeper, appCodec, gasConfig) + abi := contract.Abi() + + require.NotNil(t, abi.Methods[DepositMethodName], "deposit method should be present in the ABI") + require.NotNil(t, abi.Methods[WithdrawMethodName], "withdraw method should be present in the ABI") + require.NotNil(t, abi.Methods[BalanceOfMethodName], "balanceOf method should be present in the ABI") + }) + + t.Run("should check gas requirements for methods", func(t *testing.T) { + contract := NewIBankContract(ctx, keepers.BankKeeper, *fungibleKeeper, appCodec, gasConfig) + abi := contract.Abi() + var method [4]byte + + t.Run("deposit", func(t *testing.T) { + gasDeposit := contract.RequiredGas(abi.Methods[DepositMethodName].ID) + copy(method[:], abi.Methods[DepositMethodName].ID[:4]) + baseCost := uint64(len(method)) * gasConfig.WriteCostPerByte + require.Equal( + t, + GasRequiredByMethod[method]+baseCost, + gasDeposit, + "deposit method should require %d gas, got %d", + GasRequiredByMethod[method]+baseCost, + gasDeposit, + ) + }) + + t.Run("withdraw", func(t *testing.T) { + gasWithdraw := contract.RequiredGas(abi.Methods[WithdrawMethodName].ID) + copy(method[:], abi.Methods[WithdrawMethodName].ID[:4]) + baseCost := uint64(len(method)) * gasConfig.WriteCostPerByte + require.Equal( + t, + GasRequiredByMethod[method]+baseCost, + gasWithdraw, + "withdraw method should require %d gas, got %d", + GasRequiredByMethod[method]+baseCost, + gasWithdraw, + ) + }) + + t.Run("balanceOf", func(t *testing.T) { + gasBalanceOf := contract.RequiredGas(abi.Methods[BalanceOfMethodName].ID) + copy(method[:], abi.Methods[BalanceOfMethodName].ID[:4]) + baseCost := uint64(len(method)) * gasConfig.WriteCostPerByte + require.Equal( + t, + GasRequiredByMethod[method]+baseCost, + gasBalanceOf, + "balanceOf method should require %d gas, got %d", + GasRequiredByMethod[method]+baseCost, + gasBalanceOf, + ) + }) + + t.Run("invalid method", func(t *testing.T) { + invalidMethodBytes := []byte("invalidMethod") + gasInvalidMethod := contract.RequiredGas(invalidMethodBytes) + require.Equal( + t, + uint64(0), + gasInvalidMethod, + "invalid method should require %d gas, got %d", + uint64(0), + gasInvalidMethod, + ) + }) + }) +} + +func Test_InvalidMethod(t *testing.T) { + var encoding ethermint.EncodingConfig + appCodec := encoding.Codec + fungibleKeeper, ctx, keepers, _ := keeper.FungibleKeeper(t) + gasConfig := storetypes.TransientGasConfig() + + contract := NewIBankContract(ctx, keepers.BankKeeper, *fungibleKeeper, appCodec, gasConfig) + require.NotNil(t, contract, "NewIBankContract() should not return a nil contract") + + abi := contract.Abi() + require.NotNil(t, abi, "contract ABI should not be nil") + + _, doNotExist := abi.Methods["invalidMethod"] + require.False(t, doNotExist, "invalidMethod should not be present in the ABI") +} + +func Test_InvalidABI(t *testing.T) { + IBankMetaData.ABI = "invalid json" + defer func() { + if r := recover(); r != nil { + require.IsType(t, &json.SyntaxError{}, r, "expected error type: json.SyntaxError, got: %T", r) + } + }() + + initABI() +} + +func Test_getEVMCallerAddress(t *testing.T) { + mockEVM := vm.EVM{ + TxContext: vm.TxContext{ + Origin: common.Address{}, + }, + } + + mockVMContract := vm.NewContract( + contractRef{address: common.Address{}}, + contractRef{address: ContractAddress}, + big.NewInt(0), + 0, + ) + + // When contract.CallerAddress == evm.Origin, caller is set to contract.CallerAddress. + caller, err := getEVMCallerAddress(&mockEVM, mockVMContract) + require.NoError(t, err) + require.Equal(t, common.Address{}, caller, "address shouldn be the same") + + // When contract.CallerAddress != evm.Origin, caller should be set to evm.Origin. + mockEVM.Origin = sample.EthAddress() + caller, err = getEVMCallerAddress(&mockEVM, mockVMContract) + require.NoError(t, err) + require.Equal(t, mockEVM.Origin, caller, "address should be evm.Origin") +} diff --git a/precompiles/bank/bindings.go b/precompiles/bank/bindings.go new file mode 100644 index 0000000000..98f35ceeee --- /dev/null +++ b/precompiles/bank/bindings.go @@ -0,0 +1,7 @@ +//go:generate sh -c "solc IBank.sol --combined-json abi | jq '.contracts.\"IBank.sol:IBank\"' > IBank.json" +//go:generate sh -c "cat IBank.json | jq .abi > IBank.abi" +//go:generate sh -c "abigen --abi IBank.abi --pkg bank --type IBank --out IBank.gen.go" + +package bank + +var _ Contract diff --git a/precompiles/bank/coin.go b/precompiles/bank/coin.go new file mode 100644 index 0000000000..121ecdc1ee --- /dev/null +++ b/precompiles/bank/coin.go @@ -0,0 +1,43 @@ +package bank + +import ( + "math/big" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" + + ptypes "github.com/zeta-chain/node/precompiles/types" +) + +// ZRC20ToCosmosDenom returns the cosmos coin address for a given ZRC20 address. +// This is converted to "zevm/{ZRC20Address}". +func ZRC20ToCosmosDenom(ZRC20Address common.Address) string { + return ZRC20DenomPrefix + ZRC20Address.String() +} + +func createCoinSet(tokenDenom string, amount *big.Int) (sdk.Coins, error) { + coin := sdk.NewCoin(tokenDenom, math.NewIntFromBigInt(amount)) + if !coin.IsValid() { + return nil, &ptypes.ErrInvalidCoin{ + Got: coin.GetDenom(), + Negative: coin.IsNegative(), + Nil: coin.IsNil(), + } + } + + // A sdk.Coins (type []sdk.Coin) has to be created because it's the type expected by MintCoins + // and SendCoinsFromModuleToAccount. + // But sdk.Coins will only contain one coin, always. + coinSet := sdk.NewCoins(coin) + if !coinSet.IsValid() || coinSet.Empty() || coinSet.IsAnyNil() || coinSet == nil { + return nil, &ptypes.ErrInvalidCoin{ + Got: coinSet.String(), + Negative: coinSet.IsAnyNegative(), + Nil: coinSet.IsAnyNil(), + Empty: coinSet.Empty(), + } + } + + return coinSet, nil +} diff --git a/precompiles/bank/coin_test.go b/precompiles/bank/coin_test.go new file mode 100644 index 0000000000..0a9669e0a6 --- /dev/null +++ b/precompiles/bank/coin_test.go @@ -0,0 +1,29 @@ +package bank + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func Test_ZRC20ToCosmosDenom(t *testing.T) { + address := big.NewInt(12345) // 0x3039 + expected := "zrc20/0x0000000000000000000000000000000000003039" + denom := ZRC20ToCosmosDenom(common.BigToAddress(address)) + require.Equal(t, expected, denom, "denom should be %s, got %s", expected, denom) +} + +func Test_createCoinSet(t *testing.T) { + tokenDenom := "zrc20/0x0000000000000000000000000000000000003039" + amount := big.NewInt(100) + + coinSet, err := createCoinSet(tokenDenom, amount) + require.NoError(t, err, "createCoinSet should not return an error") + require.NotNil(t, coinSet, "coinSet should not be nil") + + coin := coinSet[0] + require.Equal(t, tokenDenom, coin.Denom, "coin denom should be %s, got %s", tokenDenom, coin.Denom) + require.Equal(t, amount, coin.Amount.BigInt(), "coin amount should be %s, got %s", amount, coin.Amount.BigInt()) +} diff --git a/precompiles/bank/const.go b/precompiles/bank/const.go new file mode 100644 index 0000000000..333bb5a76f --- /dev/null +++ b/precompiles/bank/const.go @@ -0,0 +1,22 @@ +package bank + +const ( + // ZRC20DenomPrefix are ZRC20 cosmos coins prefix. + ZRC20DenomPrefix = "zrc20/" + + // Write methods. + DepositMethodName = "deposit" + DepositMethodGas = 200_000 + DepositEventName = "Deposit" + + WithdrawMethodName = "withdraw" + WithdrawMethodGas = 200_000 + WithdrawEventName = "Withdraw" + + // Read methods. + BalanceOfMethodName = "balanceOf" + BalanceOfGas = 10_000 + + // Default gas for unknown methods. + DefaultGas = 0 +) diff --git a/precompiles/bank/logs.go b/precompiles/bank/logs.go new file mode 100644 index 0000000000..36b877dfa5 --- /dev/null +++ b/precompiles/bank/logs.go @@ -0,0 +1,50 @@ +package bank + +import ( + "math/big" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + + "github.com/zeta-chain/node/precompiles/logs" +) + +type eventData struct { + zrc20Addr common.Address + zrc20Token common.Address + cosmosAddr string + cosmosCoin string + amount *big.Int +} + +func (c *Contract) addEventLog( + ctx sdk.Context, + stateDB vm.StateDB, + eventName string, + eventData eventData, +) error { + event := c.Abi().Events[eventName] + + topics, err := logs.MakeTopics( + event, + []interface{}{common.BytesToAddress(eventData.zrc20Addr.Bytes())}, + []interface{}{common.BytesToAddress(eventData.zrc20Token.Bytes())}, + []interface{}{eventData.cosmosCoin}, + ) + if err != nil { + return err + } + + data, err := logs.PackArguments([]logs.Argument{ + {Type: "string", Value: eventData.cosmosAddr}, + {Type: "uint256", Value: eventData.amount}, + }) + if err != nil { + return err + } + + logs.AddLog(ctx, c.Address(), stateDB, topics, data) + + return nil +} diff --git a/precompiles/bank/method_balance_of.go b/precompiles/bank/method_balance_of.go new file mode 100644 index 0000000000..e4bc644a2b --- /dev/null +++ b/precompiles/bank/method_balance_of.go @@ -0,0 +1,80 @@ +package bank + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + + ptypes "github.com/zeta-chain/node/precompiles/types" +) + +// balanceOf returns the balance of cosmos coins minted by the bank's deposit function, +// for a given cosmos account calculated with toAddr := sdk.AccAddress(addr.Bytes()). +// The denomination of the cosmos coin will be "zrc20/0x12345" where 0x12345 is the ZRC20 address. +// Call this function using solidity with the following signature: +// From IBank.sol: function balanceOf(address zrc20, address user) external view returns (uint256 balance); +func (c *Contract) balanceOf( + ctx sdk.Context, + method *abi.Method, + args []interface{}, +) (result []byte, err error) { + if len(args) != 2 { + return nil, &(ptypes.ErrInvalidNumberOfArgs{ + Got: len(args), + Expect: 2, + }) + } + + // function balanceOf(address zrc20, address user) external view returns (uint256 balance); + zrc20Addr, addr, err := unpackBalanceOfArgs(args) + if err != nil { + return nil, err + } + + // Get the counterpart cosmos address. + toAddr, err := getCosmosAddress(c.bankKeeper, addr) + if err != nil { + return nil, err + } + + // Safety check: token has to be a valid whitelisted ZRC20 and not be paused. + // Do not check for t.Paused, as the balance is read only the EOA won't be able to operate. + _, found := c.fungibleKeeper.GetForeignCoins(ctx, zrc20Addr.String()) + if !found { + return nil, &ptypes.ErrInvalidToken{ + Got: zrc20Addr.String(), + Reason: "token is not a whitelisted ZRC20", + } + } + + // Bank Keeper GetBalance returns the specified Cosmos coin balance for a given address. + // Check explicitly the balance is a non-negative non-nil value. + coin := c.bankKeeper.GetBalance(ctx, toAddr, ZRC20ToCosmosDenom(zrc20Addr)) + if !coin.IsValid() { + return nil, &ptypes.ErrInvalidCoin{ + Got: coin.GetDenom(), + Negative: coin.IsNegative(), + Nil: coin.IsNil(), + } + } + + return method.Outputs.Pack(coin.Amount.BigInt()) +} + +func unpackBalanceOfArgs(args []interface{}) (zrc20Addr common.Address, addr common.Address, err error) { + zrc20Addr, ok := args[0].(common.Address) + if !ok { + return common.Address{}, common.Address{}, &ptypes.ErrInvalidAddr{ + Got: zrc20Addr.String(), + } + } + + addr, ok = args[1].(common.Address) + if !ok { + return common.Address{}, common.Address{}, &ptypes.ErrInvalidAddr{ + Got: addr.String(), + } + } + + return zrc20Addr, addr, nil +} diff --git a/precompiles/bank/method_deposit.go b/precompiles/bank/method_deposit.go new file mode 100644 index 0000000000..2f57944723 --- /dev/null +++ b/precompiles/bank/method_deposit.go @@ -0,0 +1,215 @@ +package bank + +import ( + "math/big" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + + ptypes "github.com/zeta-chain/node/precompiles/types" + "github.com/zeta-chain/node/x/fungible/types" +) + +// deposit is used to deposit ZRC20 into the bank contract, and receive the same amount of cosmos coins in exchange. +// The denomination of the cosmos coin will be "zrc20/ZRC20Address", as an example depossiting an arbitrary ZRC20 token with +// address 0x12345 will mint cosmos coins with the denomination "zrc20/0x12345". +// The caller cosmos address will be calculated from the EVM caller address. by executing toAddr := sdk.AccAddress(addr.Bytes()). +// This function can be think of a permissionless way of minting cosmos coins. +// This is how deposit works: +// - The caller has to allow the bank contract to spend a certain amount ZRC20 token coins on its behalf. This is mandatory. +// - Then, the caller calls deposit(ZRC20 address, amount), to deposit the amount and receive cosmos coins. +// - The bank will check there's enough balance, the caller is not a blocked address, and the token is a not paused ZRC20. +// - Then the cosmos coins "zrc20/0x12345" will be minted and sent to the caller's cosmos address. +// Call this function using solidity with the following signature: +// - From IBank.sol: function deposit(address zrc20, uint256 amount) external returns (bool success); +func (c *Contract) deposit( + ctx sdk.Context, + evm *vm.EVM, + contract *vm.Contract, + method *abi.Method, + args []interface{}, +) (result []byte, err error) { + // This function is developed using the Check - Effects - Interactions pattern: + // 1. Check everything is correct. + if len(args) != 2 { + return nil, &(ptypes.ErrInvalidNumberOfArgs{ + Got: len(args), + Expect: 2, + }) + } + + // Unpack parameters for function deposit. + // function deposit(address zrc20, uint256 amount) external returns (bool success); + zrc20Addr, amount, err := unpackDepositArgs(args) + if err != nil { + return nil, err + } + + // Get the correct caller address. + caller, err := getEVMCallerAddress(evm, contract) + if err != nil { + return nil, err + } + + // Get the cosmos address of the caller. + toAddr, err := getCosmosAddress(c.bankKeeper, caller) + if err != nil { + return nil, err + } + + // Safety check: token has to be a valid whitelisted ZRC20 and not be paused. + t, found := c.fungibleKeeper.GetForeignCoins(ctx, zrc20Addr.String()) + if !found { + return nil, &ptypes.ErrInvalidToken{ + Got: zrc20Addr.String(), + Reason: "token is not a whitelisted ZRC20", + } + } + + if t.Paused { + return nil, &ptypes.ErrInvalidToken{ + Got: zrc20Addr.String(), + Reason: "token is paused", + } + } + + // Check for enough balance. + // function balanceOf(address account) public view virtual override returns (uint256) + resBalanceOf, err := c.CallContract( + ctx, + &c.fungibleKeeper, + c.zrc20ABI, + zrc20Addr, + "balanceOf", + []interface{}{caller}, + ) + if err != nil { + return nil, &ptypes.ErrUnexpected{ + When: "balanceOf", + Got: err.Error(), + } + } + + balance, ok := resBalanceOf[0].(*big.Int) + if !ok { + return nil, &ptypes.ErrUnexpected{ + Got: "ZRC20 balanceOf returned an unexpected type", + } + } + + if balance.Cmp(amount) < 0 || balance.Cmp(big.NewInt(0)) <= 0 { + return nil, &ptypes.ErrInvalidAmount{ + Got: balance.String(), + } + } + + // Check for enough bank's allowance. + // function allowance(address owner, address spender) public view virtual override returns (uint256) + resAllowance, err := c.CallContract( + ctx, + &c.fungibleKeeper, + c.zrc20ABI, + zrc20Addr, + "allowance", + []interface{}{caller, ContractAddress}, + ) + if err != nil { + return nil, &ptypes.ErrUnexpected{ + When: "allowance", + Got: err.Error(), + } + } + + allowance, ok := resAllowance[0].(*big.Int) + if !ok { + return nil, &ptypes.ErrUnexpected{ + Got: "ZRC20 allowance returned an unexpected type", + } + } + + if allowance.Cmp(amount) < 0 || allowance.Cmp(big.NewInt(0)) <= 0 { + return nil, &ptypes.ErrInvalidAmount{ + Got: allowance.String(), + } + } + + // The process of creating a new cosmos coin is: + // - Generate the new coin denom using ZRC20 address, + // this way we map ZRC20 addresses to cosmos denoms "zevm/0x12345". + // - Mint coins. + // - Send coins to the caller. + coinSet, err := createCoinSet(ZRC20ToCosmosDenom(zrc20Addr), amount) + if err != nil { + return nil, err + } + + // 2. Effect: subtract balance. + // function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) + resTransferFrom, err := c.CallContract( + ctx, + &c.fungibleKeeper, + c.zrc20ABI, + zrc20Addr, + "transferFrom", + []interface{}{caller, ContractAddress, amount}, + ) + if err != nil { + return nil, &ptypes.ErrUnexpected{ + When: "transferFrom", + Got: err.Error(), + } + } + + transferred, ok := resTransferFrom[0].(bool) + if !ok || !transferred { + return nil, &ptypes.ErrUnexpected{ + When: "transferFrom", + Got: "transaction not successful", + } + } + + // 3. Interactions: create cosmos coin and send. + if err := c.bankKeeper.MintCoins(ctx, types.ModuleName, coinSet); err != nil { + return nil, &ptypes.ErrUnexpected{ + When: "MintCoins", + Got: err.Error(), + } + } + + err = c.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, toAddr, coinSet) + if err != nil { + return nil, &ptypes.ErrUnexpected{ + When: "SendCoinsFromModuleToAccount", + Got: err.Error(), + } + } + + if err := c.addEventLog(ctx, evm.StateDB, DepositEventName, eventData{caller, zrc20Addr, toAddr.String(), coinSet.Denoms()[0], amount}); err != nil { + return nil, &ptypes.ErrUnexpected{ + When: "AddDepositLog", + Got: err.Error(), + } + } + + return method.Outputs.Pack(true) +} + +func unpackDepositArgs(args []interface{}) (zrc20Addr common.Address, amount *big.Int, err error) { + zrc20Addr, ok := args[0].(common.Address) + if !ok { + return common.Address{}, nil, &ptypes.ErrInvalidAddr{ + Got: zrc20Addr.String(), + } + } + + amount, ok = args[1].(*big.Int) + if !ok || amount.Sign() < 0 || amount == nil || amount == new(big.Int) { + return common.Address{}, nil, &ptypes.ErrInvalidAmount{ + Got: amount.String(), + } + } + + return zrc20Addr, amount, nil +} diff --git a/precompiles/bank/method_test.go b/precompiles/bank/method_test.go new file mode 100644 index 0000000000..912c41b40c --- /dev/null +++ b/precompiles/bank/method_test.go @@ -0,0 +1,730 @@ +package bank + +import ( + "math/big" + "testing" + + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/require" + ethermint "github.com/zeta-chain/ethermint/types" + evmkeeper "github.com/zeta-chain/ethermint/x/evm/keeper" + "github.com/zeta-chain/ethermint/x/evm/statedb" + "github.com/zeta-chain/node/pkg/chains" + erc1967proxy "github.com/zeta-chain/node/pkg/contracts/erc1967proxy" + ptypes "github.com/zeta-chain/node/precompiles/types" + "github.com/zeta-chain/node/testutil/keeper" + "github.com/zeta-chain/node/testutil/sample" + fungiblekeeper "github.com/zeta-chain/node/x/fungible/keeper" + fungibletypes "github.com/zeta-chain/node/x/fungible/types" + gatewayzevm "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol" + "github.com/zeta-chain/protocol-contracts/v2/pkg/zrc20.sol" +) + +func Test_Methods(t *testing.T) { + t.Run("should fail when trying to run deposit as read only method", func(t *testing.T) { + ts := setupChain(t) + caller := fungibletypes.ModuleAddressEVM + methodID := ts.bankABI.Methods[DepositMethodName] + + // Set CallerAddress and evm.Origin to the caller address. + // Caller does not have any balance, and bank does not have any allowance. + ts.mockVMContract.CallerAddress = caller + ts.mockEVM.Origin = caller + + // Set the input arguments for the deposit method. + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, big.NewInt(0)}..., + ) + + success, err := ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, true) + require.ErrorIs( + t, + ptypes.ErrUnexpected{ + Got: "method not allowed in read-only mode: deposit", + }, + err) + require.Empty(t, success) + }) + + t.Run("should fail when trying to run withdraw as read only method", func(t *testing.T) { + ts := setupChain(t) + caller := fungibletypes.ModuleAddressEVM + methodID := ts.bankABI.Methods[WithdrawMethodName] + + // Set CallerAddress and evm.Origin to the caller address. + // Caller does not have any balance, and bank does not have any allowance. + ts.mockVMContract.CallerAddress = caller + ts.mockEVM.Origin = caller + + // Set the input arguments for the deposit method. + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, big.NewInt(0)}..., + ) + + success, err := ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, true) + require.ErrorIs( + t, + ptypes.ErrUnexpected{ + Got: "method not allowed in read-only mode: withdraw", + }, + err) + require.Empty(t, success) + }) + + t.Run("should fail when caller has 0 token balance", func(t *testing.T) { + ts := setupChain(t) + caller := fungibletypes.ModuleAddressEVM + methodID := ts.bankABI.Methods[DepositMethodName] + + // Set CallerAddress and evm.Origin to the caller address. + // Caller does not have any balance, and bank does not have any allowance. + ts.mockVMContract.CallerAddress = caller + ts.mockEVM.Origin = caller + + // Set the input arguments for the deposit method. + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, big.NewInt(0)}..., + ) + + success, err := ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + require.Error(t, err) + require.ErrorAs( + t, + ptypes.ErrInvalidAmount{ + Got: "0", + }, + err, + ) + + res, err := ts.bankABI.Methods[DepositMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + ok := res[0].(bool) + require.False(t, ok) + }) + + t.Run("should fail when bank has 0 token allowance", func(t *testing.T) { + ts := setupChain(t) + caller := fungibletypes.ModuleAddressEVM + ts.fungibleKeeper.DepositZRC20(ts.ctx, ts.zrc20Address, caller, big.NewInt(1000)) + + methodID := ts.bankABI.Methods[DepositMethodName] + + // Set CallerAddress and evm.Origin to the caller address. + // Caller does not have any balance, and bank does not have any allowance. + ts.mockVMContract.CallerAddress = caller + ts.mockEVM.Origin = caller + + // Set the input arguments for the deposit method. + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, big.NewInt(0)}..., + ) + + success, err := ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + require.Error(t, err) + require.ErrorAs( + t, + ptypes.ErrInvalidAmount{ + Got: "0", + }, + err, + ) + + res, err := ts.bankABI.Methods[DepositMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + ok := res[0].(bool) + require.False(t, ok) + }) + + t.Run("should fail when trying to deposit more than allowed to bank", func(t *testing.T) { + ts := setupChain(t) + caller := fungibletypes.ModuleAddressEVM + ts.fungibleKeeper.DepositZRC20(ts.ctx, ts.zrc20Address, caller, big.NewInt(1000)) + + // Allow bank to spend 500 ZRC20 tokens. + allowBank(t, ts, big.NewInt(500)) + + // Set CallerAddress and evm.Origin to the caller address. + ts.mockVMContract.CallerAddress = caller + ts.mockEVM.Origin = caller + + // Prepare and call the deposit method. + methodID := ts.bankABI.Methods[DepositMethodName] + + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, big.NewInt(501)}..., + ) + + success, err := ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + require.Error(t, err) + require.ErrorAs( + t, + ptypes.ErrInvalidAmount{ + Got: "500", + }, + err, + ) + + res, err := ts.bankABI.Methods[DepositMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + ok := res[0].(bool) + require.False(t, ok) + + // Prepare and call the balanceOf method. + methodID = ts.bankABI.Methods[BalanceOfMethodName] + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, caller}..., + ) + + success, err = ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + resultBalanceOf, err := ts.bankABI.Methods[BalanceOfMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + balance, ok := resultBalanceOf[0].(*big.Int) + require.True(t, ok) + require.EqualValues(t, big.NewInt(0).Uint64(), balance.Uint64()) + }) + + t.Run("should fail when trying to deposit more than user balance", func(t *testing.T) { + ts := setupChain(t) + caller := fungibletypes.ModuleAddressEVM + ts.fungibleKeeper.DepositZRC20(ts.ctx, ts.zrc20Address, caller, big.NewInt(1000)) + + // Allow bank to spend 500 ZRC20 tokens. + allowBank(t, ts, big.NewInt(1000)) + + // Set CallerAddress and evm.Origin to the caller address. + ts.mockVMContract.CallerAddress = caller + ts.mockEVM.Origin = caller + + // Prepare and call the deposit method. + methodID := ts.bankABI.Methods[DepositMethodName] + + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, big.NewInt(1001)}..., + ) + + success, err := ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + require.Error(t, err) + require.ErrorAs( + t, + ptypes.ErrInvalidAmount{ + Got: "1000", + }, + err, + ) + + res, err := ts.bankABI.Methods[DepositMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + ok := res[0].(bool) + require.False(t, ok) + + // Prepare and call the balanceOf method. + methodID = ts.bankABI.Methods[BalanceOfMethodName] + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, caller}..., + ) + + success, err = ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + resultBalanceOf, err := ts.bankABI.Methods[BalanceOfMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + balance, ok := resultBalanceOf[0].(*big.Int) + require.True(t, ok) + require.EqualValues(t, big.NewInt(0).Uint64(), balance.Uint64()) + }) + + t.Run("should deposit tokens and retrieve balance of cosmos coin", func(t *testing.T) { + ts := setupChain(t) + caller := fungibletypes.ModuleAddressEVM + ts.fungibleKeeper.DepositZRC20(ts.ctx, ts.zrc20Address, caller, big.NewInt(1000)) + methodID := ts.bankABI.Methods[DepositMethodName] + + // Allow bank to spend 500 ZRC20 tokens. + allowBank(t, ts, big.NewInt(500)) + + // Set CallerAddress and evm.Origin to the caller address. + ts.mockVMContract.CallerAddress = caller + ts.mockEVM.Origin = caller + + // Prepare and call the deposit method. + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, big.NewInt(500)}..., + ) + + success, err := ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + require.NoError(t, err) + + res, err := ts.bankABI.Methods[DepositMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + ok := res[0].(bool) + require.True(t, ok) + + // Prepare and call the balanceOf method. + methodID = ts.bankABI.Methods[BalanceOfMethodName] + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, caller}..., + ) + + success, err = ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + resultBalanceOf, err := ts.bankABI.Methods[BalanceOfMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + balance, ok := resultBalanceOf[0].(*big.Int) + require.True(t, ok) + require.Equal(t, big.NewInt(500), balance) + }) + + t.Run("should deposit tokens, withdraw and check with balanceOf", func(t *testing.T) { + ts := setupChain(t) + caller := fungibletypes.ModuleAddressEVM + ts.fungibleKeeper.DepositZRC20(ts.ctx, ts.zrc20Address, caller, big.NewInt(1000)) + methodID := ts.bankABI.Methods[DepositMethodName] + + // Allow bank to spend 500 ZRC20 tokens. + allowBank(t, ts, big.NewInt(500)) + + // Set CallerAddress and evm.Origin to the caller address. + ts.mockVMContract.CallerAddress = caller + ts.mockEVM.Origin = caller + + // Prepare and call the deposit method. + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, big.NewInt(500)}..., + ) + + success, err := ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + require.NoError(t, err) + + res, err := ts.bankABI.Methods[DepositMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + ok := res[0].(bool) + require.True(t, ok) + + // Prepare and call the balanceOf method. + methodID = ts.bankABI.Methods[BalanceOfMethodName] + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, caller}..., + ) + + success, err = ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + resultBalanceOf, err := ts.bankABI.Methods[BalanceOfMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + balance, ok := resultBalanceOf[0].(*big.Int) + require.True(t, ok) + require.Equal(t, big.NewInt(500).Uint64(), balance.Uint64()) + + // Prepare and call the withdraw method. + methodID = ts.bankABI.Methods[WithdrawMethodName] + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, big.NewInt(500)}..., + ) + + success, err = ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + require.NoError(t, err) + + res, err = ts.bankABI.Methods[WithdrawMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + ok = res[0].(bool) + require.True(t, ok) + + // Prepare and call the balanceOf method. + methodID = ts.bankABI.Methods[BalanceOfMethodName] + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, caller}..., + ) + + success, err = ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + resultBalanceOf, err = ts.bankABI.Methods[BalanceOfMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + balance, ok = resultBalanceOf[0].(*big.Int) + require.True(t, ok) + require.Equal(t, big.NewInt(0).Uint64(), balance.Uint64()) + }) + + t.Run("should deposit tokens and fail when withdrawing more than depositted", func(t *testing.T) { + ts := setupChain(t) + caller := fungibletypes.ModuleAddressEVM + ts.fungibleKeeper.DepositZRC20(ts.ctx, ts.zrc20Address, caller, big.NewInt(1000)) + methodID := ts.bankABI.Methods[DepositMethodName] + + // Allow bank to spend 500 ZRC20 tokens. + allowBank(t, ts, big.NewInt(500)) + + // Set CallerAddress and evm.Origin to the caller address. + ts.mockVMContract.CallerAddress = caller + ts.mockEVM.Origin = caller + + // Prepare and call the deposit method. + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, big.NewInt(500)}..., + ) + + success, err := ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + require.NoError(t, err) + + res, err := ts.bankABI.Methods[DepositMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + ok := res[0].(bool) + require.True(t, ok) + + // Prepare and call the balanceOf method. + methodID = ts.bankABI.Methods[BalanceOfMethodName] + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, caller}..., + ) + + success, err = ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + resultBalanceOf, err := ts.bankABI.Methods[BalanceOfMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + balance, ok := resultBalanceOf[0].(*big.Int) + require.True(t, ok) + require.Equal(t, big.NewInt(500).Uint64(), balance.Uint64()) + + // Prepare and call the withdraw method. + methodID = ts.bankABI.Methods[WithdrawMethodName] + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, big.NewInt(501)}..., + ) + + success, err = ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + require.Error(t, err) + require.ErrorAs( + t, + ptypes.ErrInsufficientBalance{ + Requested: "501", + Got: "500", + }, + err, + ) + + res, err = ts.bankABI.Methods[WithdrawMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + ok = res[0].(bool) + require.False(t, ok) + + // Prepare and call the balanceOf method. + methodID = ts.bankABI.Methods[BalanceOfMethodName] + ts.mockVMContract.Input = packInputArgs( + t, + methodID, + []interface{}{ts.zrc20Address, caller}..., + ) + + success, err = ts.bankContract.Run(ts.mockEVM, ts.mockVMContract, false) + resultBalanceOf, err = ts.bankABI.Methods[BalanceOfMethodName].Outputs.Unpack(success) + require.NoError(t, err) + + balance, ok = resultBalanceOf[0].(*big.Int) + require.True(t, ok) + require.Equal(t, big.NewInt(500).Uint64(), balance.Uint64()) + }) +} + +/* + Test utils. +*/ + +type testSuite struct { + ctx sdk.Context + fungibleKeeper *fungiblekeeper.Keeper + sdkKeepers keeper.SDKKeepers + bankContract *Contract + bankABI abi.ABI + mockEVM *vm.EVM + mockVMContract *vm.Contract + zrc20Address common.Address + zrc20ABI abi.ABI +} + +func setupChain(t *testing.T) testSuite { + // Initialize basic parameters to mock the chain. + fungibleKeeper, ctx, sdkKeepers, _ := keeper.FungibleKeeper(t) + chainID := getValidChainID(t) + + // Make sure the account store is initialized. + // This is completely needed for accounts to be created in the state. + fungibleKeeper.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + + // Deploy system contracts in order to deploy a ZRC20 token. + deploySystemContracts(t, ctx, fungibleKeeper, *sdkKeepers.EvmKeeper) + zrc20Address := setupGasCoin(t, ctx, fungibleKeeper, sdkKeepers.EvmKeeper, chainID, "ZRC20", "ZRC20") + + // Keepers and chain configuration. + var encoding ethermint.EncodingConfig + appCodec := encoding.Codec + gasConfig := storetypes.TransientGasConfig() + + // Create the bank contract. + contract := NewIBankContract(ctx, sdkKeepers.BankKeeper, *fungibleKeeper, appCodec, gasConfig) + require.NotNil(t, contract, "NewIBankContract() should not return a nil contract") + + abi := contract.Abi() + require.NotNil(t, abi, "contract ABI should not be nil") + + address := contract.Address() + require.NotNil(t, address, "contract address should not be nil") + + zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() + if err != nil { + return testSuite{} + } + + mockEVM := vm.NewEVM( + vm.BlockContext{}, + vm.TxContext{}, + statedb.New(ctx, sdkKeepers.EvmKeeper, statedb.TxConfig{}), + ¶ms.ChainConfig{}, + vm.Config{}, + ) + + mockVMContract := vm.NewContract( + contractRef{address: common.Address{}}, + contractRef{address: ContractAddress}, + big.NewInt(0), + 0, + ) + + return testSuite{ + ctx, + fungibleKeeper, + sdkKeepers, + contract, + abi, + mockEVM, + mockVMContract, + zrc20Address, + *zrc20ABI, + } +} + +func allowBank(t *testing.T, ts testSuite, amount *big.Int) { + resAllowance, err := callEVM( + t, + ts.ctx, + ts.fungibleKeeper, + &ts.zrc20ABI, + fungibletypes.ModuleAddressEVM, + ts.zrc20Address, + "approve", + []interface{}{ts.bankContract.Address(), amount}, + ) + require.NoError(t, err, "error allowing bank to spend ZRC20 tokens") + + allowed, ok := resAllowance[0].(bool) + require.True(t, ok) + require.True(t, allowed) +} + +func callEVM( + t *testing.T, + ctx sdk.Context, + fungibleKeeper *fungiblekeeper.Keeper, + abi *abi.ABI, + from common.Address, + dst common.Address, + method string, + args []interface{}, +) ([]interface{}, error) { + res, err := fungibleKeeper.CallEVM( + ctx, // ctx + *abi, // abi + from, // from + dst, // to + big.NewInt(0), // value + nil, // gasLimit + true, // commit + true, // noEthereumTxEvent + method, // method + args..., // args + ) + require.NoError(t, err, "CallEVM error") + require.Equal(t, "", res.VmError, "res.VmError should be empty") + + ret, err := abi.Methods[method].Outputs.Unpack(res.Ret) + require.NoError(t, err, "Unpack error") + + return ret, nil +} + +// setupGasCoin is a helper function to setup the gas coin for testing +func setupGasCoin( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + evmk *evmkeeper.Keeper, + chainID int64, + assetName string, + symbol string, +) (zrc20 common.Address) { + addr, err := k.SetupChainGasCoinAndPool( + ctx, + chainID, + assetName, + symbol, + 8, + nil, + ) + require.NoError(t, err) + assertContractDeployment(t, *evmk, ctx, addr) + return addr +} + +// get a valid chain id independently of the build flag +func getValidChainID(t *testing.T) int64 { + list := chains.DefaultChainsList() + require.NotEmpty(t, list) + require.NotNil(t, list[0]) + return list[0].ChainId +} + +// require that a contract has been deployed by checking stored code is non-empty. +func assertContractDeployment(t *testing.T, k evmkeeper.Keeper, ctx sdk.Context, contractAddress common.Address) { + acc := k.GetAccount(ctx, contractAddress) + require.NotNil(t, acc) + code := k.GetCode(ctx, common.BytesToHash(acc.CodeHash)) + require.NotEmpty(t, code) +} + +// deploySystemContracts deploys the system contracts and returns their addresses. +func deploySystemContracts( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + evmk evmkeeper.Keeper, +) (wzeta, uniswapV2Factory, uniswapV2Router, connector, systemContract common.Address) { + var err error + + wzeta, err = k.DeployWZETA(ctx) + require.NoError(t, err) + require.NotEmpty(t, wzeta) + assertContractDeployment(t, evmk, ctx, wzeta) + + uniswapV2Factory, err = k.DeployUniswapV2Factory(ctx) + require.NoError(t, err) + require.NotEmpty(t, uniswapV2Factory) + assertContractDeployment(t, evmk, ctx, uniswapV2Factory) + + uniswapV2Router, err = k.DeployUniswapV2Router02(ctx, uniswapV2Factory, wzeta) + require.NoError(t, err) + require.NotEmpty(t, uniswapV2Router) + assertContractDeployment(t, evmk, ctx, uniswapV2Router) + + connector, err = k.DeployConnectorZEVM(ctx, wzeta) + require.NoError(t, err) + require.NotEmpty(t, connector) + assertContractDeployment(t, evmk, ctx, connector) + + systemContract, err = k.DeploySystemContract(ctx, wzeta, uniswapV2Factory, uniswapV2Router) + require.NoError(t, err) + require.NotEmpty(t, systemContract) + assertContractDeployment(t, evmk, ctx, systemContract) + + // deploy the gateway contract + contract := deployGatewayContract(t, ctx, k, &evmk, wzeta, sample.EthAddress()) + require.NotEmpty(t, contract) + + return +} + +// deploy upgradable gateway contract and return its address +func deployGatewayContract( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + evmk *evmkeeper.Keeper, + wzeta, admin common.Address, +) common.Address { + // Deploy the gateway contract + implAddr, err := k.DeployContract(ctx, gatewayzevm.GatewayZEVMMetaData) + require.NoError(t, err) + require.NotEmpty(t, implAddr) + assertContractDeployment(t, *evmk, ctx, implAddr) + + // Deploy the proxy contract + gatewayABI, err := gatewayzevm.GatewayZEVMMetaData.GetAbi() + require.NoError(t, err) + + // Encode the initializer data + initializerData, err := gatewayABI.Pack("initialize", wzeta, admin) + require.NoError(t, err) + + gatewayContract, err := k.DeployContract(ctx, erc1967proxy.ERC1967ProxyMetaData, implAddr, initializerData) + require.NoError(t, err) + require.NotEmpty(t, gatewayContract) + assertContractDeployment(t, *evmk, ctx, gatewayContract) + + // store the gateway in the system contract object + sys, found := k.GetSystemContract(ctx) + if !found { + sys = fungibletypes.SystemContract{} + } + sys.Gateway = gatewayContract.Hex() + k.SetSystemContract(ctx, sys) + + return gatewayContract +} + +func packInputArgs(t *testing.T, methodID abi.Method, args ...interface{}) []byte { + input, err := methodID.Inputs.Pack(args...) + require.NoError(t, err) + return append(methodID.ID, input...) +} + +type contractRef struct { + address common.Address +} + +func (c contractRef) Address() common.Address { + return c.address +} diff --git a/precompiles/bank/method_withdraw.go b/precompiles/bank/method_withdraw.go new file mode 100644 index 0000000000..99cb4f763c --- /dev/null +++ b/precompiles/bank/method_withdraw.go @@ -0,0 +1,198 @@ +package bank + +import ( + "math/big" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + + ptypes "github.com/zeta-chain/node/precompiles/types" + "github.com/zeta-chain/node/x/fungible/types" +) + +// withdraw is used to withdraw cosmos coins minted using the bank's deposit function. +// The caller has to have enough cosmos coin on its cosmos account balance to withdraw the requested amount. +// After all check pass the bank will burn the cosmos coins and transfer the ZRC20 amount to the withdrawer. +// The cosmos coins have the denomination of "zrc20/0x12345" where 0x12345 is the ZRC20 address. +// Call this function using solidity with the following signature: +// From IBank.sol: function withdraw(address zrc20, uint256 amount) external returns (bool success); +// The address to be passed to the function is the ZRC20 address, like in 0x12345. +func (c *Contract) withdraw( + ctx sdk.Context, + evm *vm.EVM, + contract *vm.Contract, + method *abi.Method, + args []interface{}, +) (result []byte, err error) { + // 1. Check everything is correct. + if len(args) != 2 { + return nil, &(ptypes.ErrInvalidNumberOfArgs{ + Got: len(args), + Expect: 2, + }) + } + + // Unpack parameters for function withdraw. + // function withdraw(address zrc20, uint256 amount) external returns (bool success); + zrc20Addr, amount, err := unpackWithdrawArgs(args) + if err != nil { + return nil, err + } + + // Get the correct caller address. + caller, err := getEVMCallerAddress(evm, contract) + if err != nil { + return nil, err + } + + // Get the cosmos address of the caller. + // This address should have enough cosmos coin balance as the requested amount. + fromAddr, err := getCosmosAddress(c.bankKeeper, caller) + if err != nil { + return nil, err + } + + // Safety check: token has to be a valid whitelisted ZRC20 and not be paused. + t, found := c.fungibleKeeper.GetForeignCoins(ctx, zrc20Addr.String()) + if !found { + return nil, &ptypes.ErrInvalidToken{ + Got: zrc20Addr.String(), + Reason: "token is not a whitelisted ZRC20", + } + } + + if t.Paused { + return nil, &ptypes.ErrInvalidToken{ + Got: zrc20Addr.String(), + Reason: "token is paused", + } + } + + // Caller has to have enough cosmos coin balance to withdraw the requested amount. + coin := c.bankKeeper.GetBalance(ctx, fromAddr, ZRC20ToCosmosDenom(zrc20Addr)) + if !coin.IsValid() { + return nil, &ptypes.ErrInsufficientBalance{ + Requested: amount.String(), + Got: "invalid coin", + } + } + + if coin.Amount.LT(math.NewIntFromBigInt(amount)) { + return nil, &ptypes.ErrInsufficientBalance{ + Requested: amount.String(), + Got: coin.Amount.String(), + } + } + + coinSet, err := createCoinSet(ZRC20ToCosmosDenom(zrc20Addr), amount) + if err != nil { + return nil, err + } + + // Check for bank's ZRC20 balance. + // function balanceOf(address account) public view virtual override returns (uint256) + resBalanceOf, err := c.CallContract( + ctx, + &c.fungibleKeeper, + c.zrc20ABI, + zrc20Addr, + "balanceOf", + []interface{}{ContractAddress}, + ) + if err != nil { + return nil, &ptypes.ErrUnexpected{ + When: "balanceOf", + Got: err.Error(), + } + } + + balance, ok := resBalanceOf[0].(*big.Int) + if !ok { + return nil, &ptypes.ErrUnexpected{ + Got: "ZRC20 balanceOf returned an unexpected type", + } + } + + if balance.Cmp(amount) == -1 { + return nil, &ptypes.ErrInvalidAmount{ + Got: balance.String(), + } + } + + // 2. Effect: burn cosmos coin balance. + if err := c.bankKeeper.SendCoinsFromAccountToModule(ctx, fromAddr, types.ModuleName, coinSet); err != nil { + return nil, &ptypes.ErrUnexpected{ + When: "SendCoinsFromAccountToModule", + Got: err.Error(), + } + } + + if err := c.bankKeeper.BurnCoins(ctx, types.ModuleName, coinSet); err != nil { + return nil, &ptypes.ErrUnexpected{ + When: "BurnCoins", + Got: err.Error(), + } + } + + if err := c.addEventLog(ctx, evm.StateDB, WithdrawEventName, eventData{caller, zrc20Addr, fromAddr.String(), coinSet.Denoms()[0], amount}); err != nil { + return nil, &ptypes.ErrUnexpected{ + When: "AddWithdrawLog", + Got: err.Error(), + } + } + + // 3. Interactions: send to module and burn. + + // function transfer(address recipient, uint256 amount) public virtual override returns (bool) + resTransfer, err := c.CallContract( + ctx, + &c.fungibleKeeper, + c.zrc20ABI, + zrc20Addr, + "transfer", + []interface{}{caller /* sender */, amount}, + ) + if err != nil { + return nil, &ptypes.ErrUnexpected{ + When: "transfer", + Got: err.Error(), + } + } + + transferred, ok := resTransfer[0].(bool) + if !ok { + return nil, &ptypes.ErrUnexpected{ + Got: "ZRC20 transfer returned an unexpected type", + } + } + + if !transferred { + return nil, &ptypes.ErrUnexpected{ + When: "transfer", + Got: "transaction not successful", + } + } + + return method.Outputs.Pack(true) +} + +func unpackWithdrawArgs(args []interface{}) (zrc20Addr common.Address, amount *big.Int, err error) { + zrc20Addr, ok := args[0].(common.Address) + if !ok { + return common.Address{}, nil, &ptypes.ErrInvalidAddr{ + Got: zrc20Addr.String(), + } + } + + amount, ok = args[1].(*big.Int) + if !ok || amount.Sign() < 0 || amount == nil || amount == new(big.Int) { + return common.Address{}, nil, &ptypes.ErrInvalidAmount{ + Got: amount.String(), + } + } + + return zrc20Addr, amount, nil +} diff --git a/precompiles/logs/logs.go b/precompiles/logs/logs.go index f168e33da4..07960a442e 100644 --- a/precompiles/logs/logs.go +++ b/precompiles/logs/logs.go @@ -1,8 +1,6 @@ package logs import ( - "math/big" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" @@ -10,6 +8,11 @@ import ( "github.com/ethereum/go-ethereum/core/vm" ) +type Argument struct { + Type string + Value interface{} +} + // AddLog adds log to stateDB func AddLog(ctx sdk.Context, precompileAddr common.Address, stateDB vm.StateDB, topics []common.Hash, data []byte) { stateDB.AddLog(&types.Log{ @@ -38,18 +41,29 @@ func MakeTopics(event abi.Event, query ...[]interface{}) ([]common.Hash, error) return topics, nil } -// PackBigInt is a helper function to pack a uint256 amount -func PackBigInt(amount *big.Int) ([]byte, error) { - uint256Type, err := abi.NewType("uint256", "", nil) - if err != nil { - return nil, err +// PackArguments packs an arbitrary number of logs.Arguments as non-indexed data. +// When packing data, make sure the Argument are passed in the same order as the event definition. +func PackArguments(args []Argument) ([]byte, error) { + types := abi.Arguments{} + toPack := []interface{}{} + + for _, arg := range args { + abiType, err := abi.NewType(arg.Type, "", nil) + if err != nil { + return nil, err + } + + types = append(types, abi.Argument{ + Type: abiType, + }) + + toPack = append(toPack, arg.Value) } - arguments := abi.Arguments{ - { - Type: uint256Type, - }, + data, err := types.Pack(toPack...) + if err != nil { + return nil, err } - return arguments.Pack(amount) + return data, nil } diff --git a/precompiles/precompiles.go b/precompiles/precompiles.go index 1adf65005f..cdd5e2ff74 100644 --- a/precompiles/precompiles.go +++ b/precompiles/precompiles.go @@ -4,12 +4,14 @@ import ( "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdktypes "github.com/cosmos/cosmos-sdk/types" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" ethparams "github.com/ethereum/go-ethereum/params" evmkeeper "github.com/zeta-chain/ethermint/x/evm/keeper" + "github.com/zeta-chain/node/precompiles/bank" "github.com/zeta-chain/node/precompiles/prototype" "github.com/zeta-chain/node/precompiles/staking" fungiblekeeper "github.com/zeta-chain/node/x/fungible/keeper" @@ -21,12 +23,14 @@ import ( var EnabledStatefulContracts = map[common.Address]bool{ prototype.ContractAddress: true, staking.ContractAddress: true, + bank.ContractAddress: true, } // StatefulContracts returns all the registered precompiled contracts. func StatefulContracts( fungibleKeeper *fungiblekeeper.Keeper, stakingKeeper *stakingkeeper.Keeper, + bankKeeper bankkeeper.Keeper, cdc codec.Codec, gasConfig storetypes.GasConfig, ) (precompiledContracts []evmkeeper.CustomContractFn) { @@ -53,5 +57,14 @@ func StatefulContracts( precompiledContracts = append(precompiledContracts, stakingContract) } + if EnabledStatefulContracts[bank.ContractAddress] { + bankContract := func(ctx sdktypes.Context, _ ethparams.Rules) vm.PrecompiledContract { + return bank.NewIBankContract(ctx, bankKeeper, *fungibleKeeper, cdc, gasConfig) + } + + // Append the staking contract to the precompiledContracts slice. + precompiledContracts = append(precompiledContracts, bankContract) + } + return precompiledContracts } diff --git a/precompiles/precompiles_test.go b/precompiles/precompiles_test.go index 998240e644..a0b55572ea 100644 --- a/precompiles/precompiles_test.go +++ b/precompiles/precompiles_test.go @@ -25,7 +25,7 @@ func Test_StatefulContracts(t *testing.T) { } // StatefulContracts() should return all the enabled contracts. - contracts := StatefulContracts(k, &sdkk.StakingKeeper, appCodec, gasConfig) + contracts := StatefulContracts(k, &sdkk.StakingKeeper, sdkk.BankKeeper, appCodec, gasConfig) require.NotNil(t, contracts, "StatefulContracts() should not return a nil slice") require.Len(t, contracts, expectedContracts, "StatefulContracts() should return all the enabled contracts") diff --git a/precompiles/prototype/IPrototype.go b/precompiles/prototype/IPrototype.gen.go similarity index 100% rename from precompiles/prototype/IPrototype.go rename to precompiles/prototype/IPrototype.gen.go diff --git a/precompiles/prototype/bindings.go b/precompiles/prototype/bindings.go index e4a31a5e56..eeb59d988e 100644 --- a/precompiles/prototype/bindings.go +++ b/precompiles/prototype/bindings.go @@ -1,6 +1,6 @@ //go:generate sh -c "solc IPrototype.sol --combined-json abi | jq '.contracts.\"IPrototype.sol:IPrototype\"' > IPrototype.json" //go:generate sh -c "cat IPrototype.json | jq .abi > IPrototype.abi" -//go:generate sh -c "abigen --abi IPrototype.abi --pkg prototype --type IPrototype --out IPrototype.go" +//go:generate sh -c "abigen --abi IPrototype.abi --pkg prototype --type IPrototype --out IPrototype.gen.go" package prototype diff --git a/precompiles/staking/IStaking.go b/precompiles/staking/IStaking.gen.go similarity index 100% rename from precompiles/staking/IStaking.go rename to precompiles/staking/IStaking.gen.go diff --git a/precompiles/staking/bindings.go b/precompiles/staking/bindings.go index 5e182735be..324289b9f0 100644 --- a/precompiles/staking/bindings.go +++ b/precompiles/staking/bindings.go @@ -1,6 +1,6 @@ //go:generate sh -c "solc IStaking.sol --combined-json abi | jq '.contracts.\"IStaking.sol:IStaking\"' > IStaking.json" //go:generate sh -c "cat IStaking.json | jq .abi > IStaking.abi" -//go:generate sh -c "abigen --abi IStaking.abi --pkg staking --type IStaking --out IStaking.go" +//go:generate sh -c "abigen --abi IStaking.abi --pkg staking --type IStaking --out IStaking.gen.go" package staking diff --git a/precompiles/staking/logs.go b/precompiles/staking/logs.go index 165dd91aa3..ea8e51274c 100644 --- a/precompiles/staking/logs.go +++ b/precompiles/staking/logs.go @@ -37,7 +37,9 @@ func (c *Contract) AddStakeLog( } // amount is part of event data - data, err := logs.PackBigInt(amount) + data, err := logs.PackArguments([]logs.Argument{ + {Type: "uint256", Value: amount}, + }) if err != nil { return err } @@ -67,7 +69,9 @@ func (c *Contract) AddUnstakeLog( } // amount is part of event data - data, err := logs.PackBigInt(amount) + data, err := logs.PackArguments([]logs.Argument{ + {Type: "uint256", Value: amount}, + }) if err != nil { return err } @@ -108,7 +112,9 @@ func (c *Contract) AddMoveStakeLog( } // amount is part of event data - data, err := logs.PackBigInt(amount) + data, err := logs.PackArguments([]logs.Argument{ + {Type: "uint256", Value: amount}, + }) if err != nil { return err } diff --git a/precompiles/types/errors.go b/precompiles/types/errors.go index 0cc6928541..03e397fa14 100644 --- a/precompiles/types/errors.go +++ b/precompiles/types/errors.go @@ -3,19 +3,22 @@ package types import "fmt" /* -Address related errors + Address related errors */ + type ErrInvalidAddr struct { - Got string + Got string + Reason string } func (e ErrInvalidAddr) Error() string { - return fmt.Sprintf("invalid address %s", e.Got) + return fmt.Sprintf("invalid address %s, reason: %s", e.Got, e.Reason) } /* -Argument related errors + Argument related errors */ + type ErrInvalidNumberOfArgs struct { Got, Expect int } @@ -33,8 +36,56 @@ func (e ErrInvalidArgument) Error() string { } /* -Method related errors + Token related errors +*/ + +type ErrInvalidToken struct { + Got string + Reason string +} + +func (e ErrInvalidToken) Error() string { + return fmt.Sprintf("invalid token %s: %s", e.Got, e.Reason) +} + +type ErrInvalidCoin struct { + Got string + Negative bool + Nil bool + Empty bool +} + +func (e ErrInvalidCoin) Error() string { + return fmt.Sprintf( + "invalid coin: denom: %s, is negative: %v, is nil: %v, is empty: %v", + e.Got, + e.Negative, + e.Nil, + e.Empty, + ) +} + +type ErrInvalidAmount struct { + Got string +} + +func (e ErrInvalidAmount) Error() string { + return fmt.Sprintf("invalid token amount: %s", e.Got) +} + +type ErrInsufficientBalance struct { + Requested string + Got string +} + +func (e ErrInsufficientBalance) Error() string { + return fmt.Sprintf("insufficient balance: requested %s, current %s", e.Requested, e.Got) +} + +/* + Method related errors */ + type ErrInvalidMethod struct { Method string } @@ -42,3 +93,12 @@ type ErrInvalidMethod struct { func (e ErrInvalidMethod) Error() string { return fmt.Sprintf("invalid method: %s", e.Method) } + +type ErrUnexpected struct { + When string + Got string +} + +func (e ErrUnexpected) Error() string { + return fmt.Sprintf("unexpected error in %s: %s", e.When, e.Got) +} diff --git a/precompiles/types/errors_test.go b/precompiles/types/errors_test.go index 5693a450eb..c80647a08d 100644 --- a/precompiles/types/errors_test.go +++ b/precompiles/types/errors_test.go @@ -1,16 +1,22 @@ package types -import "testing" +import ( + "testing" + + "github.com/stretchr/testify/require" +) func Test_ErrInvalidAddr(t *testing.T) { e := ErrInvalidAddr{ - Got: "foo", + Got: "foo", + Reason: "bar", } got := e.Error() - expect := "invalid address foo" + expect := "invalid address foo, reason: bar" if got != expect { t.Errorf("Expected %v, got %v", expect, got) } + require.ErrorIs(t, ErrInvalidAddr{"foo", "bar"}, e) } func Test_ErrInvalidNumberOfArgs(t *testing.T) { @@ -23,6 +29,7 @@ func Test_ErrInvalidNumberOfArgs(t *testing.T) { if got != expect { t.Errorf("Expected %v, got %v", expect, got) } + require.ErrorIs(t, ErrInvalidNumberOfArgs{1, 2}, e) } func Test_ErrInvalidArgument(t *testing.T) { @@ -34,6 +41,7 @@ func Test_ErrInvalidArgument(t *testing.T) { if got != expect { t.Errorf("Expected %v, got %v", expect, got) } + require.ErrorIs(t, ErrInvalidArgument{"foo"}, e) } func Test_ErrInvalidMethod(t *testing.T) { @@ -45,4 +53,71 @@ func Test_ErrInvalidMethod(t *testing.T) { if got != expect { t.Errorf("Expected %v, got %v", expect, got) } + require.ErrorIs(t, ErrInvalidMethod{"foo"}, e) +} + +func Test_ErrInvalidCoin(t *testing.T) { + e := ErrInvalidCoin{ + Got: "foo", + Negative: true, + Nil: false, + Empty: false, + } + got := e.Error() + expect := "invalid coin: denom: foo, is negative: true, is nil: false, is empty: false" + if got != expect { + t.Errorf("Expected %v, got %v", expect, got) + } + require.ErrorIs(t, ErrInvalidCoin{"foo", true, false, false}, e) +} + +func Test_ErrInvalidAmount(t *testing.T) { + e := ErrInvalidAmount{ + Got: "foo", + } + got := e.Error() + expect := "invalid token amount: foo" + if got != expect { + t.Errorf("Expected %v, got %v", expect, got) + } + require.ErrorIs(t, ErrInvalidAmount{"foo"}, e) +} + +func Test_ErrUnexpected(t *testing.T) { + e := ErrUnexpected{ + When: "foo", + Got: "bar", + } + got := e.Error() + expect := "unexpected error in foo: bar" + if got != expect { + t.Errorf("Expected %v, got %v", expect, got) + } + require.ErrorIs(t, ErrUnexpected{"foo", "bar"}, e) +} + +func Test_ErrInsufficientBalance(t *testing.T) { + e := ErrInsufficientBalance{ + Requested: "foo", + Got: "bar", + } + got := e.Error() + expect := "insufficient balance: requested foo, current bar" + if got != expect { + t.Errorf("Expected %v, got %v", expect, got) + } + require.ErrorIs(t, ErrInsufficientBalance{"foo", "bar"}, e) +} + +func Test_ErrInvalidToken(t *testing.T) { + e := ErrInvalidToken{ + Got: "foo", + Reason: "bar", + } + got := e.Error() + expect := "invalid token foo: bar" + if got != expect { + t.Errorf("Expected %v, got %v", expect, got) + } + require.ErrorIs(t, ErrInvalidToken{"foo", "bar"}, e) } diff --git a/precompiles/types/types.go b/precompiles/types/types.go index 7bd4a57bfa..fd153d43b2 100644 --- a/precompiles/types/types.go +++ b/precompiles/types/types.go @@ -4,9 +4,12 @@ import ( "math/big" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" "github.com/zeta-chain/ethermint/x/evm/statedb" + + fungiblekeeper "github.com/zeta-chain/node/x/fungible/keeper" ) // Interface compliance. @@ -30,8 +33,19 @@ type Registrable interface { RegistryKey() common.Address } +type ContractCaller interface { + CallContract( + ctx sdk.Context, + fungibleKeeper *fungiblekeeper.Keeper, + abi *abi.ABI, + dst common.Address, + method string, + args []interface{}) ([]interface{}, error) +} + type BaseContract interface { Registrable + ContractCaller } // A baseContract implements Registrable and BaseContract interfaces. @@ -52,3 +66,53 @@ func (c *baseContract) RegistryKey() common.Address { func BytesToBigInt(data []byte) *big.Int { return big.NewInt(0).SetBytes(data[:]) } + +// CallContract calls a contract method on behalf of a precompiled contract. +// - noEtherumTxEvent is set to true because we don't want to emit EthereumTxEvent, +// as any MsgEthereumTx with more than one ethereum_tx will fail and the receipt +// won't be able to be retrieved. +// - from is set always to the precompiled contract address. +func (c *baseContract) CallContract( + ctx sdk.Context, + fungibleKeeper *fungiblekeeper.Keeper, + abi *abi.ABI, + dst common.Address, + method string, + args []interface{}, +) ([]interface{}, error) { + res, err := fungibleKeeper.CallEVM( + ctx, // ctx + *abi, // abi + c.RegistryKey(), // from + dst, // to + big.NewInt(0), // value + nil, // gasLimit + true, // commit + true, // noEthereumTxEvent + method, // method + args..., // args + ) + if err != nil { + return nil, &ErrUnexpected{ + When: "CallEVM " + method, + Got: err.Error(), + } + } + + if res.VmError != "" { + return nil, &ErrUnexpected{ + When: "VmError " + method, + Got: res.VmError, + } + } + + ret, err := abi.Methods[method].Outputs.Unpack(res.Ret) + if err != nil { + return nil, &ErrUnexpected{ + When: "Unpack " + method, + Got: err.Error(), + } + } + + return ret, nil +} diff --git a/scripts/bindings-stateful-precompiles.sh b/scripts/bindings-stateful-precompiles.sh index cc900a6942..ea646995de 100755 --- a/scripts/bindings-stateful-precompiles.sh +++ b/scripts/bindings-stateful-precompiles.sh @@ -75,4 +75,5 @@ function bindings() { # List of bindings to generate bindings ./precompiles/prototype bindings ./precompiles/staking +bindings ./precompiles/bank From 03e91d4232de2a0c79ccf12a004c635d471a7ce5 Mon Sep 17 00:00:00 2001 From: skosito Date: Fri, 27 Sep 2024 14:15:37 +0100 Subject: [PATCH 05/14] feat: add sender to revert context (#2919) * e2e tests and modifications for authenticated call * extend test with sender check and revert case * separate tests into separate files * cleanup * withdraw and call support and tests * bump protocol contracts * split tests into separate files * small cleanup * fmt * generate * lint * changelog * PR comments * fix case in proto * bump vote inbound gas limit in zetaclient * fix test * generate * fixing tests * call options non empty * generate * test fix * rename gateway caller * pr comments rename tests * PR comment * generate * tests * add sender in test contract * extend e2e tests * generate * changelog * PR comment * generate * update tests fixes * tests fixes * fix * test fix * gas limit fixes * PR comment fix * fix bad merge --- changelog.md | 1 + ...2_erc20_deposit_and_call_revert_with_call.go | 9 +++++++++ ..._erc20_withdraw_and_call_revert_with_call.go | 9 +++++++++ ..._v2_eth_deposit_and_call_revert_with_call.go | 9 +++++++++ ...v2_eth_withdraw_and_call_revert_with_call.go | 9 +++++++++ go.mod | 2 +- go.sum | 4 ++-- pkg/contracts/testdappv2/TestDAppV2.abi | 5 +++++ pkg/contracts/testdappv2/TestDAppV2.bin | 2 +- pkg/contracts/testdappv2/TestDAppV2.go | 17 +++++++++-------- pkg/contracts/testdappv2/TestDAppV2.json | 7 ++++++- pkg/contracts/testdappv2/TestDAppV2.sol | 3 +++ testutil/keeper/mocks/crosschain/fungible.go | 10 +++++----- .../cctx_orchestrator_validate_outbound.go | 1 + x/crosschain/keeper/gas_payment.go | 6 ++++++ x/crosschain/types/expected_keepers.go | 1 + x/fungible/keeper/v2_deposits.go | 4 +++- x/fungible/keeper/v2_evm.go | 4 ++++ zetaclient/chains/evm/signer/v2_sign.go | 4 ++++ zetaclient/chains/evm/signer/v2_signer.go | 4 ++-- 20 files changed, 90 insertions(+), 21 deletions(-) diff --git a/changelog.md b/changelog.md index 3a43031bb4..d78c1861ae 100644 --- a/changelog.md +++ b/changelog.md @@ -15,6 +15,7 @@ * [2907](https://github.com/zeta-chain/node/pull/2907) - derive Bitcoin tss address by chain id and added more Signet static info * [2911](https://github.com/zeta-chain/node/pull/2911) - add chain static information for btc testnet4 * [2904](https://github.com/zeta-chain/node/pull/2904) - integrate authenticated calls smart contract functionality into protocol +* [2919](https://github.com/zeta-chain/node/pull/2919) - add inbound sender to revert context ### Refactor diff --git a/e2e/e2etests/test_v2_erc20_deposit_and_call_revert_with_call.go b/e2e/e2etests/test_v2_erc20_deposit_and_call_revert_with_call.go index 40a880ac6e..41b92fee4f 100644 --- a/e2e/e2etests/test_v2_erc20_deposit_and_call_revert_with_call.go +++ b/e2e/e2etests/test_v2_erc20_deposit_and_call_revert_with_call.go @@ -3,6 +3,7 @@ package e2etests import ( "math/big" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/stretchr/testify/require" "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayevm.sol" @@ -38,4 +39,12 @@ func TestV2ERC20DepositAndCallRevertWithCall(r *runner.E2ERunner, args []string) // check the payload was received on the contract r.AssertTestDAppEVMCalled(true, payloadMessageDepositOnRevertERC20, big.NewInt(0)) + + // check expected sender was used + senderForMsg, err := r.TestDAppV2EVM.SenderWithMessage( + &bind.CallOpts{}, + []byte(payloadMessageDepositOnRevertERC20), + ) + require.NoError(r, err) + require.Equal(r, r.EVMAuth.From, senderForMsg) } diff --git a/e2e/e2etests/test_v2_erc20_withdraw_and_call_revert_with_call.go b/e2e/e2etests/test_v2_erc20_withdraw_and_call_revert_with_call.go index 9ce4b48613..45bab52ae6 100644 --- a/e2e/e2etests/test_v2_erc20_withdraw_and_call_revert_with_call.go +++ b/e2e/e2etests/test_v2_erc20_withdraw_and_call_revert_with_call.go @@ -3,6 +3,7 @@ package e2etests import ( "math/big" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/stretchr/testify/require" "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol" @@ -43,4 +44,12 @@ func TestV2ERC20WithdrawAndCallRevertWithCall(r *runner.E2ERunner, args []string require.Equal(r, crosschaintypes.CctxStatus_Reverted, cctx.CctxStatus.Status) r.AssertTestDAppZEVMCalled(true, payloadMessageWithdrawOnRevertERC20, big.NewInt(0)) + + // check expected sender was used + senderForMsg, err := r.TestDAppV2ZEVM.SenderWithMessage( + &bind.CallOpts{}, + []byte(payloadMessageWithdrawOnRevertERC20), + ) + require.NoError(r, err) + require.Equal(r, r.ZEVMAuth.From, senderForMsg) } diff --git a/e2e/e2etests/test_v2_eth_deposit_and_call_revert_with_call.go b/e2e/e2etests/test_v2_eth_deposit_and_call_revert_with_call.go index 47c3f20755..245aa3e636 100644 --- a/e2e/e2etests/test_v2_eth_deposit_and_call_revert_with_call.go +++ b/e2e/e2etests/test_v2_eth_deposit_and_call_revert_with_call.go @@ -3,6 +3,7 @@ package e2etests import ( "math/big" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/stretchr/testify/require" "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayevm.sol" @@ -38,4 +39,12 @@ func TestV2ETHDepositAndCallRevertWithCall(r *runner.E2ERunner, args []string) { // check the payload was received on the contract r.AssertTestDAppEVMCalled(true, payloadMessageDepositOnRevertETH, big.NewInt(0)) + + // check expected sender was used + senderForMsg, err := r.TestDAppV2EVM.SenderWithMessage( + &bind.CallOpts{}, + []byte(payloadMessageDepositOnRevertETH), + ) + require.NoError(r, err) + require.Equal(r, r.EVMAuth.From, senderForMsg) } diff --git a/e2e/e2etests/test_v2_eth_withdraw_and_call_revert_with_call.go b/e2e/e2etests/test_v2_eth_withdraw_and_call_revert_with_call.go index 391e37e150..f4d31d5d14 100644 --- a/e2e/e2etests/test_v2_eth_withdraw_and_call_revert_with_call.go +++ b/e2e/e2etests/test_v2_eth_withdraw_and_call_revert_with_call.go @@ -3,6 +3,7 @@ package e2etests import ( "math/big" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/stretchr/testify/require" "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol" @@ -42,4 +43,12 @@ func TestV2ETHWithdrawAndCallRevertWithCall(r *runner.E2ERunner, args []string) require.Equal(r, crosschaintypes.CctxStatus_Reverted, cctx.CctxStatus.Status) r.AssertTestDAppZEVMCalled(true, payloadMessageWithdrawOnRevertETH, big.NewInt(0)) + + // check expected sender was used + senderForMsg, err := r.TestDAppV2ZEVM.SenderWithMessage( + &bind.CallOpts{}, + []byte(payloadMessageWithdrawOnRevertETH), + ) + require.NoError(r, err) + require.Equal(r, r.ZEVMAuth.From, senderForMsg) } diff --git a/go.mod b/go.mod index 17899e5ccb..b169010e38 100644 --- a/go.mod +++ b/go.mod @@ -59,7 +59,7 @@ require ( github.com/stretchr/testify v1.9.0 github.com/zeta-chain/ethermint v0.0.0-20240909234716-2fad916e7179 github.com/zeta-chain/keystone/keys v0.0.0-20240826165841-3874f358c138 - github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240920151810-cabe34920d52 + github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240924201108-3a274ce7bad0 gitlab.com/thorchain/tss/go-tss v1.6.5 go.nhat.io/grpcmock v0.25.0 golang.org/x/crypto v0.23.0 diff --git a/go.sum b/go.sum index 972c2695ce..b06cf25283 100644 --- a/go.sum +++ b/go.sum @@ -4182,8 +4182,8 @@ github.com/zeta-chain/go-tss v0.0.0-20240916173049-89fee4b0ae7f h1:XqUvw9a3EnDa2 github.com/zeta-chain/go-tss v0.0.0-20240916173049-89fee4b0ae7f/go.mod h1:B1FDE6kHs8hozKSX1/iXgCdvlFbS6+FeAupoBHDK0Cc= github.com/zeta-chain/keystone/keys v0.0.0-20240826165841-3874f358c138 h1:vck/FcIIpFOvpBUm0NO17jbEtmSz/W/a5Y4jRuSJl6I= github.com/zeta-chain/keystone/keys v0.0.0-20240826165841-3874f358c138/go.mod h1:U494OsZTWsU75hqoriZgMdSsgSGP1mUL1jX+wN/Aez8= -github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240920151810-cabe34920d52 h1:DlSY9awQteXVmvY0lPD4Or83iuL4P5KwSGky+n4mYio= -github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240920151810-cabe34920d52/go.mod h1:SjT7QirtJE8stnAe1SlNOanxtfSfijJm3MGJ+Ax7w7w= +github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240924201108-3a274ce7bad0 h1:GbfO2dyjSAWqBH0xDIttwPB2fE5A+zw0UUbEoW3S3wU= +github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240924201108-3a274ce7bad0/go.mod h1:SjT7QirtJE8stnAe1SlNOanxtfSfijJm3MGJ+Ax7w7w= github.com/zeta-chain/tss-lib v0.0.0-20240916163010-2e6b438bd901 h1:9whtN5fjYHfk4yXIuAsYP2EHxImwDWDVUOnZJ2pfL3w= github.com/zeta-chain/tss-lib v0.0.0-20240916163010-2e6b438bd901/go.mod h1:d2iTC62s9JwKiCMPhcDDXbIZmuzAyJ4lwso0H5QyRbk= github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= diff --git a/pkg/contracts/testdappv2/TestDAppV2.abi b/pkg/contracts/testdappv2/TestDAppV2.abi index b57adc2484..cbfdc1bfca 100644 --- a/pkg/contracts/testdappv2/TestDAppV2.abi +++ b/pkg/contracts/testdappv2/TestDAppV2.abi @@ -204,6 +204,11 @@ "inputs": [ { "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, { "internalType": "address", "name": "asset", diff --git a/pkg/contracts/testdappv2/TestDAppV2.bin b/pkg/contracts/testdappv2/TestDAppV2.bin index b8768f52b4..0a7fe69007 100644 --- a/pkg/contracts/testdappv2/TestDAppV2.bin +++ b/pkg/contracts/testdappv2/TestDAppV2.bin @@ -1 +1 @@ -608060405234801561001057600080fd5b5061147c806100206000396000f3fe6080604052600436106100c65760003560e01c8063a799911f1161007f578063de43156e11610059578063de43156e14610267578063e2842ed714610290578063f592cbfb146102cd578063f936ae851461030a576100cd565b8063a799911f146101f9578063c234fecf14610215578063c7a339a91461023e576100cd565b806336e980a0146100d25780634297a263146100fb57806359f4a77714610138578063660b9de014610163578063676cc0541461018c5780639291fe26146101bc576100cd565b366100cd57005b600080fd5b3480156100de57600080fd5b506100f960048036038101906100f49190610b78565b610347565b005b34801561010757600080fd5b50610122600480360381019061011d9190610bf7565b610371565b60405161012f9190610c3d565b60405180910390f35b34801561014457600080fd5b5061014d610389565b60405161015a9190610c99565b60405180910390f35b34801561016f57600080fd5b5061018a60048036038101906101859190610cd8565b6103ad565b005b6101a660048036038101906101a19190610da0565b610468565b6040516101b39190610e88565b60405180910390f35b3480156101c857600080fd5b506101e360048036038101906101de9190610b78565b61061d565b6040516101f09190610c3d565b60405180910390f35b610213600480360381019061020e9190610b78565b610660565b005b34801561022157600080fd5b5061023c60048036038101906102379190610ed6565b610689565b005b34801561024a57600080fd5b5061026560048036038101906102609190610f6d565b6106cc565b005b34801561027357600080fd5b5061028e60048036038101906102899190610ffb565b610780565b005b34801561029c57600080fd5b506102b760048036038101906102b29190610bf7565b610879565b6040516102c491906110ba565b60405180910390f35b3480156102d957600080fd5b506102f460048036038101906102ef9190610b78565b610899565b60405161030191906110ba565b60405180910390f35b34801561031657600080fd5b50610331600480360381019061032c9190611176565b6108e9565b60405161033e9190610c99565b60405180910390f35b61035081610932565b1561035a57600080fd5b61036381610988565b61036e8160006109dc565b50565b60036020528060005260406000206000915090505481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6104088180604001906103c091906111ce565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b61046581806040019061041b91906111ce565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060006109dc565b50565b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168460000160208101906104b49190610ed6565b73ffffffffffffffffffffffffffffffffffffffff161461050a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105019061128e565b60405180910390fd5b61055783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b6105a583838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050346109dc565b8360000160208101906105b89190610ed6565b600284846040516105ca9291906112de565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509392505050565b60006003600083604051602001610634919061133e565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b61066981610932565b1561067357600080fd5b61067c81610988565b61068681346109dc565b50565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6106d581610932565b156106df57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161071c93929190611355565b6020604051808303816000875af115801561073b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075f91906113b8565b61076857600080fd5b61077181610988565b61077b81836109dc565b505050565b6107cd82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610932565b156107d757600080fd5b61082482828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b61087282828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050846109dc565b5050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b600060016000836040516020016108b0919061133e565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b6002818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060405160200161094390611431565b604051602081830303815290604052805190602001208260405160200161096a919061133e565b60405160208183030381529060405280519060200120149050919050565b60018060008360405160200161099e919061133e565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b8060036000846040516020016109f2919061133e565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610a8582610a3c565b810181811067ffffffffffffffff82111715610aa457610aa3610a4d565b5b80604052505050565b6000610ab7610a1e565b9050610ac38282610a7c565b919050565b600067ffffffffffffffff821115610ae357610ae2610a4d565b5b610aec82610a3c565b9050602081019050919050565b82818337600083830152505050565b6000610b1b610b1684610ac8565b610aad565b905082815260208101848484011115610b3757610b36610a37565b5b610b42848285610af9565b509392505050565b600082601f830112610b5f57610b5e610a32565b5b8135610b6f848260208601610b08565b91505092915050565b600060208284031215610b8e57610b8d610a28565b5b600082013567ffffffffffffffff811115610bac57610bab610a2d565b5b610bb884828501610b4a565b91505092915050565b6000819050919050565b610bd481610bc1565b8114610bdf57600080fd5b50565b600081359050610bf181610bcb565b92915050565b600060208284031215610c0d57610c0c610a28565b5b6000610c1b84828501610be2565b91505092915050565b6000819050919050565b610c3781610c24565b82525050565b6000602082019050610c526000830184610c2e565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610c8382610c58565b9050919050565b610c9381610c78565b82525050565b6000602082019050610cae6000830184610c8a565b92915050565b600080fd5b600060608284031215610ccf57610cce610cb4565b5b81905092915050565b600060208284031215610cee57610ced610a28565b5b600082013567ffffffffffffffff811115610d0c57610d0b610a2d565b5b610d1884828501610cb9565b91505092915050565b600060208284031215610d3757610d36610cb4565b5b81905092915050565b600080fd5b600080fd5b60008083601f840112610d6057610d5f610a32565b5b8235905067ffffffffffffffff811115610d7d57610d7c610d40565b5b602083019150836001820283011115610d9957610d98610d45565b5b9250929050565b600080600060408486031215610db957610db8610a28565b5b6000610dc786828701610d21565b935050602084013567ffffffffffffffff811115610de857610de7610a2d565b5b610df486828701610d4a565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b60005b83811015610e3a578082015181840152602081019050610e1f565b83811115610e49576000848401525b50505050565b6000610e5a82610e00565b610e648185610e0b565b9350610e74818560208601610e1c565b610e7d81610a3c565b840191505092915050565b60006020820190508181036000830152610ea28184610e4f565b905092915050565b610eb381610c78565b8114610ebe57600080fd5b50565b600081359050610ed081610eaa565b92915050565b600060208284031215610eec57610eeb610a28565b5b6000610efa84828501610ec1565b91505092915050565b6000610f0e82610c78565b9050919050565b610f1e81610f03565b8114610f2957600080fd5b50565b600081359050610f3b81610f15565b92915050565b610f4a81610c24565b8114610f5557600080fd5b50565b600081359050610f6781610f41565b92915050565b600080600060608486031215610f8657610f85610a28565b5b6000610f9486828701610f2c565b9350506020610fa586828701610f58565b925050604084013567ffffffffffffffff811115610fc657610fc5610a2d565b5b610fd286828701610b4a565b9150509250925092565b600060608284031215610ff257610ff1610cb4565b5b81905092915050565b60008060008060006080868803121561101757611016610a28565b5b600086013567ffffffffffffffff81111561103557611034610a2d565b5b61104188828901610fdc565b955050602061105288828901610ec1565b945050604061106388828901610f58565b935050606086013567ffffffffffffffff81111561108457611083610a2d565b5b61109088828901610d4a565b92509250509295509295909350565b60008115159050919050565b6110b48161109f565b82525050565b60006020820190506110cf60008301846110ab565b92915050565b600067ffffffffffffffff8211156110f0576110ef610a4d565b5b6110f982610a3c565b9050602081019050919050565b6000611119611114846110d5565b610aad565b90508281526020810184848401111561113557611134610a37565b5b611140848285610af9565b509392505050565b600082601f83011261115d5761115c610a32565b5b813561116d848260208601611106565b91505092915050565b60006020828403121561118c5761118b610a28565b5b600082013567ffffffffffffffff8111156111aa576111a9610a2d565b5b6111b684828501611148565b91505092915050565b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126111eb576111ea6111bf565b5b80840192508235915067ffffffffffffffff82111561120d5761120c6111c4565b5b602083019250600182023603831315611229576112286111c9565b5b509250929050565b600082825260208201905092915050565b7f756e61757468656e746963617465642073656e64657200000000000000000000600082015250565b6000611278601683611231565b915061128382611242565b602082019050919050565b600060208201905081810360008301526112a78161126b565b9050919050565b600081905092915050565b60006112c583856112ae565b93506112d2838584610af9565b82840190509392505050565b60006112eb8284866112b9565b91508190509392505050565b600081519050919050565b600081905092915050565b6000611318826112f7565b6113228185611302565b9350611332818560208601610e1c565b80840191505092915050565b600061134a828461130d565b915081905092915050565b600060608201905061136a6000830186610c8a565b6113776020830185610c8a565b6113846040830184610c2e565b949350505050565b6113958161109f565b81146113a057600080fd5b50565b6000815190506113b28161138c565b92915050565b6000602082840312156113ce576113cd610a28565b5b60006113dc848285016113a3565b91505092915050565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b600061141b600683611302565b9150611426826113e5565b600682019050919050565b600061143c8261140e565b915081905091905056fea264697066735822122046fb444f8c754142359339f5f1d728822414688169d0d22f23bd25c688c73fdf64736f6c634300080a0033 +608060405234801561001057600080fd5b5061150a806100206000396000f3fe6080604052600436106100c65760003560e01c8063a799911f1161007f578063de43156e11610059578063de43156e14610267578063e2842ed714610290578063f592cbfb146102cd578063f936ae851461030a576100cd565b8063a799911f146101f9578063c234fecf14610215578063c7a339a91461023e576100cd565b806336e980a0146100d25780634297a263146100fb57806359f4a777146101385780635ac1e07014610163578063676cc0541461018c5780639291fe26146101bc576100cd565b366100cd57005b600080fd5b3480156100de57600080fd5b506100f960048036038101906100f49190610de7565b610347565b005b34801561010757600080fd5b50610122600480360381019061011d9190610d02565b610371565b60405161012f9190611173565b60405180910390f35b34801561014457600080fd5b5061014d610389565b60405161015a91906110c4565b60405180910390f35b34801561016f57600080fd5b5061018a60048036038101906101859190610e90565b6103ad565b005b6101a660048036038101906101a19190610e30565b6104e7565b6040516101b39190611131565b60405180910390f35b3480156101c857600080fd5b506101e360048036038101906101de9190610de7565b61069c565b6040516101f09190611173565b60405180910390f35b610213600480360381019061020e9190610de7565b6106df565b005b34801561022157600080fd5b5061023c60048036038101906102379190610ca8565b610708565b005b34801561024a57600080fd5b5061026560048036038101906102609190610d78565b61074b565b005b34801561027357600080fd5b5061028e60048036038101906102899190610ed9565b61080e565b005b34801561029c57600080fd5b506102b760048036038101906102b29190610d02565b610907565b6040516102c49190611116565b60405180910390f35b3480156102d957600080fd5b506102f460048036038101906102ef9190610de7565b610927565b6040516103019190611116565b60405180910390f35b34801561031657600080fd5b50610331600480360381019061032c9190610d2f565b610977565b60405161033e91906110c4565b60405180910390f35b610350816109c0565b1561035a57600080fd5b61036381610a16565b61036e816000610a6a565b50565b60036020528060005260406000206000915090505481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6104088180606001906103c0919061118e565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610a16565b61046581806060019061041b919061118e565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506000610a6a565b8060000160208101906104789190610ca8565b600282806060019061048a919061118e565b60405161049892919061107f565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168460000160208101906105339190610ca8565b73ffffffffffffffffffffffffffffffffffffffff1614610589576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090611153565b60405180910390fd5b6105d683838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610a16565b61062483838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505034610a6a565b8360000160208101906106379190610ca8565b6002848460405161064992919061107f565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509392505050565b600060036000836040516020016106b39190611098565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b6106e8816109c0565b156106f257600080fd5b6106fb81610a16565b6107058134610a6a565b50565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610754816109c0565b1561075e57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161079b939291906110df565b602060405180830381600087803b1580156107b557600080fd5b505af11580156107c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ed9190610cd5565b6107f657600080fd5b6107ff81610a16565b6108098183610a6a565b505050565b61085b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506109c0565b1561086557600080fd5b6108b282828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610a16565b61090082828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084610a6a565b5050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b6000600160008360405160200161093e9190611098565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b6002818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040516020016109d1906110af565b60405160208183030381529060405280519060200120826040516020016109f89190611098565b60405160208183030381529060405280519060200120149050919050565b600180600083604051602001610a2c9190611098565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b806003600084604051602001610a809190611098565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b6000610abf610aba84611216565b6111f1565b905082815260208101848484011115610adb57610ada6113ef565b5b610ae684828561132a565b509392505050565b6000610b01610afc84611247565b6111f1565b905082815260208101848484011115610b1d57610b1c6113ef565b5b610b2884828561132a565b509392505050565b600081359050610b3f81611461565b92915050565b600081519050610b5481611478565b92915050565b600081359050610b698161148f565b92915050565b60008083601f840112610b8557610b846113d1565b5b8235905067ffffffffffffffff811115610ba257610ba16113cc565b5b602083019150836001820283011115610bbe57610bbd6113e5565b5b9250929050565b600082601f830112610bda57610bd96113d1565b5b8135610bea848260208601610aac565b91505092915050565b600081359050610c02816114a6565b92915050565b600082601f830112610c1d57610c1c6113d1565b5b8135610c2d848260208601610aee565b91505092915050565b600060208284031215610c4c57610c4b6113db565b5b81905092915050565b600060808284031215610c6b57610c6a6113db565b5b81905092915050565b600060608284031215610c8a57610c896113db565b5b81905092915050565b600081359050610ca2816114bd565b92915050565b600060208284031215610cbe57610cbd6113f9565b5b6000610ccc84828501610b30565b91505092915050565b600060208284031215610ceb57610cea6113f9565b5b6000610cf984828501610b45565b91505092915050565b600060208284031215610d1857610d176113f9565b5b6000610d2684828501610b5a565b91505092915050565b600060208284031215610d4557610d446113f9565b5b600082013567ffffffffffffffff811115610d6357610d626113f4565b5b610d6f84828501610bc5565b91505092915050565b600080600060608486031215610d9157610d906113f9565b5b6000610d9f86828701610bf3565b9350506020610db086828701610c93565b925050604084013567ffffffffffffffff811115610dd157610dd06113f4565b5b610ddd86828701610c08565b9150509250925092565b600060208284031215610dfd57610dfc6113f9565b5b600082013567ffffffffffffffff811115610e1b57610e1a6113f4565b5b610e2784828501610c08565b91505092915050565b600080600060408486031215610e4957610e486113f9565b5b6000610e5786828701610c36565b935050602084013567ffffffffffffffff811115610e7857610e776113f4565b5b610e8486828701610b6f565b92509250509250925092565b600060208284031215610ea657610ea56113f9565b5b600082013567ffffffffffffffff811115610ec457610ec36113f4565b5b610ed084828501610c55565b91505092915050565b600080600080600060808688031215610ef557610ef46113f9565b5b600086013567ffffffffffffffff811115610f1357610f126113f4565b5b610f1f88828901610c74565b9550506020610f3088828901610b30565b9450506040610f4188828901610c93565b935050606086013567ffffffffffffffff811115610f6257610f616113f4565b5b610f6e88828901610b6f565b92509250509295509295909350565b610f86816112c6565b82525050565b610f95816112d8565b82525050565b6000610fa7838561129f565b9350610fb483858461132a565b82840190509392505050565b6000610fcb82611278565b610fd5818561128e565b9350610fe5818560208601611339565b610fee816113fe565b840191505092915050565b600061100482611283565b61100e81856112bb565b935061101e818560208601611339565b80840191505092915050565b60006110376016836112aa565b91506110428261140f565b602082019050919050565b600061105a6006836112bb565b915061106582611438565b600682019050919050565b61107981611320565b82525050565b600061108c828486610f9b565b91508190509392505050565b60006110a48284610ff9565b915081905092915050565b60006110ba8261104d565b9150819050919050565b60006020820190506110d96000830184610f7d565b92915050565b60006060820190506110f46000830186610f7d565b6111016020830185610f7d565b61110e6040830184611070565b949350505050565b600060208201905061112b6000830184610f8c565b92915050565b6000602082019050818103600083015261114b8184610fc0565b905092915050565b6000602082019050818103600083015261116c8161102a565b9050919050565b60006020820190506111886000830184611070565b92915050565b600080833560016020038436030381126111ab576111aa6113e0565b5b80840192508235915067ffffffffffffffff8211156111cd576111cc6113d6565b5b6020830192506001820236038313156111e9576111e86113ea565b5b509250929050565b60006111fb61120c565b9050611207828261136c565b919050565b6000604051905090565b600067ffffffffffffffff8211156112315761123061139d565b5b61123a826113fe565b9050602081019050919050565b600067ffffffffffffffff8211156112625761126161139d565b5b61126b826113fe565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006112d182611300565b9050919050565b60008115159050919050565b6000819050919050565b60006112f9826112c6565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561135757808201518184015260208101905061133c565b83811115611366576000848401525b50505050565b611375826113fe565b810181811067ffffffffffffffff821117156113945761139361139d565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f756e61757468656e746963617465642073656e64657200000000000000000000600082015250565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b61146a816112c6565b811461147557600080fd5b50565b611481816112d8565b811461148c57600080fd5b50565b611498816112e4565b81146114a357600080fd5b50565b6114af816112ee565b81146114ba57600080fd5b50565b6114c681611320565b81146114d157600080fd5b5056fea2646970667358221220e090c5cd81361f8bba5d13d4fb801ab148714dad774e12a4acf812e341dc93c564736f6c63430008070033 diff --git a/pkg/contracts/testdappv2/TestDAppV2.go b/pkg/contracts/testdappv2/TestDAppV2.go index 689014c847..50e4bbcecb 100644 --- a/pkg/contracts/testdappv2/TestDAppV2.go +++ b/pkg/contracts/testdappv2/TestDAppV2.go @@ -36,6 +36,7 @@ type TestDAppV2MessageContext struct { // TestDAppV2RevertContext is an auto generated low-level Go binding around an user-defined struct. type TestDAppV2RevertContext struct { + Sender common.Address Asset common.Address Amount uint64 RevertMessage []byte @@ -50,8 +51,8 @@ type TestDAppV2zContext struct { // TestDAppV2MetaData contains all meta data concerning the TestDAppV2 contract. var TestDAppV2MetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"amountWithMessage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"calledWithMessage\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"erc20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"erc20Call\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"expectedOnCallSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"gasCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"getAmountWithMessage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"getCalledWithMessage\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"internalType\":\"structTestDAppV2.MessageContext\",\"name\":\"messageContext\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"onCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"origin\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainID\",\"type\":\"uint256\"}],\"internalType\":\"structTestDAppV2.zContext\",\"name\":\"_context\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"_zrc20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"onCrossChainCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"amount\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"revertMessage\",\"type\":\"bytes\"}],\"internalType\":\"structTestDAppV2.RevertContext\",\"name\":\"revertContext\",\"type\":\"tuple\"}],\"name\":\"onRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"senderWithMessage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_expectedOnCallSender\",\"type\":\"address\"}],\"name\":\"setExpectedOnCallSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"simpleCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", - Bin: "0x608060405234801561001057600080fd5b5061147c806100206000396000f3fe6080604052600436106100c65760003560e01c8063a799911f1161007f578063de43156e11610059578063de43156e14610267578063e2842ed714610290578063f592cbfb146102cd578063f936ae851461030a576100cd565b8063a799911f146101f9578063c234fecf14610215578063c7a339a91461023e576100cd565b806336e980a0146100d25780634297a263146100fb57806359f4a77714610138578063660b9de014610163578063676cc0541461018c5780639291fe26146101bc576100cd565b366100cd57005b600080fd5b3480156100de57600080fd5b506100f960048036038101906100f49190610b78565b610347565b005b34801561010757600080fd5b50610122600480360381019061011d9190610bf7565b610371565b60405161012f9190610c3d565b60405180910390f35b34801561014457600080fd5b5061014d610389565b60405161015a9190610c99565b60405180910390f35b34801561016f57600080fd5b5061018a60048036038101906101859190610cd8565b6103ad565b005b6101a660048036038101906101a19190610da0565b610468565b6040516101b39190610e88565b60405180910390f35b3480156101c857600080fd5b506101e360048036038101906101de9190610b78565b61061d565b6040516101f09190610c3d565b60405180910390f35b610213600480360381019061020e9190610b78565b610660565b005b34801561022157600080fd5b5061023c60048036038101906102379190610ed6565b610689565b005b34801561024a57600080fd5b5061026560048036038101906102609190610f6d565b6106cc565b005b34801561027357600080fd5b5061028e60048036038101906102899190610ffb565b610780565b005b34801561029c57600080fd5b506102b760048036038101906102b29190610bf7565b610879565b6040516102c491906110ba565b60405180910390f35b3480156102d957600080fd5b506102f460048036038101906102ef9190610b78565b610899565b60405161030191906110ba565b60405180910390f35b34801561031657600080fd5b50610331600480360381019061032c9190611176565b6108e9565b60405161033e9190610c99565b60405180910390f35b61035081610932565b1561035a57600080fd5b61036381610988565b61036e8160006109dc565b50565b60036020528060005260406000206000915090505481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6104088180604001906103c091906111ce565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b61046581806040019061041b91906111ce565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060006109dc565b50565b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168460000160208101906104b49190610ed6565b73ffffffffffffffffffffffffffffffffffffffff161461050a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105019061128e565b60405180910390fd5b61055783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b6105a583838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050346109dc565b8360000160208101906105b89190610ed6565b600284846040516105ca9291906112de565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509392505050565b60006003600083604051602001610634919061133e565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b61066981610932565b1561067357600080fd5b61067c81610988565b61068681346109dc565b50565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6106d581610932565b156106df57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161071c93929190611355565b6020604051808303816000875af115801561073b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075f91906113b8565b61076857600080fd5b61077181610988565b61077b81836109dc565b505050565b6107cd82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610932565b156107d757600080fd5b61082482828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b61087282828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050846109dc565b5050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b600060016000836040516020016108b0919061133e565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b6002818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060405160200161094390611431565b604051602081830303815290604052805190602001208260405160200161096a919061133e565b60405160208183030381529060405280519060200120149050919050565b60018060008360405160200161099e919061133e565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b8060036000846040516020016109f2919061133e565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610a8582610a3c565b810181811067ffffffffffffffff82111715610aa457610aa3610a4d565b5b80604052505050565b6000610ab7610a1e565b9050610ac38282610a7c565b919050565b600067ffffffffffffffff821115610ae357610ae2610a4d565b5b610aec82610a3c565b9050602081019050919050565b82818337600083830152505050565b6000610b1b610b1684610ac8565b610aad565b905082815260208101848484011115610b3757610b36610a37565b5b610b42848285610af9565b509392505050565b600082601f830112610b5f57610b5e610a32565b5b8135610b6f848260208601610b08565b91505092915050565b600060208284031215610b8e57610b8d610a28565b5b600082013567ffffffffffffffff811115610bac57610bab610a2d565b5b610bb884828501610b4a565b91505092915050565b6000819050919050565b610bd481610bc1565b8114610bdf57600080fd5b50565b600081359050610bf181610bcb565b92915050565b600060208284031215610c0d57610c0c610a28565b5b6000610c1b84828501610be2565b91505092915050565b6000819050919050565b610c3781610c24565b82525050565b6000602082019050610c526000830184610c2e565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610c8382610c58565b9050919050565b610c9381610c78565b82525050565b6000602082019050610cae6000830184610c8a565b92915050565b600080fd5b600060608284031215610ccf57610cce610cb4565b5b81905092915050565b600060208284031215610cee57610ced610a28565b5b600082013567ffffffffffffffff811115610d0c57610d0b610a2d565b5b610d1884828501610cb9565b91505092915050565b600060208284031215610d3757610d36610cb4565b5b81905092915050565b600080fd5b600080fd5b60008083601f840112610d6057610d5f610a32565b5b8235905067ffffffffffffffff811115610d7d57610d7c610d40565b5b602083019150836001820283011115610d9957610d98610d45565b5b9250929050565b600080600060408486031215610db957610db8610a28565b5b6000610dc786828701610d21565b935050602084013567ffffffffffffffff811115610de857610de7610a2d565b5b610df486828701610d4a565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b60005b83811015610e3a578082015181840152602081019050610e1f565b83811115610e49576000848401525b50505050565b6000610e5a82610e00565b610e648185610e0b565b9350610e74818560208601610e1c565b610e7d81610a3c565b840191505092915050565b60006020820190508181036000830152610ea28184610e4f565b905092915050565b610eb381610c78565b8114610ebe57600080fd5b50565b600081359050610ed081610eaa565b92915050565b600060208284031215610eec57610eeb610a28565b5b6000610efa84828501610ec1565b91505092915050565b6000610f0e82610c78565b9050919050565b610f1e81610f03565b8114610f2957600080fd5b50565b600081359050610f3b81610f15565b92915050565b610f4a81610c24565b8114610f5557600080fd5b50565b600081359050610f6781610f41565b92915050565b600080600060608486031215610f8657610f85610a28565b5b6000610f9486828701610f2c565b9350506020610fa586828701610f58565b925050604084013567ffffffffffffffff811115610fc657610fc5610a2d565b5b610fd286828701610b4a565b9150509250925092565b600060608284031215610ff257610ff1610cb4565b5b81905092915050565b60008060008060006080868803121561101757611016610a28565b5b600086013567ffffffffffffffff81111561103557611034610a2d565b5b61104188828901610fdc565b955050602061105288828901610ec1565b945050604061106388828901610f58565b935050606086013567ffffffffffffffff81111561108457611083610a2d565b5b61109088828901610d4a565b92509250509295509295909350565b60008115159050919050565b6110b48161109f565b82525050565b60006020820190506110cf60008301846110ab565b92915050565b600067ffffffffffffffff8211156110f0576110ef610a4d565b5b6110f982610a3c565b9050602081019050919050565b6000611119611114846110d5565b610aad565b90508281526020810184848401111561113557611134610a37565b5b611140848285610af9565b509392505050565b600082601f83011261115d5761115c610a32565b5b813561116d848260208601611106565b91505092915050565b60006020828403121561118c5761118b610a28565b5b600082013567ffffffffffffffff8111156111aa576111a9610a2d565b5b6111b684828501611148565b91505092915050565b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126111eb576111ea6111bf565b5b80840192508235915067ffffffffffffffff82111561120d5761120c6111c4565b5b602083019250600182023603831315611229576112286111c9565b5b509250929050565b600082825260208201905092915050565b7f756e61757468656e746963617465642073656e64657200000000000000000000600082015250565b6000611278601683611231565b915061128382611242565b602082019050919050565b600060208201905081810360008301526112a78161126b565b9050919050565b600081905092915050565b60006112c583856112ae565b93506112d2838584610af9565b82840190509392505050565b60006112eb8284866112b9565b91508190509392505050565b600081519050919050565b600081905092915050565b6000611318826112f7565b6113228185611302565b9350611332818560208601610e1c565b80840191505092915050565b600061134a828461130d565b915081905092915050565b600060608201905061136a6000830186610c8a565b6113776020830185610c8a565b6113846040830184610c2e565b949350505050565b6113958161109f565b81146113a057600080fd5b50565b6000815190506113b28161138c565b92915050565b6000602082840312156113ce576113cd610a28565b5b60006113dc848285016113a3565b91505092915050565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b600061141b600683611302565b9150611426826113e5565b600682019050919050565b600061143c8261140e565b915081905091905056fea264697066735822122046fb444f8c754142359339f5f1d728822414688169d0d22f23bd25c688c73fdf64736f6c634300080a0033", + ABI: "[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"amountWithMessage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"calledWithMessage\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"erc20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"erc20Call\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"expectedOnCallSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"gasCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"getAmountWithMessage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"getCalledWithMessage\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"internalType\":\"structTestDAppV2.MessageContext\",\"name\":\"messageContext\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"onCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"origin\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainID\",\"type\":\"uint256\"}],\"internalType\":\"structTestDAppV2.zContext\",\"name\":\"_context\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"_zrc20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"onCrossChainCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"amount\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"revertMessage\",\"type\":\"bytes\"}],\"internalType\":\"structTestDAppV2.RevertContext\",\"name\":\"revertContext\",\"type\":\"tuple\"}],\"name\":\"onRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"senderWithMessage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_expectedOnCallSender\",\"type\":\"address\"}],\"name\":\"setExpectedOnCallSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"simpleCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x608060405234801561001057600080fd5b5061150a806100206000396000f3fe6080604052600436106100c65760003560e01c8063a799911f1161007f578063de43156e11610059578063de43156e14610267578063e2842ed714610290578063f592cbfb146102cd578063f936ae851461030a576100cd565b8063a799911f146101f9578063c234fecf14610215578063c7a339a91461023e576100cd565b806336e980a0146100d25780634297a263146100fb57806359f4a777146101385780635ac1e07014610163578063676cc0541461018c5780639291fe26146101bc576100cd565b366100cd57005b600080fd5b3480156100de57600080fd5b506100f960048036038101906100f49190610de7565b610347565b005b34801561010757600080fd5b50610122600480360381019061011d9190610d02565b610371565b60405161012f9190611173565b60405180910390f35b34801561014457600080fd5b5061014d610389565b60405161015a91906110c4565b60405180910390f35b34801561016f57600080fd5b5061018a60048036038101906101859190610e90565b6103ad565b005b6101a660048036038101906101a19190610e30565b6104e7565b6040516101b39190611131565b60405180910390f35b3480156101c857600080fd5b506101e360048036038101906101de9190610de7565b61069c565b6040516101f09190611173565b60405180910390f35b610213600480360381019061020e9190610de7565b6106df565b005b34801561022157600080fd5b5061023c60048036038101906102379190610ca8565b610708565b005b34801561024a57600080fd5b5061026560048036038101906102609190610d78565b61074b565b005b34801561027357600080fd5b5061028e60048036038101906102899190610ed9565b61080e565b005b34801561029c57600080fd5b506102b760048036038101906102b29190610d02565b610907565b6040516102c49190611116565b60405180910390f35b3480156102d957600080fd5b506102f460048036038101906102ef9190610de7565b610927565b6040516103019190611116565b60405180910390f35b34801561031657600080fd5b50610331600480360381019061032c9190610d2f565b610977565b60405161033e91906110c4565b60405180910390f35b610350816109c0565b1561035a57600080fd5b61036381610a16565b61036e816000610a6a565b50565b60036020528060005260406000206000915090505481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6104088180606001906103c0919061118e565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610a16565b61046581806060019061041b919061118e565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506000610a6a565b8060000160208101906104789190610ca8565b600282806060019061048a919061118e565b60405161049892919061107f565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168460000160208101906105339190610ca8565b73ffffffffffffffffffffffffffffffffffffffff1614610589576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090611153565b60405180910390fd5b6105d683838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610a16565b61062483838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505034610a6a565b8360000160208101906106379190610ca8565b6002848460405161064992919061107f565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509392505050565b600060036000836040516020016106b39190611098565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b6106e8816109c0565b156106f257600080fd5b6106fb81610a16565b6107058134610a6a565b50565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610754816109c0565b1561075e57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161079b939291906110df565b602060405180830381600087803b1580156107b557600080fd5b505af11580156107c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ed9190610cd5565b6107f657600080fd5b6107ff81610a16565b6108098183610a6a565b505050565b61085b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506109c0565b1561086557600080fd5b6108b282828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610a16565b61090082828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084610a6a565b5050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b6000600160008360405160200161093e9190611098565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b6002818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040516020016109d1906110af565b60405160208183030381529060405280519060200120826040516020016109f89190611098565b60405160208183030381529060405280519060200120149050919050565b600180600083604051602001610a2c9190611098565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b806003600084604051602001610a809190611098565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b6000610abf610aba84611216565b6111f1565b905082815260208101848484011115610adb57610ada6113ef565b5b610ae684828561132a565b509392505050565b6000610b01610afc84611247565b6111f1565b905082815260208101848484011115610b1d57610b1c6113ef565b5b610b2884828561132a565b509392505050565b600081359050610b3f81611461565b92915050565b600081519050610b5481611478565b92915050565b600081359050610b698161148f565b92915050565b60008083601f840112610b8557610b846113d1565b5b8235905067ffffffffffffffff811115610ba257610ba16113cc565b5b602083019150836001820283011115610bbe57610bbd6113e5565b5b9250929050565b600082601f830112610bda57610bd96113d1565b5b8135610bea848260208601610aac565b91505092915050565b600081359050610c02816114a6565b92915050565b600082601f830112610c1d57610c1c6113d1565b5b8135610c2d848260208601610aee565b91505092915050565b600060208284031215610c4c57610c4b6113db565b5b81905092915050565b600060808284031215610c6b57610c6a6113db565b5b81905092915050565b600060608284031215610c8a57610c896113db565b5b81905092915050565b600081359050610ca2816114bd565b92915050565b600060208284031215610cbe57610cbd6113f9565b5b6000610ccc84828501610b30565b91505092915050565b600060208284031215610ceb57610cea6113f9565b5b6000610cf984828501610b45565b91505092915050565b600060208284031215610d1857610d176113f9565b5b6000610d2684828501610b5a565b91505092915050565b600060208284031215610d4557610d446113f9565b5b600082013567ffffffffffffffff811115610d6357610d626113f4565b5b610d6f84828501610bc5565b91505092915050565b600080600060608486031215610d9157610d906113f9565b5b6000610d9f86828701610bf3565b9350506020610db086828701610c93565b925050604084013567ffffffffffffffff811115610dd157610dd06113f4565b5b610ddd86828701610c08565b9150509250925092565b600060208284031215610dfd57610dfc6113f9565b5b600082013567ffffffffffffffff811115610e1b57610e1a6113f4565b5b610e2784828501610c08565b91505092915050565b600080600060408486031215610e4957610e486113f9565b5b6000610e5786828701610c36565b935050602084013567ffffffffffffffff811115610e7857610e776113f4565b5b610e8486828701610b6f565b92509250509250925092565b600060208284031215610ea657610ea56113f9565b5b600082013567ffffffffffffffff811115610ec457610ec36113f4565b5b610ed084828501610c55565b91505092915050565b600080600080600060808688031215610ef557610ef46113f9565b5b600086013567ffffffffffffffff811115610f1357610f126113f4565b5b610f1f88828901610c74565b9550506020610f3088828901610b30565b9450506040610f4188828901610c93565b935050606086013567ffffffffffffffff811115610f6257610f616113f4565b5b610f6e88828901610b6f565b92509250509295509295909350565b610f86816112c6565b82525050565b610f95816112d8565b82525050565b6000610fa7838561129f565b9350610fb483858461132a565b82840190509392505050565b6000610fcb82611278565b610fd5818561128e565b9350610fe5818560208601611339565b610fee816113fe565b840191505092915050565b600061100482611283565b61100e81856112bb565b935061101e818560208601611339565b80840191505092915050565b60006110376016836112aa565b91506110428261140f565b602082019050919050565b600061105a6006836112bb565b915061106582611438565b600682019050919050565b61107981611320565b82525050565b600061108c828486610f9b565b91508190509392505050565b60006110a48284610ff9565b915081905092915050565b60006110ba8261104d565b9150819050919050565b60006020820190506110d96000830184610f7d565b92915050565b60006060820190506110f46000830186610f7d565b6111016020830185610f7d565b61110e6040830184611070565b949350505050565b600060208201905061112b6000830184610f8c565b92915050565b6000602082019050818103600083015261114b8184610fc0565b905092915050565b6000602082019050818103600083015261116c8161102a565b9050919050565b60006020820190506111886000830184611070565b92915050565b600080833560016020038436030381126111ab576111aa6113e0565b5b80840192508235915067ffffffffffffffff8211156111cd576111cc6113d6565b5b6020830192506001820236038313156111e9576111e86113ea565b5b509250929050565b60006111fb61120c565b9050611207828261136c565b919050565b6000604051905090565b600067ffffffffffffffff8211156112315761123061139d565b5b61123a826113fe565b9050602081019050919050565b600067ffffffffffffffff8211156112625761126161139d565b5b61126b826113fe565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006112d182611300565b9050919050565b60008115159050919050565b6000819050919050565b60006112f9826112c6565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561135757808201518184015260208101905061133c565b83811115611366576000848401525b50505050565b611375826113fe565b810181811067ffffffffffffffff821117156113945761139361139d565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f756e61757468656e746963617465642073656e64657200000000000000000000600082015250565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b61146a816112c6565b811461147557600080fd5b50565b611481816112d8565b811461148c57600080fd5b50565b611498816112e4565b81146114a357600080fd5b50565b6114af816112ee565b81146114ba57600080fd5b50565b6114c681611320565b81146114d157600080fd5b5056fea2646970667358221220e090c5cd81361f8bba5d13d4fb801ab148714dad774e12a4acf812e341dc93c564736f6c63430008070033", } // TestDAppV2ABI is the input ABI used to generate the binding from. @@ -491,23 +492,23 @@ func (_TestDAppV2 *TestDAppV2TransactorSession) OnCrossChainCall(_context TestDA return _TestDAppV2.Contract.OnCrossChainCall(&_TestDAppV2.TransactOpts, _context, _zrc20, amount, message) } -// OnRevert is a paid mutator transaction binding the contract method 0x660b9de0. +// OnRevert is a paid mutator transaction binding the contract method 0x5ac1e070. // -// Solidity: function onRevert((address,uint64,bytes) revertContext) returns() +// Solidity: function onRevert((address,address,uint64,bytes) revertContext) returns() func (_TestDAppV2 *TestDAppV2Transactor) OnRevert(opts *bind.TransactOpts, revertContext TestDAppV2RevertContext) (*types.Transaction, error) { return _TestDAppV2.contract.Transact(opts, "onRevert", revertContext) } -// OnRevert is a paid mutator transaction binding the contract method 0x660b9de0. +// OnRevert is a paid mutator transaction binding the contract method 0x5ac1e070. // -// Solidity: function onRevert((address,uint64,bytes) revertContext) returns() +// Solidity: function onRevert((address,address,uint64,bytes) revertContext) returns() func (_TestDAppV2 *TestDAppV2Session) OnRevert(revertContext TestDAppV2RevertContext) (*types.Transaction, error) { return _TestDAppV2.Contract.OnRevert(&_TestDAppV2.TransactOpts, revertContext) } -// OnRevert is a paid mutator transaction binding the contract method 0x660b9de0. +// OnRevert is a paid mutator transaction binding the contract method 0x5ac1e070. // -// Solidity: function onRevert((address,uint64,bytes) revertContext) returns() +// Solidity: function onRevert((address,address,uint64,bytes) revertContext) returns() func (_TestDAppV2 *TestDAppV2TransactorSession) OnRevert(revertContext TestDAppV2RevertContext) (*types.Transaction, error) { return _TestDAppV2.Contract.OnRevert(&_TestDAppV2.TransactOpts, revertContext) } diff --git a/pkg/contracts/testdappv2/TestDAppV2.json b/pkg/contracts/testdappv2/TestDAppV2.json index 04cbd8756a..3117879927 100644 --- a/pkg/contracts/testdappv2/TestDAppV2.json +++ b/pkg/contracts/testdappv2/TestDAppV2.json @@ -205,6 +205,11 @@ "inputs": [ { "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, { "internalType": "address", "name": "asset", @@ -281,5 +286,5 @@ "type": "receive" } ], - "bin": "608060405234801561001057600080fd5b5061147c806100206000396000f3fe6080604052600436106100c65760003560e01c8063a799911f1161007f578063de43156e11610059578063de43156e14610267578063e2842ed714610290578063f592cbfb146102cd578063f936ae851461030a576100cd565b8063a799911f146101f9578063c234fecf14610215578063c7a339a91461023e576100cd565b806336e980a0146100d25780634297a263146100fb57806359f4a77714610138578063660b9de014610163578063676cc0541461018c5780639291fe26146101bc576100cd565b366100cd57005b600080fd5b3480156100de57600080fd5b506100f960048036038101906100f49190610b78565b610347565b005b34801561010757600080fd5b50610122600480360381019061011d9190610bf7565b610371565b60405161012f9190610c3d565b60405180910390f35b34801561014457600080fd5b5061014d610389565b60405161015a9190610c99565b60405180910390f35b34801561016f57600080fd5b5061018a60048036038101906101859190610cd8565b6103ad565b005b6101a660048036038101906101a19190610da0565b610468565b6040516101b39190610e88565b60405180910390f35b3480156101c857600080fd5b506101e360048036038101906101de9190610b78565b61061d565b6040516101f09190610c3d565b60405180910390f35b610213600480360381019061020e9190610b78565b610660565b005b34801561022157600080fd5b5061023c60048036038101906102379190610ed6565b610689565b005b34801561024a57600080fd5b5061026560048036038101906102609190610f6d565b6106cc565b005b34801561027357600080fd5b5061028e60048036038101906102899190610ffb565b610780565b005b34801561029c57600080fd5b506102b760048036038101906102b29190610bf7565b610879565b6040516102c491906110ba565b60405180910390f35b3480156102d957600080fd5b506102f460048036038101906102ef9190610b78565b610899565b60405161030191906110ba565b60405180910390f35b34801561031657600080fd5b50610331600480360381019061032c9190611176565b6108e9565b60405161033e9190610c99565b60405180910390f35b61035081610932565b1561035a57600080fd5b61036381610988565b61036e8160006109dc565b50565b60036020528060005260406000206000915090505481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6104088180604001906103c091906111ce565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b61046581806040019061041b91906111ce565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060006109dc565b50565b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168460000160208101906104b49190610ed6565b73ffffffffffffffffffffffffffffffffffffffff161461050a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105019061128e565b60405180910390fd5b61055783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b6105a583838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050346109dc565b8360000160208101906105b89190610ed6565b600284846040516105ca9291906112de565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509392505050565b60006003600083604051602001610634919061133e565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b61066981610932565b1561067357600080fd5b61067c81610988565b61068681346109dc565b50565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6106d581610932565b156106df57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161071c93929190611355565b6020604051808303816000875af115801561073b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075f91906113b8565b61076857600080fd5b61077181610988565b61077b81836109dc565b505050565b6107cd82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610932565b156107d757600080fd5b61082482828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610988565b61087282828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050846109dc565b5050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b600060016000836040516020016108b0919061133e565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b6002818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060405160200161094390611431565b604051602081830303815290604052805190602001208260405160200161096a919061133e565b60405160208183030381529060405280519060200120149050919050565b60018060008360405160200161099e919061133e565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b8060036000846040516020016109f2919061133e565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610a8582610a3c565b810181811067ffffffffffffffff82111715610aa457610aa3610a4d565b5b80604052505050565b6000610ab7610a1e565b9050610ac38282610a7c565b919050565b600067ffffffffffffffff821115610ae357610ae2610a4d565b5b610aec82610a3c565b9050602081019050919050565b82818337600083830152505050565b6000610b1b610b1684610ac8565b610aad565b905082815260208101848484011115610b3757610b36610a37565b5b610b42848285610af9565b509392505050565b600082601f830112610b5f57610b5e610a32565b5b8135610b6f848260208601610b08565b91505092915050565b600060208284031215610b8e57610b8d610a28565b5b600082013567ffffffffffffffff811115610bac57610bab610a2d565b5b610bb884828501610b4a565b91505092915050565b6000819050919050565b610bd481610bc1565b8114610bdf57600080fd5b50565b600081359050610bf181610bcb565b92915050565b600060208284031215610c0d57610c0c610a28565b5b6000610c1b84828501610be2565b91505092915050565b6000819050919050565b610c3781610c24565b82525050565b6000602082019050610c526000830184610c2e565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610c8382610c58565b9050919050565b610c9381610c78565b82525050565b6000602082019050610cae6000830184610c8a565b92915050565b600080fd5b600060608284031215610ccf57610cce610cb4565b5b81905092915050565b600060208284031215610cee57610ced610a28565b5b600082013567ffffffffffffffff811115610d0c57610d0b610a2d565b5b610d1884828501610cb9565b91505092915050565b600060208284031215610d3757610d36610cb4565b5b81905092915050565b600080fd5b600080fd5b60008083601f840112610d6057610d5f610a32565b5b8235905067ffffffffffffffff811115610d7d57610d7c610d40565b5b602083019150836001820283011115610d9957610d98610d45565b5b9250929050565b600080600060408486031215610db957610db8610a28565b5b6000610dc786828701610d21565b935050602084013567ffffffffffffffff811115610de857610de7610a2d565b5b610df486828701610d4a565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b60005b83811015610e3a578082015181840152602081019050610e1f565b83811115610e49576000848401525b50505050565b6000610e5a82610e00565b610e648185610e0b565b9350610e74818560208601610e1c565b610e7d81610a3c565b840191505092915050565b60006020820190508181036000830152610ea28184610e4f565b905092915050565b610eb381610c78565b8114610ebe57600080fd5b50565b600081359050610ed081610eaa565b92915050565b600060208284031215610eec57610eeb610a28565b5b6000610efa84828501610ec1565b91505092915050565b6000610f0e82610c78565b9050919050565b610f1e81610f03565b8114610f2957600080fd5b50565b600081359050610f3b81610f15565b92915050565b610f4a81610c24565b8114610f5557600080fd5b50565b600081359050610f6781610f41565b92915050565b600080600060608486031215610f8657610f85610a28565b5b6000610f9486828701610f2c565b9350506020610fa586828701610f58565b925050604084013567ffffffffffffffff811115610fc657610fc5610a2d565b5b610fd286828701610b4a565b9150509250925092565b600060608284031215610ff257610ff1610cb4565b5b81905092915050565b60008060008060006080868803121561101757611016610a28565b5b600086013567ffffffffffffffff81111561103557611034610a2d565b5b61104188828901610fdc565b955050602061105288828901610ec1565b945050604061106388828901610f58565b935050606086013567ffffffffffffffff81111561108457611083610a2d565b5b61109088828901610d4a565b92509250509295509295909350565b60008115159050919050565b6110b48161109f565b82525050565b60006020820190506110cf60008301846110ab565b92915050565b600067ffffffffffffffff8211156110f0576110ef610a4d565b5b6110f982610a3c565b9050602081019050919050565b6000611119611114846110d5565b610aad565b90508281526020810184848401111561113557611134610a37565b5b611140848285610af9565b509392505050565b600082601f83011261115d5761115c610a32565b5b813561116d848260208601611106565b91505092915050565b60006020828403121561118c5761118b610a28565b5b600082013567ffffffffffffffff8111156111aa576111a9610a2d565b5b6111b684828501611148565b91505092915050565b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126111eb576111ea6111bf565b5b80840192508235915067ffffffffffffffff82111561120d5761120c6111c4565b5b602083019250600182023603831315611229576112286111c9565b5b509250929050565b600082825260208201905092915050565b7f756e61757468656e746963617465642073656e64657200000000000000000000600082015250565b6000611278601683611231565b915061128382611242565b602082019050919050565b600060208201905081810360008301526112a78161126b565b9050919050565b600081905092915050565b60006112c583856112ae565b93506112d2838584610af9565b82840190509392505050565b60006112eb8284866112b9565b91508190509392505050565b600081519050919050565b600081905092915050565b6000611318826112f7565b6113228185611302565b9350611332818560208601610e1c565b80840191505092915050565b600061134a828461130d565b915081905092915050565b600060608201905061136a6000830186610c8a565b6113776020830185610c8a565b6113846040830184610c2e565b949350505050565b6113958161109f565b81146113a057600080fd5b50565b6000815190506113b28161138c565b92915050565b6000602082840312156113ce576113cd610a28565b5b60006113dc848285016113a3565b91505092915050565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b600061141b600683611302565b9150611426826113e5565b600682019050919050565b600061143c8261140e565b915081905091905056fea264697066735822122046fb444f8c754142359339f5f1d728822414688169d0d22f23bd25c688c73fdf64736f6c634300080a0033" + "bin": "608060405234801561001057600080fd5b5061150a806100206000396000f3fe6080604052600436106100c65760003560e01c8063a799911f1161007f578063de43156e11610059578063de43156e14610267578063e2842ed714610290578063f592cbfb146102cd578063f936ae851461030a576100cd565b8063a799911f146101f9578063c234fecf14610215578063c7a339a91461023e576100cd565b806336e980a0146100d25780634297a263146100fb57806359f4a777146101385780635ac1e07014610163578063676cc0541461018c5780639291fe26146101bc576100cd565b366100cd57005b600080fd5b3480156100de57600080fd5b506100f960048036038101906100f49190610de7565b610347565b005b34801561010757600080fd5b50610122600480360381019061011d9190610d02565b610371565b60405161012f9190611173565b60405180910390f35b34801561014457600080fd5b5061014d610389565b60405161015a91906110c4565b60405180910390f35b34801561016f57600080fd5b5061018a60048036038101906101859190610e90565b6103ad565b005b6101a660048036038101906101a19190610e30565b6104e7565b6040516101b39190611131565b60405180910390f35b3480156101c857600080fd5b506101e360048036038101906101de9190610de7565b61069c565b6040516101f09190611173565b60405180910390f35b610213600480360381019061020e9190610de7565b6106df565b005b34801561022157600080fd5b5061023c60048036038101906102379190610ca8565b610708565b005b34801561024a57600080fd5b5061026560048036038101906102609190610d78565b61074b565b005b34801561027357600080fd5b5061028e60048036038101906102899190610ed9565b61080e565b005b34801561029c57600080fd5b506102b760048036038101906102b29190610d02565b610907565b6040516102c49190611116565b60405180910390f35b3480156102d957600080fd5b506102f460048036038101906102ef9190610de7565b610927565b6040516103019190611116565b60405180910390f35b34801561031657600080fd5b50610331600480360381019061032c9190610d2f565b610977565b60405161033e91906110c4565b60405180910390f35b610350816109c0565b1561035a57600080fd5b61036381610a16565b61036e816000610a6a565b50565b60036020528060005260406000206000915090505481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6104088180606001906103c0919061118e565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610a16565b61046581806060019061041b919061118e565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506000610a6a565b8060000160208101906104789190610ca8565b600282806060019061048a919061118e565b60405161049892919061107f565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168460000160208101906105339190610ca8565b73ffffffffffffffffffffffffffffffffffffffff1614610589576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058090611153565b60405180910390fd5b6105d683838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610a16565b61062483838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505034610a6a565b8360000160208101906106379190610ca8565b6002848460405161064992919061107f565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509392505050565b600060036000836040516020016106b39190611098565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b6106e8816109c0565b156106f257600080fd5b6106fb81610a16565b6107058134610a6a565b50565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610754816109c0565b1561075e57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161079b939291906110df565b602060405180830381600087803b1580156107b557600080fd5b505af11580156107c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ed9190610cd5565b6107f657600080fd5b6107ff81610a16565b6108098183610a6a565b505050565b61085b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506109c0565b1561086557600080fd5b6108b282828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610a16565b61090082828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084610a6a565b5050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b6000600160008360405160200161093e9190611098565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b6002818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040516020016109d1906110af565b60405160208183030381529060405280519060200120826040516020016109f89190611098565b60405160208183030381529060405280519060200120149050919050565b600180600083604051602001610a2c9190611098565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b806003600084604051602001610a809190611098565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b6000610abf610aba84611216565b6111f1565b905082815260208101848484011115610adb57610ada6113ef565b5b610ae684828561132a565b509392505050565b6000610b01610afc84611247565b6111f1565b905082815260208101848484011115610b1d57610b1c6113ef565b5b610b2884828561132a565b509392505050565b600081359050610b3f81611461565b92915050565b600081519050610b5481611478565b92915050565b600081359050610b698161148f565b92915050565b60008083601f840112610b8557610b846113d1565b5b8235905067ffffffffffffffff811115610ba257610ba16113cc565b5b602083019150836001820283011115610bbe57610bbd6113e5565b5b9250929050565b600082601f830112610bda57610bd96113d1565b5b8135610bea848260208601610aac565b91505092915050565b600081359050610c02816114a6565b92915050565b600082601f830112610c1d57610c1c6113d1565b5b8135610c2d848260208601610aee565b91505092915050565b600060208284031215610c4c57610c4b6113db565b5b81905092915050565b600060808284031215610c6b57610c6a6113db565b5b81905092915050565b600060608284031215610c8a57610c896113db565b5b81905092915050565b600081359050610ca2816114bd565b92915050565b600060208284031215610cbe57610cbd6113f9565b5b6000610ccc84828501610b30565b91505092915050565b600060208284031215610ceb57610cea6113f9565b5b6000610cf984828501610b45565b91505092915050565b600060208284031215610d1857610d176113f9565b5b6000610d2684828501610b5a565b91505092915050565b600060208284031215610d4557610d446113f9565b5b600082013567ffffffffffffffff811115610d6357610d626113f4565b5b610d6f84828501610bc5565b91505092915050565b600080600060608486031215610d9157610d906113f9565b5b6000610d9f86828701610bf3565b9350506020610db086828701610c93565b925050604084013567ffffffffffffffff811115610dd157610dd06113f4565b5b610ddd86828701610c08565b9150509250925092565b600060208284031215610dfd57610dfc6113f9565b5b600082013567ffffffffffffffff811115610e1b57610e1a6113f4565b5b610e2784828501610c08565b91505092915050565b600080600060408486031215610e4957610e486113f9565b5b6000610e5786828701610c36565b935050602084013567ffffffffffffffff811115610e7857610e776113f4565b5b610e8486828701610b6f565b92509250509250925092565b600060208284031215610ea657610ea56113f9565b5b600082013567ffffffffffffffff811115610ec457610ec36113f4565b5b610ed084828501610c55565b91505092915050565b600080600080600060808688031215610ef557610ef46113f9565b5b600086013567ffffffffffffffff811115610f1357610f126113f4565b5b610f1f88828901610c74565b9550506020610f3088828901610b30565b9450506040610f4188828901610c93565b935050606086013567ffffffffffffffff811115610f6257610f616113f4565b5b610f6e88828901610b6f565b92509250509295509295909350565b610f86816112c6565b82525050565b610f95816112d8565b82525050565b6000610fa7838561129f565b9350610fb483858461132a565b82840190509392505050565b6000610fcb82611278565b610fd5818561128e565b9350610fe5818560208601611339565b610fee816113fe565b840191505092915050565b600061100482611283565b61100e81856112bb565b935061101e818560208601611339565b80840191505092915050565b60006110376016836112aa565b91506110428261140f565b602082019050919050565b600061105a6006836112bb565b915061106582611438565b600682019050919050565b61107981611320565b82525050565b600061108c828486610f9b565b91508190509392505050565b60006110a48284610ff9565b915081905092915050565b60006110ba8261104d565b9150819050919050565b60006020820190506110d96000830184610f7d565b92915050565b60006060820190506110f46000830186610f7d565b6111016020830185610f7d565b61110e6040830184611070565b949350505050565b600060208201905061112b6000830184610f8c565b92915050565b6000602082019050818103600083015261114b8184610fc0565b905092915050565b6000602082019050818103600083015261116c8161102a565b9050919050565b60006020820190506111886000830184611070565b92915050565b600080833560016020038436030381126111ab576111aa6113e0565b5b80840192508235915067ffffffffffffffff8211156111cd576111cc6113d6565b5b6020830192506001820236038313156111e9576111e86113ea565b5b509250929050565b60006111fb61120c565b9050611207828261136c565b919050565b6000604051905090565b600067ffffffffffffffff8211156112315761123061139d565b5b61123a826113fe565b9050602081019050919050565b600067ffffffffffffffff8211156112625761126161139d565b5b61126b826113fe565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006112d182611300565b9050919050565b60008115159050919050565b6000819050919050565b60006112f9826112c6565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561135757808201518184015260208101905061133c565b83811115611366576000848401525b50505050565b611375826113fe565b810181811067ffffffffffffffff821117156113945761139361139d565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f756e61757468656e746963617465642073656e64657200000000000000000000600082015250565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b61146a816112c6565b811461147557600080fd5b50565b611481816112d8565b811461148c57600080fd5b50565b611498816112e4565b81146114a357600080fd5b50565b6114af816112ee565b81146114ba57600080fd5b50565b6114c681611320565b81146114d157600080fd5b5056fea2646970667358221220e090c5cd81361f8bba5d13d4fb801ab148714dad774e12a4acf812e341dc93c564736f6c63430008070033" } diff --git a/pkg/contracts/testdappv2/TestDAppV2.sol b/pkg/contracts/testdappv2/TestDAppV2.sol index 431ccf417d..5f301a08cf 100644 --- a/pkg/contracts/testdappv2/TestDAppV2.sol +++ b/pkg/contracts/testdappv2/TestDAppV2.sol @@ -13,10 +13,12 @@ contract TestDAppV2 { } /// @notice Struct containing revert context passed to onRevert. + /// @param sender Address of account that initiated smart contract call. /// @param asset Address of asset, empty if it's gas token. /// @param amount Amount specified with the transaction. /// @param revertMessage Arbitrary data sent back in onRevert. struct RevertContext { + address sender; address asset; uint64 amount; bytes revertMessage; @@ -100,6 +102,7 @@ contract TestDAppV2 { function onRevert(RevertContext calldata revertContext) external { setCalledWithMessage(string(revertContext.revertMessage)); setAmountWithMessage(string(revertContext.revertMessage), 0); + senderWithMessage[revertContext.revertMessage] = revertContext.sender; } function setExpectedOnCallSender(address _expectedOnCallSender) external { diff --git a/testutil/keeper/mocks/crosschain/fungible.go b/testutil/keeper/mocks/crosschain/fungible.go index e7cd2bfe09..d2de2b7a98 100644 --- a/testutil/keeper/mocks/crosschain/fungible.go +++ b/testutil/keeper/mocks/crosschain/fungible.go @@ -418,17 +418,17 @@ func (_m *CrosschainFungibleKeeper) GetUniswapV2Router02Address(ctx types.Contex return r0, r1 } -// ProcessV2RevertDeposit provides a mock function with given fields: ctx, amount, chainID, coinType, asset, revertAddress, callOnRevert, revertMessage -func (_m *CrosschainFungibleKeeper) ProcessV2RevertDeposit(ctx types.Context, amount *big.Int, chainID int64, coinType coin.CoinType, asset string, revertAddress common.Address, callOnRevert bool, revertMessage []byte) error { - ret := _m.Called(ctx, amount, chainID, coinType, asset, revertAddress, callOnRevert, revertMessage) +// ProcessV2RevertDeposit provides a mock function with given fields: ctx, inboundSender, amount, chainID, coinType, asset, revertAddress, callOnRevert, revertMessage +func (_m *CrosschainFungibleKeeper) ProcessV2RevertDeposit(ctx types.Context, inboundSender string, amount *big.Int, chainID int64, coinType coin.CoinType, asset string, revertAddress common.Address, callOnRevert bool, revertMessage []byte) error { + ret := _m.Called(ctx, inboundSender, amount, chainID, coinType, asset, revertAddress, callOnRevert, revertMessage) if len(ret) == 0 { panic("no return value specified for ProcessV2RevertDeposit") } var r0 error - if rf, ok := ret.Get(0).(func(types.Context, *big.Int, int64, coin.CoinType, string, common.Address, bool, []byte) error); ok { - r0 = rf(ctx, amount, chainID, coinType, asset, revertAddress, callOnRevert, revertMessage) + if rf, ok := ret.Get(0).(func(types.Context, string, *big.Int, int64, coin.CoinType, string, common.Address, bool, []byte) error); ok { + r0 = rf(ctx, inboundSender, amount, chainID, coinType, asset, revertAddress, callOnRevert, revertMessage) } else { r0 = ret.Error(0) } diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go index d788e60fe0..17c848613a 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go @@ -341,6 +341,7 @@ func (k Keeper) processFailedOutboundV2(ctx sdk.Context, cctx *types.CrossChainT // process the revert on ZEVM if err := k.fungibleKeeper.ProcessV2RevertDeposit( ctx, + cctx.InboundParams.Sender, cctx.GetCurrentOutboundParam().Amount.BigInt(), chainID, cctx.InboundParams.CoinType, diff --git a/x/crosschain/keeper/gas_payment.go b/x/crosschain/keeper/gas_payment.go index d0bd4921df..ed1417b405 100644 --- a/x/crosschain/keeper/gas_payment.go +++ b/x/crosschain/keeper/gas_payment.go @@ -121,6 +121,12 @@ func (k Keeper) PayGasNativeAndUpdateCctx( return cosmoserrors.Wrap(types.ErrCannotFindGasParams, err.Error()) } + // with V2 protocol, reverts on connected chains can eventually call a onRevert function which can require a higher gas limit + if cctx.ProtocolContractVersion == types.ProtocolContractVersion_V2 && cctx.RevertOptions.CallOnRevert && + !cctx.RevertOptions.RevertGasLimit.IsZero() { + gas.GasLimit = cctx.RevertOptions.RevertGasLimit + } + // calculate the final gas fee outTxGasFee := gas.GasLimit.Mul(gas.GasPrice).Add(gas.ProtocolFlatFee) diff --git a/x/crosschain/types/expected_keepers.go b/x/crosschain/types/expected_keepers.go index c1bc41bdf2..140c9b2db2 100644 --- a/x/crosschain/types/expected_keepers.go +++ b/x/crosschain/types/expected_keepers.go @@ -149,6 +149,7 @@ type FungibleKeeper interface { ) (*evmtypes.MsgEthereumTxResponse, bool, error) ProcessV2RevertDeposit( ctx sdk.Context, + inboundSender string, amount *big.Int, chainID int64, coinType coin.CoinType, diff --git a/x/fungible/keeper/v2_deposits.go b/x/fungible/keeper/v2_deposits.go index 16001d2f58..812f2c0b81 100644 --- a/x/fungible/keeper/v2_deposits.go +++ b/x/fungible/keeper/v2_deposits.go @@ -49,6 +49,7 @@ func (k Keeper) ProcessV2Deposit( // ProcessV2RevertDeposit handles a revert deposit from an inbound tx with protocol version 2 func (k Keeper) ProcessV2RevertDeposit( ctx sdk.Context, + inboundSender string, amount *big.Int, chainID int64, coinType coin.CoinType, @@ -74,7 +75,7 @@ func (k Keeper) ProcessV2RevertDeposit( if callOnRevert { // no asset, call simple revert - _, err := k.CallExecuteRevert(ctx, zrc20Addr, amount, revertAddress, revertMessage) + _, err := k.CallExecuteRevert(ctx, inboundSender, zrc20Addr, amount, revertAddress, revertMessage) return err } else { // no asset, no call, do nothing @@ -87,6 +88,7 @@ func (k Keeper) ProcessV2RevertDeposit( // revert with a ZRC20 asset _, err := k.CallDepositAndRevert( ctx, + inboundSender, zrc20Addr, amount, revertAddress, diff --git a/x/fungible/keeper/v2_evm.go b/x/fungible/keeper/v2_evm.go index 364c857bdc..4f76606151 100644 --- a/x/fungible/keeper/v2_evm.go +++ b/x/fungible/keeper/v2_evm.go @@ -153,6 +153,7 @@ func (k Keeper) CallExecute( // ) func (k Keeper) CallExecuteRevert( ctx sdk.Context, + inboundSender string, zrc20 common.Address, amount *big.Int, target common.Address, @@ -184,6 +185,7 @@ func (k Keeper) CallExecuteRevert( "executeRevert", target, revert.RevertContext{ + Sender: common.HexToAddress(inboundSender), Asset: zrc20, Amount: amount.Uint64(), RevertMessage: message, @@ -203,6 +205,7 @@ func (k Keeper) CallExecuteRevert( // ) func (k Keeper) CallDepositAndRevert( ctx sdk.Context, + inboundSender string, zrc20 common.Address, amount *big.Int, target common.Address, @@ -236,6 +239,7 @@ func (k Keeper) CallDepositAndRevert( amount, target, revert.RevertContext{ + Sender: common.HexToAddress(inboundSender), Asset: zrc20, Amount: amount.Uint64(), RevertMessage: message, diff --git a/zetaclient/chains/evm/signer/v2_sign.go b/zetaclient/chains/evm/signer/v2_sign.go index 81702d2aba..510c0e2a4d 100644 --- a/zetaclient/chains/evm/signer/v2_sign.go +++ b/zetaclient/chains/evm/signer/v2_sign.go @@ -66,6 +66,7 @@ func (signer *Signer) signGatewayExecute( // bytes calldata data func (signer *Signer) signGatewayExecuteRevert( ctx context.Context, + inboundSender string, txData *OutboundData, ) (*ethtypes.Transaction, error) { gatewayABI, err := gatewayevm.GatewayEVMMetaData.GetAbi() @@ -78,6 +79,7 @@ func (signer *Signer) signGatewayExecuteRevert( txData.to, txData.message, revert.RevertContext{ + Sender: common.HexToAddress(inboundSender), Asset: txData.asset, Amount: txData.amount.Uint64(), RevertMessage: txData.revertOptions.RevertMessage, @@ -182,6 +184,7 @@ func (signer *Signer) signERC20CustodyWithdrawAndCall( // bytes calldata data func (signer *Signer) signERC20CustodyWithdrawRevert( ctx context.Context, + inboundSender string, txData *OutboundData, ) (*ethtypes.Transaction, error) { erc20CustodyV2ABI, err := erc20custodyv2.ERC20CustodyMetaData.GetAbi() @@ -196,6 +199,7 @@ func (signer *Signer) signERC20CustodyWithdrawRevert( txData.amount, txData.message, revert.RevertContext{ + Sender: common.HexToAddress(inboundSender), Asset: txData.asset, Amount: txData.amount.Uint64(), RevertMessage: txData.revertOptions.RevertMessage, diff --git a/zetaclient/chains/evm/signer/v2_signer.go b/zetaclient/chains/evm/signer/v2_signer.go index b3a06a19c2..e687454b3b 100644 --- a/zetaclient/chains/evm/signer/v2_signer.go +++ b/zetaclient/chains/evm/signer/v2_signer.go @@ -29,9 +29,9 @@ func (signer *Signer) SignOutboundFromCCTXV2( // no-asset call simply hash msg.value == 0 return signer.signGatewayExecute(ctx, cctx.InboundParams.Sender, outboundData) case evm.OutboundTypeGasWithdrawRevertAndCallOnRevert: - return signer.signGatewayExecuteRevert(ctx, outboundData) + return signer.signGatewayExecuteRevert(ctx, cctx.InboundParams.Sender, outboundData) case evm.OutboundTypeERC20WithdrawRevertAndCallOnRevert: - return signer.signERC20CustodyWithdrawRevert(ctx, outboundData) + return signer.signERC20CustodyWithdrawRevert(ctx, cctx.InboundParams.Sender, outboundData) } return nil, fmt.Errorf("unsupported outbound type %d", outboundType) } From a98979ce7b51a4f040f4a4b866c46a40307c759a Mon Sep 17 00:00:00 2001 From: Alex Gartner Date: Fri, 27 Sep 2024 09:06:40 -0700 Subject: [PATCH 06/14] ci: add option to enable monitoring stack (#2927) * ci: add option to enable monitoring stack * start prometheus faster * update --- .github/workflows/e2e.yml | 9 +++++++++ .github/workflows/reusable-e2e.yml | 14 ++++++++++++++ contrib/localnet/docker-compose.yml | 29 +++++++++++++++++++++++------ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 4214fba551..c3d413ee54 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -17,6 +17,11 @@ on: description: 'Comma separated list of make targets to run (without the start- prefix)' required: true default: '' + enable-monitoring: + description: 'Enable the monitoring stack' + required: true + type: boolean + default: false concurrency: group: e2e-${{ github.head_ref || github.sha }} @@ -40,6 +45,7 @@ jobs: TON_TESTS: ${{ steps.matrix-conditionals.outputs.TON_TESTS }} V2_TESTS: ${{ steps.matrix-conditionals.outputs.V2_TESTS }} V2_MIGRATION_TESTS: ${{ steps.matrix-conditionals.outputs.V2_MIGRATION_TESTS }} + ENABLE_MONITORING: ${{ steps.matrix-conditionals.outputs.ENABLE_MONITORING }} steps: # use api rather than event context to avoid race conditions (label added after push) - id: matrix-conditionals @@ -66,6 +72,7 @@ jobs: core.setOutput('TON_TESTS', labels.includes('TON_TESTS')); core.setOutput('V2_TESTS', labels.includes('V2_TESTS')); // for v2 tests, TODO: remove this once we fully migrate to v2 (https://github.com/zeta-chain/node/issues/2627) core.setOutput('V2_MIGRATION_TESTS', labels.includes('V2_MIGRATION_TESTS')); // for v2 tests, TODO: remove this once we fully migrate to v2 (https://github.com/zeta-chain/node/issues/2627) + core.setOutput('ENABLE_MONITORING', labels.includes('ENABLE_MONITORING')); } else if (context.eventName === 'merge_group') { core.setOutput('DEFAULT_TESTS', true); core.setOutput('UPGRADE_LIGHT_TESTS', true); @@ -110,6 +117,7 @@ jobs: core.setOutput('TON_TESTS', makeTargets.includes('ton-test')); core.setOutput('V2_TESTS', makeTargets.includes('v2-test')); // for v2 tests, TODO: remove this once we fully migrate to v2 (https://github.com/zeta-chain/node/issues/2627) core.setOutput('V2_MIGRATION_TESTS', makeTargets.includes('v2-migration-test')); // for v2 tests, TODO: remove this once we fully migrate to v2 (https://github.com/zeta-chain/node/issues/2627) + core.setOutput('ENABLE_MONITORING', context.payload.inputs['enable-monitoring']); } e2e: @@ -164,6 +172,7 @@ jobs: runs-on: ${{ matrix.runs-on}} run: ${{ matrix.run }} timeout-minutes: "${{ matrix.timeout-minutes || 25 }}" + enable-monitoring: ${{ needs.matrix-conditionals.outputs.ENABLE_MONITORING == 'true' }} secrets: inherit # this allows you to set a required status check e2e-ok: diff --git a/.github/workflows/reusable-e2e.yml b/.github/workflows/reusable-e2e.yml index 5fbe273771..1ef194667e 100644 --- a/.github/workflows/reusable-e2e.yml +++ b/.github/workflows/reusable-e2e.yml @@ -19,6 +19,10 @@ on: required: true type: string default: 'ubuntu-20.04' + enable-monitoring: + description: 'Enable the monitoring stack for this run' + type: boolean + default: false jobs: e2e: @@ -80,9 +84,19 @@ jobs: cache-to: ${{ github.event_name == 'push' && env.CACHE_TO_CONFIG || '' }} target: latest-runtime + - name: Enable monitoring + if: inputs.enable-monitoring + run: | + echo "NODE_COMPOSE_ARGS=${NODE_COMPOSE_ARGS:-} --profile monitoring --profile monitoring-cloudflared" >> $GITHUB_ENV + - name: Start Test run: make ${{ inputs.make-target }} + - name: Get grafana URL + if: inputs.enable-monitoring + run: | + docker logs grafana-cloudflared 2>&1 | grep -oP 'https?://\S+\.trycloudflare\.com' + # use docker logs -f rather than docker attach to make sure we get the initial logs - name: Watch Test run: | diff --git a/contrib/localnet/docker-compose.yml b/contrib/localnet/docker-compose.yml index a56f463389..2c2efbd87f 100644 --- a/contrib/localnet/docker-compose.yml +++ b/contrib/localnet/docker-compose.yml @@ -313,7 +313,7 @@ services: - ssh:/root/.ssh grafana: - image: grafana/grafana:11.2.0 + image: ghcr.io/zeta-chain/grafana-grafana:11.2.0 container_name: grafana hostname: grafana profiles: @@ -333,7 +333,7 @@ services: - prometheus prometheus: - image: prom/prometheus:v2.53.1 + image: ghcr.io/zeta-chain/prom-prometheus:v2.53.1 container_name: prometheus hostname: prometheus profiles: @@ -345,8 +345,7 @@ services: mynetwork: ipv4_address: 172.20.0.31 depends_on: - zetacore0: - condition: service_healthy + - zetacore0 zetachain-exporter: image: zetachain/zetachain-exporter:v2.0.6 @@ -377,7 +376,7 @@ services: loki: container_name: loki - image: grafana/loki:3.1.0 + image: ghcr.io/zeta-chain/grafana-loki:3.1.0 hostname: loki profiles: - monitoring @@ -389,7 +388,7 @@ services: promtail: container_name: promtail - image: grafana/promtail:2.9.9 + image: ghcr.io/zeta-chain/grafana-promtail:2.9.9 hostname: promtail profiles: - monitoring @@ -402,6 +401,24 @@ services: - /var/run/docker.sock:/var/run/docker.sock command: -config.file=/etc/promtail/config.yaml + grafana-cloudflared: + container_name: grafana-cloudflared + image: ghcr.io/zeta-chain/cloudflare-cloudflared:2024.9.1 + hostname: grafana-cloudflared + profiles: + - monitoring-cloudflared + - all + command: + - tunnel + - --no-autoupdate + - --url + - http://grafana:3000 + networks: + mynetwork: + ipv4_address: 172.20.0.35 + depends_on: + - grafana + volumes: ssh: preparams: From 676e1c0c0d058413cf57b3fc622a665e856c7cac Mon Sep 17 00:00:00 2001 From: Alex Gartner Date: Fri, 27 Sep 2024 09:39:26 -0700 Subject: [PATCH 07/14] ci: add rpcimportable test (#2817) * ci: add rpcimportable test * add ci * fmt * use github.com/btcsuite/btcd/btcutil in pkg/chains * remove app imports types tests * use standalone sdkconfig package * fix policies test * move crosschain keeper tests from types to keeper * never seal config in tests * use https://github.com/zeta-chain/ethermint/pull/126 * add some comments * use merged ethermint hash * show resulting go.mod --- .github/workflows/{build.yml => ci.yml} | 39 +++- contrib/rpcimportable/go.mod | 15 ++ contrib/rpcimportable/rpcimportable_test.go | 11 ++ go.mod | 2 +- go.sum | 4 +- pkg/rpc/clients_crosschain.go | 38 ---- pkg/rpc/clients_test.go | 40 ----- pkg/sdkconfig/sdkconfig.go | 36 ++++ testutil/keeper/config.go | 22 --- testutil/keeper/emissions.go | 3 +- x/authority/types/genesis_test.go | 3 +- x/authority/types/policies_test.go | 17 +- x/crosschain/keeper/cctx_test.go | 164 +++++++++++++++++ x/crosschain/types/cctx_test.go | 166 ------------------ ...essage_migrate_erc20_custody_funds_test.go | 4 +- .../types/message_migrate_tss_funds_test.go | 4 +- ..._update_erc20_custody_pause_status_test.go | 4 +- .../types/message_update_tss_address_test.go | 4 +- .../types/message_whitelist_erc20_test.go | 4 +- x/emissions/abci_test.go | 3 +- x/observer/types/message_vote_blame_test.go | 4 +- .../types/message_vote_block_header_test.go | 4 +- zetaclient/zetacore/client_crosschain.go | 47 +++++ zetaclient/zetacore/client_test.go | 41 +++++ 24 files changed, 376 insertions(+), 303 deletions(-) rename .github/workflows/{build.yml => ci.yml} (68%) create mode 100644 contrib/rpcimportable/go.mod create mode 100644 contrib/rpcimportable/rpcimportable_test.go create mode 100644 pkg/sdkconfig/sdkconfig.go create mode 100644 zetaclient/zetacore/client_crosschain.go diff --git a/.github/workflows/build.yml b/.github/workflows/ci.yml similarity index 68% rename from .github/workflows/build.yml rename to .github/workflows/ci.yml index 5e360f442a..518823b42f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: PR Testing +name: ci on: push: @@ -9,7 +9,7 @@ on: pull_request: concurrency: - group: pr-testing-${{ github.head_ref || github.run_id }} + group: ci-${{ github.head_ref || github.run_id }} cancel-in-progress: true env: @@ -93,3 +93,38 @@ jobs: if: always() shell: bash run: rm -rf * + rpcimportable: + runs-on: ubuntu-20.04 + timeout-minutes: 15 + steps: + - uses: actions/checkout@v4 + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.22' + - name: go get node + working-directory: contrib/rpcimportable + run: go get github.com/zeta-chain/node@${{github.event.pull_request.head.sha || github.sha}} + env: + GOPROXY: direct + - name: go mod tidy + working-directory: contrib/rpcimportable + run: go mod tidy + - name: show go.mod + working-directory: contrib/rpcimportable + run: cat go.mod + - name: go test + working-directory: contrib/rpcimportable + run: go test ./... + ci-ok: + runs-on: ubuntu-22.04 + needs: + - build-and-test + - rpcimportable + if: always() + steps: + - if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} + run: | + echo "One of the jobs failed or was cancelled" + exit 1 + diff --git a/contrib/rpcimportable/go.mod b/contrib/rpcimportable/go.mod new file mode 100644 index 0000000000..32fe6d9e3d --- /dev/null +++ b/contrib/rpcimportable/go.mod @@ -0,0 +1,15 @@ +module github.com/zeta-chain/node/contrib/rpcimportable + +go 1.22.5 + +// this go.mod should be empty when committed +// the go.sum should not be committed + +// this replacement is unavoidable until we upgrade cosmos sdk >=v0.50 +// but we should not tolerate any other replacements +replace ( + github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 +) + +// uncomment this for local development/testing/debugging +// replace github.com/zeta-chain/node => ../.. \ No newline at end of file diff --git a/contrib/rpcimportable/rpcimportable_test.go b/contrib/rpcimportable/rpcimportable_test.go new file mode 100644 index 0000000000..b2bc8959a5 --- /dev/null +++ b/contrib/rpcimportable/rpcimportable_test.go @@ -0,0 +1,11 @@ +package rpcimportable + +import ( + "testing" + + "github.com/zeta-chain/node/pkg/rpc" +) + +func TestRPCImportable(t *testing.T) { + _ = rpc.Clients{} +} diff --git a/go.mod b/go.mod index b169010e38..7625fc2047 100644 --- a/go.mod +++ b/go.mod @@ -57,7 +57,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.9.0 - github.com/zeta-chain/ethermint v0.0.0-20240909234716-2fad916e7179 + github.com/zeta-chain/ethermint v0.0.0-20240927155358-f34e2a4a86f1 github.com/zeta-chain/keystone/keys v0.0.0-20240826165841-3874f358c138 github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240924201108-3a274ce7bad0 gitlab.com/thorchain/tss/go-tss v1.6.5 diff --git a/go.sum b/go.sum index b06cf25283..dd2ce7f425 100644 --- a/go.sum +++ b/go.sum @@ -4172,8 +4172,8 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPS github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= -github.com/zeta-chain/ethermint v0.0.0-20240909234716-2fad916e7179 h1:HykzQOeqBYFHPQCLrj7VAhoGOONtYJnt8IvyHNb9/d8= -github.com/zeta-chain/ethermint v0.0.0-20240909234716-2fad916e7179/go.mod h1:NeQEwcKBpKAUxIsii2F+jfyOD94jN/3fzPMv/1kVF9M= +github.com/zeta-chain/ethermint v0.0.0-20240927155358-f34e2a4a86f1 h1:o0Sh6Y2PKcG634hWqRWmWqBteSuoQUDxIR04OX9Llr8= +github.com/zeta-chain/ethermint v0.0.0-20240927155358-f34e2a4a86f1/go.mod h1:NeQEwcKBpKAUxIsii2F+jfyOD94jN/3fzPMv/1kVF9M= github.com/zeta-chain/go-ethereum v1.10.26-spc h1:NvY4rR9yw52wfxWt7YoFsWbaIwVMyOtTsWKqGAXk+sE= github.com/zeta-chain/go-ethereum v1.10.26-spc/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo= github.com/zeta-chain/go-libp2p v0.0.0-20240710192637-567fbaacc2b4 h1:FmO3HfVdZ7LzxBUfg6sVzV7ilKElQU2DZm8PxJ7KcYI= diff --git a/pkg/rpc/clients_crosschain.go b/pkg/rpc/clients_crosschain.go index 30d9c9c926..f1ef8f5e34 100644 --- a/pkg/rpc/clients_crosschain.go +++ b/pkg/rpc/clients_crosschain.go @@ -2,15 +2,12 @@ package rpc import ( "context" - "sort" "cosmossdk.io/errors" - "github.com/cosmos/cosmos-sdk/types/query" "google.golang.org/grpc" "github.com/zeta-chain/node/pkg/chains" "github.com/zeta-chain/node/x/crosschain/types" - "github.com/zeta-chain/node/zetaclient/chains/interfaces" ) // 32MB @@ -157,38 +154,3 @@ func (c *Clients) GetInboundTrackersForChain(ctx context.Context, chainID int64) return resp.InboundTracker, nil } - -// GetAllOutboundTrackerByChain returns all outbound trackers for a chain -func (c *Clients) GetAllOutboundTrackerByChain( - ctx context.Context, - chainID int64, - order interfaces.Order, -) ([]types.OutboundTracker, error) { - in := &types.QueryAllOutboundTrackerByChainRequest{ - Chain: chainID, - Pagination: &query.PageRequest{ - Key: nil, - Offset: 0, - Limit: 2000, - CountTotal: false, - Reverse: false, - }, - } - - resp, err := c.Crosschain.OutboundTrackerAllByChain(ctx, in) - if err != nil { - return nil, errors.Wrap(err, "failed to get all outbound trackers") - } - - if order == interfaces.Ascending { - sort.SliceStable(resp.OutboundTracker, func(i, j int) bool { - return resp.OutboundTracker[i].Nonce < resp.OutboundTracker[j].Nonce - }) - } else if order == interfaces.Descending { - sort.SliceStable(resp.OutboundTracker, func(i, j int) bool { - return resp.OutboundTracker[i].Nonce > resp.OutboundTracker[j].Nonce - }) - } - - return resp.OutboundTracker, nil -} diff --git a/pkg/rpc/clients_test.go b/pkg/rpc/clients_test.go index ca5abf0d92..9e14266770 100644 --- a/pkg/rpc/clients_test.go +++ b/pkg/rpc/clients_test.go @@ -12,7 +12,6 @@ import ( tmtypes "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/query" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/stretchr/testify/require" @@ -27,7 +26,6 @@ import ( crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" lightclienttypes "github.com/zeta-chain/node/x/lightclient/types" observertypes "github.com/zeta-chain/node/x/observer/types" - "github.com/zeta-chain/node/zetaclient/chains/interfaces" ) const skipMethod = "skip" @@ -688,44 +686,6 @@ func TestZetacore_GetOutboundTracker(t *testing.T) { require.Equal(t, expectedOutput.OutboundTracker, *resp) } -func TestZetacore_GetAllOutboundTrackerByChain(t *testing.T) { - ctx := context.Background() - - chain := chains.BscMainnet - expectedOutput := crosschaintypes.QueryAllOutboundTrackerByChainResponse{ - OutboundTracker: []crosschaintypes.OutboundTracker{ - { - Index: "tracker23456", - ChainId: chain.ChainId, - Nonce: 123456, - HashList: nil, - }, - }, - } - input := crosschaintypes.QueryAllOutboundTrackerByChainRequest{ - Chain: chain.ChainId, - Pagination: &query.PageRequest{ - Key: nil, - Offset: 0, - Limit: 2000, - CountTotal: false, - Reverse: false, - }, - } - method := "/zetachain.zetacore.crosschain.Query/OutboundTrackerAllByChain" - setupMockServer(t, crosschaintypes.RegisterQueryServer, method, input, expectedOutput) - - client := setupZetacoreClients(t) - - resp, err := client.GetAllOutboundTrackerByChain(ctx, chain.ChainId, interfaces.Ascending) - require.NoError(t, err) - require.Equal(t, expectedOutput.OutboundTracker, resp) - - resp, err = client.GetAllOutboundTrackerByChain(ctx, chain.ChainId, interfaces.Descending) - require.NoError(t, err) - require.Equal(t, expectedOutput.OutboundTracker, resp) -} - func TestZetacore_GetPendingNoncesByChain(t *testing.T) { ctx := context.Background() diff --git a/pkg/sdkconfig/sdkconfig.go b/pkg/sdkconfig/sdkconfig.go new file mode 100644 index 0000000000..37149496f0 --- /dev/null +++ b/pkg/sdkconfig/sdkconfig.go @@ -0,0 +1,36 @@ +package sdkconfig + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const ( + AccountAddressPrefix = "zeta" +) + +var ( + AccountPubKeyPrefix = AccountAddressPrefix + "pub" + ValidatorAddressPrefix = AccountAddressPrefix + "valoper" + ValidatorPubKeyPrefix = AccountAddressPrefix + "valoperpub" + ConsNodeAddressPrefix = AccountAddressPrefix + "valcons" + ConsNodePubKeyPrefix = AccountAddressPrefix + "valconspub" +) + +func SetDefault(seal bool) { + config := sdk.GetConfig() + config.SetBech32PrefixForAccount(AccountAddressPrefix, AccountPubKeyPrefix) + config.SetBech32PrefixForValidator(ValidatorAddressPrefix, ValidatorPubKeyPrefix) + config.SetBech32PrefixForConsensusNode(ConsNodeAddressPrefix, ConsNodePubKeyPrefix) + if seal { + config.Seal() + } +} + +func Set(config *sdk.Config, seal bool) { + config.SetBech32PrefixForAccount(AccountAddressPrefix, AccountPubKeyPrefix) + config.SetBech32PrefixForValidator(ValidatorAddressPrefix, ValidatorPubKeyPrefix) + config.SetBech32PrefixForConsensusNode(ConsNodeAddressPrefix, ConsNodePubKeyPrefix) + if seal { + config.Seal() + } +} diff --git a/testutil/keeper/config.go b/testutil/keeper/config.go index 58826dd5a7..732f7c0a03 100644 --- a/testutil/keeper/config.go +++ b/testutil/keeper/config.go @@ -30,28 +30,6 @@ import ( observertypes "github.com/zeta-chain/node/x/observer/types" ) -const ( - AccountAddressPrefix = "zeta" -) - -var ( - AccountPubKeyPrefix = AccountAddressPrefix + "pub" - ValidatorAddressPrefix = AccountAddressPrefix + "valoper" - ValidatorPubKeyPrefix = AccountAddressPrefix + "valoperpub" - ConsNodeAddressPrefix = AccountAddressPrefix + "valcons" - ConsNodePubKeyPrefix = AccountAddressPrefix + "valconspub" -) - -func SetConfig(seal bool) { - config := sdk.GetConfig() - config.SetBech32PrefixForAccount(AccountAddressPrefix, AccountPubKeyPrefix) - config.SetBech32PrefixForValidator(ValidatorAddressPrefix, ValidatorPubKeyPrefix) - config.SetBech32PrefixForConsensusNode(ConsNodeAddressPrefix, ConsNodePubKeyPrefix) - if seal { - config.Seal() - } -} - func StoreKeys() ( map[string]*storetypes.KVStoreKey, map[string]*storetypes.MemoryStoreKey, diff --git a/testutil/keeper/emissions.go b/testutil/keeper/emissions.go index 99c385f72d..b2ce7a004c 100644 --- a/testutil/keeper/emissions.go +++ b/testutil/keeper/emissions.go @@ -12,6 +12,7 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/stretchr/testify/require" + "github.com/zeta-chain/node/pkg/sdkconfig" emissionsmocks "github.com/zeta-chain/node/testutil/keeper/mocks/emissions" "github.com/zeta-chain/node/x/emissions/keeper" "github.com/zeta-chain/node/x/emissions/types" @@ -32,7 +33,7 @@ func EmissionKeeperWithMockOptions( t testing.TB, mockOptions EmissionMockOptions, ) (*keeper.Keeper, sdk.Context, SDKKeepers, ZetaKeepers) { - SetConfig(false) + sdkconfig.SetDefault(false) storeKey := sdk.NewKVStoreKey(types.StoreKey) memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) diff --git a/x/authority/types/genesis_test.go b/x/authority/types/genesis_test.go index 251a3192ba..8266a2e3a8 100644 --- a/x/authority/types/genesis_test.go +++ b/x/authority/types/genesis_test.go @@ -7,12 +7,13 @@ import ( "github.com/stretchr/testify/require" "github.com/zeta-chain/node/pkg/chains" + "github.com/zeta-chain/node/pkg/sdkconfig" "github.com/zeta-chain/node/testutil/sample" "github.com/zeta-chain/node/x/authority/types" ) func TestGenesisState_Validate(t *testing.T) { - setConfig(t) + sdkconfig.SetDefault(false) tests := []struct { name string diff --git a/x/authority/types/policies_test.go b/x/authority/types/policies_test.go index faa35993a5..7fa222af69 100644 --- a/x/authority/types/policies_test.go +++ b/x/authority/types/policies_test.go @@ -3,28 +3,15 @@ package types_test import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - "github.com/zeta-chain/node/app" + "github.com/zeta-chain/node/pkg/sdkconfig" "github.com/zeta-chain/node/testutil/sample" "github.com/zeta-chain/node/x/authority/types" ) -// setConfig sets the global config to use zeta chain's bech32 prefixes -func setConfig(t *testing.T) { - defer func(t *testing.T) { - if r := recover(); r != nil { - t.Log("config is already sealed", r) - } - }(t) - cfg := sdk.GetConfig() - cfg.SetBech32PrefixForAccount(app.Bech32PrefixAccAddr, app.Bech32PrefixAccPub) - cfg.Seal() -} - func TestPolicies_Validate(t *testing.T) { - setConfig(t) + sdkconfig.SetDefault(false) // use table driven tests to test the validation of policies tests := []struct { name string diff --git a/x/crosschain/keeper/cctx_test.go b/x/crosschain/keeper/cctx_test.go index 9b17f825d6..8a51b4cf2a 100644 --- a/x/crosschain/keeper/cctx_test.go +++ b/x/crosschain/keeper/cctx_test.go @@ -6,17 +6,21 @@ import ( "testing" "cosmossdk.io/math" + sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/query" "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "github.com/zeta-chain/node/pkg/chains" "github.com/zeta-chain/node/pkg/coin" keepertest "github.com/zeta-chain/node/testutil/keeper" "github.com/zeta-chain/node/testutil/sample" "github.com/zeta-chain/node/x/crosschain/keeper" "github.com/zeta-chain/node/x/crosschain/types" + observertypes "github.com/zeta-chain/node/x/observer/types" ) func createNCctxWithStatus( @@ -290,3 +294,163 @@ func TestKeeper_RemoveCrossChainTx(t *testing.T) { txs = keeper.GetAllCrossChainTx(ctx) require.Equal(t, 4, len(txs)) } + +func TestCrossChainTx_AddOutbound(t *testing.T) { + t.Run("successfully get outbound tx", func(t *testing.T) { + _, ctx, _, _ := keepertest.CrosschainKeeper(t) + cctx := sample.CrossChainTx(t, "test") + hash := sample.Hash().String() + + err := cctx.AddOutbound(ctx, types.MsgVoteOutbound{ + ValueReceived: cctx.GetCurrentOutboundParam().Amount, + ObservedOutboundHash: hash, + ObservedOutboundBlockHeight: 10, + ObservedOutboundGasUsed: 100, + ObservedOutboundEffectiveGasPrice: sdkmath.NewInt(100), + ObservedOutboundEffectiveGasLimit: 20, + }, observertypes.BallotStatus_BallotFinalized_SuccessObservation) + require.NoError(t, err) + require.Equal(t, cctx.GetCurrentOutboundParam().Hash, hash) + require.Equal(t, cctx.GetCurrentOutboundParam().GasUsed, uint64(100)) + require.Equal(t, cctx.GetCurrentOutboundParam().EffectiveGasPrice, sdkmath.NewInt(100)) + require.Equal(t, cctx.GetCurrentOutboundParam().EffectiveGasLimit, uint64(20)) + require.Equal(t, cctx.GetCurrentOutboundParam().ObservedExternalHeight, uint64(10)) + }) + + t.Run("successfully get outbound tx for failed ballot without amount check", func(t *testing.T) { + _, ctx, _, _ := keepertest.CrosschainKeeper(t) + cctx := sample.CrossChainTx(t, "test") + hash := sample.Hash().String() + + err := cctx.AddOutbound(ctx, types.MsgVoteOutbound{ + ObservedOutboundHash: hash, + ObservedOutboundBlockHeight: 10, + ObservedOutboundGasUsed: 100, + ObservedOutboundEffectiveGasPrice: sdkmath.NewInt(100), + ObservedOutboundEffectiveGasLimit: 20, + }, observertypes.BallotStatus_BallotFinalized_FailureObservation) + require.NoError(t, err) + require.Equal(t, cctx.GetCurrentOutboundParam().Hash, hash) + require.Equal(t, cctx.GetCurrentOutboundParam().GasUsed, uint64(100)) + require.Equal(t, cctx.GetCurrentOutboundParam().EffectiveGasPrice, sdkmath.NewInt(100)) + require.Equal(t, cctx.GetCurrentOutboundParam().EffectiveGasLimit, uint64(20)) + require.Equal(t, cctx.GetCurrentOutboundParam().ObservedExternalHeight, uint64(10)) + }) + + t.Run("failed to get outbound tx if amount does not match value received", func(t *testing.T) { + _, ctx, _, _ := keepertest.CrosschainKeeper(t) + + cctx := sample.CrossChainTx(t, "test") + hash := sample.Hash().String() + + err := cctx.AddOutbound(ctx, types.MsgVoteOutbound{ + ValueReceived: sdkmath.NewUint(100), + ObservedOutboundHash: hash, + ObservedOutboundBlockHeight: 10, + ObservedOutboundGasUsed: 100, + ObservedOutboundEffectiveGasPrice: sdkmath.NewInt(100), + ObservedOutboundEffectiveGasLimit: 20, + }, observertypes.BallotStatus_BallotFinalized_SuccessObservation) + require.ErrorIs(t, err, sdkerrors.ErrInvalidRequest) + }) +} + +func Test_NewCCTX(t *testing.T) { + t.Run("should return a cctx with correct values", func(t *testing.T) { + _, ctx, _, _ := keepertest.CrosschainKeeper(t) + senderChain := chains.Goerli + sender := sample.EthAddress() + receiverChain := chains.Goerli + receiver := sample.EthAddress() + creator := sample.AccAddress() + amount := sdkmath.NewUint(42) + message := "test" + inboundBlockHeight := uint64(420) + inboundHash := sample.Hash() + gasLimit := uint64(100) + asset := "test-asset" + eventIndex := uint64(1) + cointType := coin.CoinType_ERC20 + tss := sample.Tss() + msg := types.MsgVoteInbound{ + Creator: creator, + Sender: sender.String(), + SenderChainId: senderChain.ChainId, + Receiver: receiver.String(), + ReceiverChain: receiverChain.ChainId, + Amount: amount, + Message: message, + InboundHash: inboundHash.String(), + InboundBlockHeight: inboundBlockHeight, + CallOptions: &types.CallOptions{ + GasLimit: gasLimit, + }, + CoinType: cointType, + TxOrigin: sender.String(), + Asset: asset, + EventIndex: eventIndex, + ProtocolContractVersion: types.ProtocolContractVersion_V2, + } + cctx, err := types.NewCCTX(ctx, msg, tss.TssPubkey) + require.NoError(t, err) + require.Equal(t, receiver.String(), cctx.GetCurrentOutboundParam().Receiver) + require.Equal(t, receiverChain.ChainId, cctx.GetCurrentOutboundParam().ReceiverChainId) + require.Equal(t, sender.String(), cctx.GetInboundParams().Sender) + require.Equal(t, senderChain.ChainId, cctx.GetInboundParams().SenderChainId) + require.Equal(t, amount, cctx.GetInboundParams().Amount) + require.Equal(t, message, cctx.RelayedMessage) + require.Equal(t, inboundHash.String(), cctx.GetInboundParams().ObservedHash) + require.Equal(t, inboundBlockHeight, cctx.GetInboundParams().ObservedExternalHeight) + require.Equal(t, gasLimit, cctx.GetCurrentOutboundParam().CallOptions.GasLimit) + require.Equal(t, asset, cctx.GetInboundParams().Asset) + require.Equal(t, cointType, cctx.InboundParams.CoinType) + require.Equal(t, uint64(0), cctx.GetCurrentOutboundParam().TssNonce) + require.Equal(t, sdkmath.ZeroUint(), cctx.GetCurrentOutboundParam().Amount) + require.Equal(t, types.CctxStatus_PendingInbound, cctx.CctxStatus.Status) + require.Equal(t, false, cctx.CctxStatus.IsAbortRefunded) + require.Equal(t, types.ProtocolContractVersion_V2, cctx.ProtocolContractVersion) + }) + + t.Run("should return an error if the cctx is invalid", func(t *testing.T) { + _, ctx, _, _ := keepertest.CrosschainKeeper(t) + senderChain := chains.Goerli + sender := sample.EthAddress() + receiverChain := chains.Goerli + receiver := sample.EthAddress() + creator := sample.AccAddress() + amount := sdkmath.NewUint(42) + message := "test" + inboundBlockHeight := uint64(420) + inboundHash := sample.Hash() + gasLimit := uint64(100) + asset := "test-asset" + eventIndex := uint64(1) + cointType := coin.CoinType_ERC20 + tss := sample.Tss() + msg := types.MsgVoteInbound{ + Creator: creator, + Sender: "", + SenderChainId: senderChain.ChainId, + Receiver: receiver.String(), + ReceiverChain: receiverChain.ChainId, + Amount: amount, + Message: message, + InboundHash: inboundHash.String(), + InboundBlockHeight: inboundBlockHeight, + CallOptions: &types.CallOptions{ + GasLimit: gasLimit, + }, + CoinType: cointType, + TxOrigin: sender.String(), + Asset: asset, + EventIndex: eventIndex, + } + _, err := types.NewCCTX(ctx, msg, tss.TssPubkey) + require.ErrorContains(t, err, "sender cannot be empty") + }) + + t.Run("zero value for protocol contract version gives V1", func(t *testing.T) { + cctx := types.CrossChainTx{} + require.Equal(t, types.ProtocolContractVersion_V1, cctx.ProtocolContractVersion) + }) +} diff --git a/x/crosschain/types/cctx_test.go b/x/crosschain/types/cctx_test.go index 0f2f84ac7b..00fbe2ac66 100644 --- a/x/crosschain/types/cctx_test.go +++ b/x/crosschain/types/cctx_test.go @@ -4,16 +4,10 @@ import ( "math/rand" "testing" - sdkmath "cosmossdk.io/math" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/stretchr/testify/require" - "github.com/zeta-chain/node/pkg/chains" - "github.com/zeta-chain/node/pkg/coin" - keepertest "github.com/zeta-chain/node/testutil/keeper" "github.com/zeta-chain/node/testutil/sample" "github.com/zeta-chain/node/x/crosschain/types" - observertypes "github.com/zeta-chain/node/x/observer/types" ) func TestCrossChainTx_GetEVMRevertAddress(t *testing.T) { @@ -63,106 +57,6 @@ func TestCrossChainTx_GetCCTXIndexBytes(t *testing.T) { require.Equal(t, cctx.Index, types.GetCctxIndexFromBytes(indexBytes)) } -func Test_NewCCTX(t *testing.T) { - t.Run("should return a cctx with correct values", func(t *testing.T) { - _, ctx, _, _ := keepertest.CrosschainKeeper(t) - senderChain := chains.Goerli - sender := sample.EthAddress() - receiverChain := chains.Goerli - receiver := sample.EthAddress() - creator := sample.AccAddress() - amount := sdkmath.NewUint(42) - message := "test" - inboundBlockHeight := uint64(420) - inboundHash := sample.Hash() - gasLimit := uint64(100) - asset := "test-asset" - eventIndex := uint64(1) - cointType := coin.CoinType_ERC20 - tss := sample.Tss() - msg := types.MsgVoteInbound{ - Creator: creator, - Sender: sender.String(), - SenderChainId: senderChain.ChainId, - Receiver: receiver.String(), - ReceiverChain: receiverChain.ChainId, - Amount: amount, - Message: message, - InboundHash: inboundHash.String(), - InboundBlockHeight: inboundBlockHeight, - CallOptions: &types.CallOptions{ - GasLimit: gasLimit, - }, - CoinType: cointType, - TxOrigin: sender.String(), - Asset: asset, - EventIndex: eventIndex, - ProtocolContractVersion: types.ProtocolContractVersion_V2, - } - cctx, err := types.NewCCTX(ctx, msg, tss.TssPubkey) - require.NoError(t, err) - require.Equal(t, receiver.String(), cctx.GetCurrentOutboundParam().Receiver) - require.Equal(t, receiverChain.ChainId, cctx.GetCurrentOutboundParam().ReceiverChainId) - require.Equal(t, sender.String(), cctx.GetInboundParams().Sender) - require.Equal(t, senderChain.ChainId, cctx.GetInboundParams().SenderChainId) - require.Equal(t, amount, cctx.GetInboundParams().Amount) - require.Equal(t, message, cctx.RelayedMessage) - require.Equal(t, inboundHash.String(), cctx.GetInboundParams().ObservedHash) - require.Equal(t, inboundBlockHeight, cctx.GetInboundParams().ObservedExternalHeight) - require.Equal(t, gasLimit, cctx.GetCurrentOutboundParam().CallOptions.GasLimit) - require.Equal(t, asset, cctx.GetInboundParams().Asset) - require.Equal(t, cointType, cctx.InboundParams.CoinType) - require.Equal(t, uint64(0), cctx.GetCurrentOutboundParam().TssNonce) - require.Equal(t, sdkmath.ZeroUint(), cctx.GetCurrentOutboundParam().Amount) - require.Equal(t, types.CctxStatus_PendingInbound, cctx.CctxStatus.Status) - require.Equal(t, false, cctx.CctxStatus.IsAbortRefunded) - require.Equal(t, types.ProtocolContractVersion_V2, cctx.ProtocolContractVersion) - }) - - t.Run("should return an error if the cctx is invalid", func(t *testing.T) { - _, ctx, _, _ := keepertest.CrosschainKeeper(t) - senderChain := chains.Goerli - sender := sample.EthAddress() - receiverChain := chains.Goerli - receiver := sample.EthAddress() - creator := sample.AccAddress() - amount := sdkmath.NewUint(42) - message := "test" - inboundBlockHeight := uint64(420) - inboundHash := sample.Hash() - gasLimit := uint64(100) - asset := "test-asset" - eventIndex := uint64(1) - cointType := coin.CoinType_ERC20 - tss := sample.Tss() - msg := types.MsgVoteInbound{ - Creator: creator, - Sender: "", - SenderChainId: senderChain.ChainId, - Receiver: receiver.String(), - ReceiverChain: receiverChain.ChainId, - Amount: amount, - Message: message, - InboundHash: inboundHash.String(), - InboundBlockHeight: inboundBlockHeight, - CallOptions: &types.CallOptions{ - GasLimit: gasLimit, - }, - CoinType: cointType, - TxOrigin: sender.String(), - Asset: asset, - EventIndex: eventIndex, - } - _, err := types.NewCCTX(ctx, msg, tss.TssPubkey) - require.ErrorContains(t, err, "sender cannot be empty") - }) - - t.Run("zero value for protocol contract version gives V1", func(t *testing.T) { - cctx := types.CrossChainTx{} - require.Equal(t, types.ProtocolContractVersion_V1, cctx.ProtocolContractVersion) - }) -} - func TestCrossChainTx_Validate(t *testing.T) { cctx := sample.CrossChainTx(t, "foo") cctx.InboundParams = nil @@ -225,66 +119,6 @@ func TestCrossChainTx_OriginalDestinationChainID(t *testing.T) { require.Equal(t, cctx.OutboundParams[0].ReceiverChainId, cctx.OriginalDestinationChainID()) } -func TestCrossChainTx_AddOutbound(t *testing.T) { - t.Run("successfully get outbound tx", func(t *testing.T) { - _, ctx, _, _ := keepertest.CrosschainKeeper(t) - cctx := sample.CrossChainTx(t, "test") - hash := sample.Hash().String() - - err := cctx.AddOutbound(ctx, types.MsgVoteOutbound{ - ValueReceived: cctx.GetCurrentOutboundParam().Amount, - ObservedOutboundHash: hash, - ObservedOutboundBlockHeight: 10, - ObservedOutboundGasUsed: 100, - ObservedOutboundEffectiveGasPrice: sdkmath.NewInt(100), - ObservedOutboundEffectiveGasLimit: 20, - }, observertypes.BallotStatus_BallotFinalized_SuccessObservation) - require.NoError(t, err) - require.Equal(t, cctx.GetCurrentOutboundParam().Hash, hash) - require.Equal(t, cctx.GetCurrentOutboundParam().GasUsed, uint64(100)) - require.Equal(t, cctx.GetCurrentOutboundParam().EffectiveGasPrice, sdkmath.NewInt(100)) - require.Equal(t, cctx.GetCurrentOutboundParam().EffectiveGasLimit, uint64(20)) - require.Equal(t, cctx.GetCurrentOutboundParam().ObservedExternalHeight, uint64(10)) - }) - - t.Run("successfully get outbound tx for failed ballot without amount check", func(t *testing.T) { - _, ctx, _, _ := keepertest.CrosschainKeeper(t) - cctx := sample.CrossChainTx(t, "test") - hash := sample.Hash().String() - - err := cctx.AddOutbound(ctx, types.MsgVoteOutbound{ - ObservedOutboundHash: hash, - ObservedOutboundBlockHeight: 10, - ObservedOutboundGasUsed: 100, - ObservedOutboundEffectiveGasPrice: sdkmath.NewInt(100), - ObservedOutboundEffectiveGasLimit: 20, - }, observertypes.BallotStatus_BallotFinalized_FailureObservation) - require.NoError(t, err) - require.Equal(t, cctx.GetCurrentOutboundParam().Hash, hash) - require.Equal(t, cctx.GetCurrentOutboundParam().GasUsed, uint64(100)) - require.Equal(t, cctx.GetCurrentOutboundParam().EffectiveGasPrice, sdkmath.NewInt(100)) - require.Equal(t, cctx.GetCurrentOutboundParam().EffectiveGasLimit, uint64(20)) - require.Equal(t, cctx.GetCurrentOutboundParam().ObservedExternalHeight, uint64(10)) - }) - - t.Run("failed to get outbound tx if amount does not match value received", func(t *testing.T) { - _, ctx, _, _ := keepertest.CrosschainKeeper(t) - - cctx := sample.CrossChainTx(t, "test") - hash := sample.Hash().String() - - err := cctx.AddOutbound(ctx, types.MsgVoteOutbound{ - ValueReceived: sdkmath.NewUint(100), - ObservedOutboundHash: hash, - ObservedOutboundBlockHeight: 10, - ObservedOutboundGasUsed: 100, - ObservedOutboundEffectiveGasPrice: sdkmath.NewInt(100), - ObservedOutboundEffectiveGasLimit: 20, - }, observertypes.BallotStatus_BallotFinalized_SuccessObservation) - require.ErrorIs(t, err, sdkerrors.ErrInvalidRequest) - }) -} - func Test_SetRevertOutboundValues(t *testing.T) { t.Run("successfully set revert outbound values", func(t *testing.T) { cctx := sample.CrossChainTx(t, "test") diff --git a/x/crosschain/types/message_migrate_erc20_custody_funds_test.go b/x/crosschain/types/message_migrate_erc20_custody_funds_test.go index 4a6027e8e2..823b2a54a1 100644 --- a/x/crosschain/types/message_migrate_erc20_custody_funds_test.go +++ b/x/crosschain/types/message_migrate_erc20_custody_funds_test.go @@ -8,13 +8,13 @@ import ( "github.com/stretchr/testify/require" "github.com/zeta-chain/node/pkg/chains" - "github.com/zeta-chain/node/testutil/keeper" + "github.com/zeta-chain/node/pkg/sdkconfig" "github.com/zeta-chain/node/testutil/sample" "github.com/zeta-chain/node/x/crosschain/types" ) func TestNewMsgMigrateERC20CustodyFunds_ValidateBasic(t *testing.T) { - keeper.SetConfig(false) + sdkconfig.SetDefault(false) tests := []struct { name string msg *types.MsgMigrateERC20CustodyFunds diff --git a/x/crosschain/types/message_migrate_tss_funds_test.go b/x/crosschain/types/message_migrate_tss_funds_test.go index 48362f207a..5e1ead5913 100644 --- a/x/crosschain/types/message_migrate_tss_funds_test.go +++ b/x/crosschain/types/message_migrate_tss_funds_test.go @@ -8,13 +8,13 @@ import ( "github.com/stretchr/testify/require" "github.com/zeta-chain/node/pkg/chains" - "github.com/zeta-chain/node/testutil/keeper" + "github.com/zeta-chain/node/pkg/sdkconfig" "github.com/zeta-chain/node/testutil/sample" "github.com/zeta-chain/node/x/crosschain/types" ) func TestNewMsgMigrateTssFunds_ValidateBasic(t *testing.T) { - keeper.SetConfig(false) + sdkconfig.SetDefault(false) tests := []struct { name string msg *types.MsgMigrateTssFunds diff --git a/x/crosschain/types/message_update_erc20_custody_pause_status_test.go b/x/crosschain/types/message_update_erc20_custody_pause_status_test.go index cddb141db5..bbd93dbe55 100644 --- a/x/crosschain/types/message_update_erc20_custody_pause_status_test.go +++ b/x/crosschain/types/message_update_erc20_custody_pause_status_test.go @@ -7,13 +7,13 @@ import ( "github.com/stretchr/testify/require" "github.com/zeta-chain/node/pkg/chains" - "github.com/zeta-chain/node/testutil/keeper" + "github.com/zeta-chain/node/pkg/sdkconfig" "github.com/zeta-chain/node/testutil/sample" "github.com/zeta-chain/node/x/crosschain/types" ) func TestNewMsgUpdateERC20CustodyPauseStatus_ValidateBasic(t *testing.T) { - keeper.SetConfig(false) + sdkconfig.SetDefault(false) tests := []struct { name string msg *types.MsgUpdateERC20CustodyPauseStatus diff --git a/x/crosschain/types/message_update_tss_address_test.go b/x/crosschain/types/message_update_tss_address_test.go index 4118611307..d7fca0116c 100644 --- a/x/crosschain/types/message_update_tss_address_test.go +++ b/x/crosschain/types/message_update_tss_address_test.go @@ -6,13 +6,13 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - "github.com/zeta-chain/node/testutil/keeper" + "github.com/zeta-chain/node/pkg/sdkconfig" "github.com/zeta-chain/node/testutil/sample" "github.com/zeta-chain/node/x/crosschain/types" ) func TestMessageUpdateTssAddress_ValidateBasic(t *testing.T) { - keeper.SetConfig(false) + sdkconfig.SetDefault(false) tests := []struct { name string msg *types.MsgUpdateTssAddress diff --git a/x/crosschain/types/message_whitelist_erc20_test.go b/x/crosschain/types/message_whitelist_erc20_test.go index 1cf5d6350c..8219140fd9 100644 --- a/x/crosschain/types/message_whitelist_erc20_test.go +++ b/x/crosschain/types/message_whitelist_erc20_test.go @@ -6,13 +6,13 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - "github.com/zeta-chain/node/testutil/keeper" + "github.com/zeta-chain/node/pkg/sdkconfig" "github.com/zeta-chain/node/testutil/sample" "github.com/zeta-chain/node/x/crosschain/types" ) func TestMsgWhitelistERC20_ValidateBasic(t *testing.T) { - keeper.SetConfig(false) + sdkconfig.SetDefault(false) tests := []struct { name string msg *types.MsgWhitelistERC20 diff --git a/x/emissions/abci_test.go b/x/emissions/abci_test.go index 2ef62ed7b5..26420231fd 100644 --- a/x/emissions/abci_test.go +++ b/x/emissions/abci_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/zeta-chain/node/cmd/zetacored/config" + "github.com/zeta-chain/node/pkg/sdkconfig" keepertest "github.com/zeta-chain/node/testutil/keeper" "github.com/zeta-chain/node/testutil/sample" emissionsModule "github.com/zeta-chain/node/x/emissions" @@ -311,7 +312,7 @@ func TestBeginBlocker(t *testing.T) { } func TestDistributeObserverRewards(t *testing.T) { - keepertest.SetConfig(false) + sdkconfig.SetDefault(false) k, ctx, _, _ := keepertest.EmissionsKeeper(t) observerSet := sample.ObserverSet(4) diff --git a/x/observer/types/message_vote_blame_test.go b/x/observer/types/message_vote_blame_test.go index f7cd5c7eb4..425f7c0888 100644 --- a/x/observer/types/message_vote_blame_test.go +++ b/x/observer/types/message_vote_blame_test.go @@ -7,13 +7,13 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/require" - "github.com/zeta-chain/node/testutil/keeper" + "github.com/zeta-chain/node/pkg/sdkconfig" "github.com/zeta-chain/node/testutil/sample" "github.com/zeta-chain/node/x/observer/types" ) func TestNewMsgVoteBlameMsg_ValidateBasic(t *testing.T) { - keeper.SetConfig(false) + sdkconfig.SetDefault(false) tests := []struct { name string msg *types.MsgVoteBlame diff --git a/x/observer/types/message_vote_block_header_test.go b/x/observer/types/message_vote_block_header_test.go index 88d27b039d..9d5d0d7974 100644 --- a/x/observer/types/message_vote_block_header_test.go +++ b/x/observer/types/message_vote_block_header_test.go @@ -12,13 +12,13 @@ import ( "github.com/zeta-chain/node/pkg/chains" "github.com/zeta-chain/node/pkg/proofs" - "github.com/zeta-chain/node/testutil/keeper" + "github.com/zeta-chain/node/pkg/sdkconfig" "github.com/zeta-chain/node/testutil/sample" "github.com/zeta-chain/node/x/observer/types" ) func TestMsgVoteBlockHeader_ValidateBasic(t *testing.T) { - keeper.SetConfig(false) + sdkconfig.SetDefault(false) var header ethtypes.Header file, err := os.Open("../../../testutil/testdata/eth_header_18495266.json") require.NoError(t, err) diff --git a/zetaclient/zetacore/client_crosschain.go b/zetaclient/zetacore/client_crosschain.go new file mode 100644 index 0000000000..bd40665340 --- /dev/null +++ b/zetaclient/zetacore/client_crosschain.go @@ -0,0 +1,47 @@ +package zetacore + +import ( + "context" + "sort" + + "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/types/query" + + "github.com/zeta-chain/node/x/crosschain/types" + "github.com/zeta-chain/node/zetaclient/chains/interfaces" +) + +// GetAllOutboundTrackerByChain returns all outbound trackers for a chain +func (c *Client) GetAllOutboundTrackerByChain( + ctx context.Context, + chainID int64, + order interfaces.Order, +) ([]types.OutboundTracker, error) { + in := &types.QueryAllOutboundTrackerByChainRequest{ + Chain: chainID, + Pagination: &query.PageRequest{ + Key: nil, + Offset: 0, + Limit: 2000, + CountTotal: false, + Reverse: false, + }, + } + + resp, err := c.Crosschain.OutboundTrackerAllByChain(ctx, in) + if err != nil { + return nil, errors.Wrap(err, "failed to get all outbound trackers") + } + + if order == interfaces.Ascending { + sort.SliceStable(resp.OutboundTracker, func(i, j int) bool { + return resp.OutboundTracker[i].Nonce < resp.OutboundTracker[j].Nonce + }) + } else if order == interfaces.Descending { + sort.SliceStable(resp.OutboundTracker, func(i, j int) bool { + return resp.OutboundTracker[i].Nonce > resp.OutboundTracker[j].Nonce + }) + } + + return resp.OutboundTracker, nil +} diff --git a/zetaclient/zetacore/client_test.go b/zetaclient/zetacore/client_test.go index 060d96515d..c989ef7916 100644 --- a/zetaclient/zetacore/client_test.go +++ b/zetaclient/zetacore/client_test.go @@ -9,12 +9,15 @@ import ( cosmosclient "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/testutil/mock" "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/golang/mock/gomock" "github.com/rs/zerolog" "github.com/stretchr/testify/require" feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" + "github.com/zeta-chain/node/pkg/chains" + "github.com/zeta-chain/node/zetaclient/chains/interfaces" keyinterfaces "github.com/zeta-chain/node/zetaclient/keys/interfaces" "go.nhat.io/grpcmock" "go.nhat.io/grpcmock/planner" @@ -189,3 +192,41 @@ func TestZetacore_GetZetaHotKeyBalance(t *testing.T) { require.Error(t, err) require.Equal(t, types.ZeroInt(), resp) } + +func TestZetacore_GetAllOutboundTrackerByChain(t *testing.T) { + ctx := context.Background() + + chain := chains.BscMainnet + expectedOutput := crosschaintypes.QueryAllOutboundTrackerByChainResponse{ + OutboundTracker: []crosschaintypes.OutboundTracker{ + { + Index: "tracker23456", + ChainId: chain.ChainId, + Nonce: 123456, + HashList: nil, + }, + }, + } + input := crosschaintypes.QueryAllOutboundTrackerByChainRequest{ + Chain: chain.ChainId, + Pagination: &query.PageRequest{ + Key: nil, + Offset: 0, + Limit: 2000, + CountTotal: false, + Reverse: false, + }, + } + method := "/zetachain.zetacore.crosschain.Query/OutboundTrackerAllByChain" + setupMockServer(t, crosschaintypes.RegisterQueryServer, method, input, expectedOutput) + + client := setupZetacoreClient(t, withDefaultObserverKeys()) + + resp, err := client.GetAllOutboundTrackerByChain(ctx, chain.ChainId, interfaces.Ascending) + require.NoError(t, err) + require.Equal(t, expectedOutput.OutboundTracker, resp) + + resp, err = client.GetAllOutboundTrackerByChain(ctx, chain.ChainId, interfaces.Descending) + require.NoError(t, err) + require.Equal(t, expectedOutput.OutboundTracker, resp) +} From cef4cbd2bcda1d1c4ca5dfea7710cac01bcaa751 Mon Sep 17 00:00:00 2001 From: jkan2 Date: Mon, 30 Sep 2024 01:57:04 -0700 Subject: [PATCH 08/14] ci: Add SARIF upload to GitHub Security Dashboard (#2929) * add semgrep sarif upload to GHAS * added comment to clairfy the usage of the utility script * use ghcr.io instead * add tag to image * bad org name --------- Co-authored-by: jkan2 <5862123+jkan2@users.noreply.github.com> --- .github/workflows/semgrep.yml | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml index f76ee3d14b..fcffcf7855 100644 --- a/.github/workflows/semgrep.yml +++ b/.github/workflows/semgrep.yml @@ -15,8 +15,26 @@ jobs: env: SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} container: - image: semgrep/semgrep + image: ghcr.io/zeta-chain/semgrep-semgrep:1.90.0 + if: (github.actor != 'dependabot[bot]') steps: - - uses: actions/checkout@v4 - - run: semgrep ci + - uses: actions/checkout@v4 + - name: Checkout semgrep-utilities repo + uses: actions/checkout@v4 + with: + repository: zeta-chain/semgrep-utilities + path: semgrep-utilities + + # uses json for semgrep script for transformation in the next step + - run: semgrep ci --json --output semgrep-findings.json + + # transforms the the output from the above into a GHAS compatible SARIF + # SARIF output by "semgrep --sarif" doesn't integrate well with GHAS dashboard + # Example: the event name uses segmrep rules name/ID, severities are [error, warning, info], tags are a bit confusing) + - run: python semgrep-utilities/utilities/github-sarif-helper/src/semgrep-json-to-sarif.py --json semgrep-findings.json --sarif semgrep-github.sarif + + - name: Upload SARIF file for GitHub Advanced Security Dashboard + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: semgrep-github.sarif From 5bfe97615861e7d5326c7426d60ba007dbf2f7e0 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Mon, 30 Sep 2024 15:27:30 +0530 Subject: [PATCH 09/14] fix: add recover to InitChainer to diplay informative message when starting a node from block 1 (#2925) * add recover to InitChainer * generate files * add docs link to error message * move InitChainErrorMessage to app.go * Update app/app.go Co-authored-by: Francisco de Borja Aranda Castillejo * use const for message --------- Co-authored-by: Francisco de Borja Aranda Castillejo --- app/app.go | 21 +++++++++++++++++++++ changelog.md | 1 + 2 files changed, 22 insertions(+) diff --git a/app/app.go b/app/app.go index cc271fc35f..4fe5595199 100644 --- a/app/app.go +++ b/app/app.go @@ -4,6 +4,7 @@ import ( "io" "net/http" "os" + "runtime/debug" "time" cosmoserrors "cosmossdk.io/errors" @@ -876,6 +877,26 @@ func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.Respo // InitChainer application update at chain initialization func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + // InitChainErrorMessage is the error message displayed when trying to sync testnet or mainnet from block 1 using the latest binary. + const InitChainErrorMessage = ` +Unable to sync testnet or mainnet from block 1 using the latest version. +Please use a snapshot to sync your node. +Refer to the documentation for more information: +https://www.zetachain.com/docs/nodes/start-here/syncing/` + + // The defer is used to catch panics during InitChain + // and display a more meaningful message for people trying to sync a node from block 1 using the latest binary. + // We exit the process after displaying the message as we do not need to start a node with empty state. + + defer func() { + if r := recover(); r != nil { + ctx.Logger().Error("panic occurred during InitGenesis", "error", r) + ctx.Logger().Debug("stack trace", "stack", string(debug.Stack())) + ctx.Logger(). + Info(InitChainErrorMessage) + os.Exit(1) + } + }() var genesisState GenesisState if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil { panic(err) diff --git a/changelog.md b/changelog.md index d78c1861ae..437b97382d 100644 --- a/changelog.md +++ b/changelog.md @@ -45,6 +45,7 @@ * [2944](https://github.com/zeta-chain/node/pull/2844) - add tsspubkey to index for tss keygen voting * [2842](https://github.com/zeta-chain/node/pull/2842) - fix: move interval assignment out of cctx loop in EVM outbound tx scheduler * [2853](https://github.com/zeta-chain/node/pull/2853) - calling precompile through sc with sc state update +* [2925](https://github.com/zeta-chain/node/pull/2925) - add recover to init chainer to diplay informative message when starting a node from block 1 ## v20.0.0 From 088351fc8abe66788f6005af8ea319b244628487 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Mon, 30 Sep 2024 19:11:09 +0530 Subject: [PATCH 10/14] test: add wait for block to tss migration test (#2931) * add wait for block to tss migration test * add comments * refactor identifiers * rename checkNumberOfTssGenerated to checkNumberOfTSSGenerated --- e2e/e2etests/test_migrate_tss.go | 2 ++ e2e/runner/zeta.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/e2e/e2etests/test_migrate_tss.go b/e2e/e2etests/test_migrate_tss.go index cb5e3c35c4..3825228c14 100644 --- a/e2e/e2etests/test_migrate_tss.go +++ b/e2e/e2etests/test_migrate_tss.go @@ -48,6 +48,8 @@ func TestMigrateTSS(r *runner.E2ERunner, _ []string) { btcBalance = btcBalance - 0.01 btcChain := chains.BitcoinRegtest.ChainId + r.WaitForTSSGeneration(2) + //migrate btc funds // #nosec G701 e2eTest - always in range migrationAmountBTC := sdkmath.NewUint(uint64(btcBalance * 1e8)) diff --git a/e2e/runner/zeta.go b/e2e/runner/zeta.go index cec59219cd..bdada4763c 100644 --- a/e2e/runner/zeta.go +++ b/e2e/runner/zeta.go @@ -15,8 +15,11 @@ import ( "github.com/zeta-chain/node/e2e/utils" "github.com/zeta-chain/node/pkg/retry" "github.com/zeta-chain/node/x/crosschain/types" + observertypes "github.com/zeta-chain/node/x/observer/types" ) +// WaitForBlocks waits for a specific number of blocks to be generated +// The parameter n is the number of blocks to wait for func (r *E2ERunner) WaitForBlocks(n int64) { height, err := r.CctxClient.LastZetaHeight(r.Ctx, &types.QueryLastZetaHeightRequest{}) if err != nil { @@ -31,6 +34,32 @@ func (r *E2ERunner) WaitForBlocks(n int64) { err = retry.DoWithBackoff(call, boWithMaxRetries) require.NoError(r, err, "failed to wait for %d blocks", n) } + +// WaitForTSSGeneration waits for a specific number of TSS to be generated +// The parameter n is the number of TSS to wait for +func (r *E2ERunner) WaitForTSSGeneration(tssNumber int64) { + call := func() error { + return retry.Retry(r.checkNumberOfTSSGenerated(tssNumber)) + } + bo := backoff.NewConstantBackOff(time.Second * 5) + boWithMaxRetries := backoff.WithMaxRetries(bo, 10) + err := retry.DoWithBackoff(call, boWithMaxRetries) + require.NoError(r, err, "failed to wait for %d tss generation", tssNumber) +} + +// checkNumberOfTSSGenerated checks the number of TSS generated +// if the number of tss is less that the `tssNumber` provided we return an error +func (r *E2ERunner) checkNumberOfTSSGenerated(tssNumber int64) error { + tssList, err := r.ObserverClient.TssHistory(r.Ctx, &observertypes.QueryTssHistoryRequest{}) + if err != nil { + return err + } + if int64(len(tssList.TssList)) < tssNumber { + return fmt.Errorf("waiting for %d tss generation, number of TSS :%d", tssNumber, len(tssList.TssList)) + } + return nil +} + func (r *E2ERunner) waitForBlock(n int64) error { height, err := r.CctxClient.LastZetaHeight(r.Ctx, &types.QueryLastZetaHeightRequest{}) if err != nil { From 8f888cacf6fcdcfadae77731797f7ca44a9c9023 Mon Sep 17 00:00:00 2001 From: Alex Gartner Date: Tue, 1 Oct 2024 00:16:13 -0700 Subject: [PATCH 11/14] chore: allow full zetaclient config overlay (#2945) --- .gitignore | 2 +- contrib/localnet/scripts/start-zetaclientd.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index e0f51f8d4a..3f8e6a6ff4 100644 --- a/.gitignore +++ b/.gitignore @@ -56,4 +56,4 @@ contrib/localnet/addresses.txt # Config for e2e tests e2e_conf* -contrib/localnet/scripts/extra-evm-chains.json \ No newline at end of file +contrib/localnet/scripts/zetaclient-config-overlay.json \ No newline at end of file diff --git a/contrib/localnet/scripts/start-zetaclientd.sh b/contrib/localnet/scripts/start-zetaclientd.sh index 7d2768b177..e403e2d599 100755 --- a/contrib/localnet/scripts/start-zetaclientd.sh +++ b/contrib/localnet/scripts/start-zetaclientd.sh @@ -109,9 +109,9 @@ then fi fi -# merge extra-evm-chains.json into zetaclient_config.json if specified -if [[ -f /root/extra-evm-chains.json ]]; then - jq '.EVMChainConfigs *= input' /root/.zetacored/config/zetaclient_config.json /root/extra-evm-chains.json > /tmp/merged_config.json +# merge zetaclient-config-overlay.json into zetaclient_config.json if specified +if [[ -f /root/zetaclient-config-overlay.json ]]; then + jq -s '.[0] * .[1]' /root/.zetacored/config/zetaclient_config.json /root/zetaclient-config-overlay.json > /tmp/merged_config.json mv /tmp/merged_config.json /root/.zetacored/config/zetaclient_config.json fi From 3b3390e3ff565d9e50e4da95d334f77db712c8df Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Tue, 1 Oct 2024 10:10:26 +0200 Subject: [PATCH 12/14] test(e2e): add gateway upgrade in upgrade test (#2932) * add gateway upgrade * change reference * add v2 setup for all tests * test v2 in light upgrade * refactor setup to use custody v2 directly --- Makefile | 4 +- changelog.md | 1 + cmd/zetae2e/local/local.go | 29 ++++++---- .../localnet/orchestrator/start-zetae2e.sh | 4 +- e2e/runner/v2_gateway.go | 55 +++++++++++++++++++ 5 files changed, 78 insertions(+), 15 deletions(-) create mode 100644 e2e/runner/v2_gateway.go diff --git a/Makefile b/Makefile index b3fbf4009a..40053db864 100644 --- a/Makefile +++ b/Makefile @@ -299,12 +299,12 @@ start-v2-test: zetanode ifdef UPGRADE_TEST_FROM_SOURCE zetanode-upgrade: zetanode @echo "Building zetanode-upgrade from source" - $(DOCKER) build -t zetanode:old -f Dockerfile-localnet --target old-runtime-source --build-arg OLD_VERSION='release/v19' . + $(DOCKER) build -t zetanode:old -f Dockerfile-localnet --target old-runtime-source --build-arg OLD_VERSION='release/v20' . .PHONY: zetanode-upgrade else zetanode-upgrade: zetanode @echo "Building zetanode-upgrade from binaries" - $(DOCKER) build -t zetanode:old -f Dockerfile-localnet --target old-runtime --build-arg OLD_VERSION='https://github.com/zeta-chain/node/releases/download/v19.1.1' . + $(DOCKER) build -t zetanode:old -f Dockerfile-localnet --target old-runtime --build-arg OLD_VERSION='https://github.com/zeta-chain/node/releases/download/v20.0.2' . .PHONY: zetanode-upgrade endif diff --git a/changelog.md b/changelog.md index 437b97382d..dc83cb839b 100644 --- a/changelog.md +++ b/changelog.md @@ -36,6 +36,7 @@ * [2874](https://github.com/zeta-chain/node/pull/2874) - add support for multiple runs for precompile tests * [2895](https://github.com/zeta-chain/node/pull/2895) - add e2e test for bitcoin deposit and call * [2894](https://github.com/zeta-chain/node/pull/2894) - increase gas limit for TSS vote tx +* [2932](https://github.com/zeta-chain/node/pull/2932) - add gateway upgrade as part of the upgrade test ### Fixes diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index ced848aadc..4a7fbef39c 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -46,6 +46,7 @@ const ( flagTestV2Migration = "test-v2-migration" flagSkipTrackerCheck = "skip-tracker-check" flagSkipPrecompiles = "skip-precompiles" + flagUpgradeGateways = "upgrade-gateways" ) var ( @@ -83,6 +84,7 @@ func NewLocalCmd() *cobra.Command { cmd.Flags().Bool(flagTestV2Migration, false, "set to true to run tests for v2 contracts migration test") cmd.Flags().Bool(flagSkipTrackerCheck, false, "set to true to skip tracker check at the end of the tests") cmd.Flags().Bool(flagSkipPrecompiles, false, "set to true to skip stateful precompiled contracts test") + cmd.Flags().Bool(flagUpgradeGateways, false, "set to true to upgrade gateways during setup for ZEVM and EVM") return cmd } @@ -112,6 +114,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { testV2 = must(cmd.Flags().GetBool(flagTestV2)) testV2Migration = must(cmd.Flags().GetBool(flagTestV2Migration)) skipPrecompiles = must(cmd.Flags().GetBool(flagSkipPrecompiles)) + upgradeGateways = must(cmd.Flags().GetBool(flagUpgradeGateways)) ) logger := runner.NewLogger(verbose, color.FgWhite, "setup") @@ -202,21 +205,26 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("⚙️ setting up networks") startTime := time.Now() + // TODO: merge v1 and v2 together + // https://github.com/zeta-chain/node/issues/2627 + deployerRunner.SetupEVM(contractsDeployed, true) - if testV2 { - deployerRunner.SetupEVMV2() - } + deployerRunner.SetupEVMV2() deployerRunner.SetZEVMSystemContracts() - if testV2 { - // NOTE: v2 (gateway) setup called here because system contract needs to be set first, then gateway, then zrc20 - deployerRunner.SetZEVMContractsV2() - } + // NOTE: v2 (gateway) setup called here because system contract needs to be set first, then gateway, then zrc20 + deployerRunner.SetZEVMContractsV2() deployerRunner.SetZEVMZRC20s() + // Update the chain params to use v2 contract for ERC20Custody + // TODO: this function should be removed and the chain params should be directly set to use v2 contract + // https://github.com/zeta-chain/node/issues/2627 + deployerRunner.UpdateChainParamsV2Contracts() + deployerRunner.ERC20CustodyAddr = deployerRunner.ERC20CustodyV2Addr + if testSolana { deployerRunner.SetSolanaContracts(conf.AdditionalAccounts.UserSolana.SolanaPrivateKey.String()) } @@ -404,10 +412,9 @@ func localE2ETest(cmd *cobra.Command, _ []string) { eg.Go(tonTestRoutine(conf, deployerRunner, verbose, tonTests...)) } - if testV2 { - // update the ERC20 custody contract for v2 tests - // note: not run in testV2Migration because it is already run in the migration process - deployerRunner.UpdateChainParamsV2Contracts() + // upgrade gateways + if upgradeGateways { + deployerRunner.UpgradeGateways() } if testV2 || testV2Migration { diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index 9977b7dbd9..e7374216f3 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -258,9 +258,9 @@ if [ "$LOCALNET_MODE" == "upgrade" ]; then # When the upgrade height is greater than 100 for upgrade test, the Bitcoin tests have been run once, therefore the Bitcoin wallet is already set up # Use light flag to skip advanced tests if [ "$UPGRADE_HEIGHT" -lt 100 ]; then - zetae2e local $E2E_ARGS --skip-setup --config "$deployed_config_path" --light ${COMMON_ARGS} + zetae2e local $E2E_ARGS --skip-setup --config "$deployed_config_path" --light --test-v2 --upgrade-gateways ${COMMON_ARGS} else - zetae2e local $E2E_ARGS --skip-setup --config "$deployed_config_path" --skip-bitcoin-setup --light ${COMMON_ARGS} + zetae2e local $E2E_ARGS --skip-setup --config "$deployed_config_path" --skip-bitcoin-setup --light --test-v2 --upgrade-gateways ${COMMON_ARGS} fi ZETAE2E_EXIT_CODE=$? diff --git a/e2e/runner/v2_gateway.go b/e2e/runner/v2_gateway.go new file mode 100644 index 0000000000..2bede9e3fe --- /dev/null +++ b/e2e/runner/v2_gateway.go @@ -0,0 +1,55 @@ +package runner + +import ( + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayevm.sol" + "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol" + + "github.com/zeta-chain/node/e2e/utils" +) + +// UpgradeGateways upgrades the GatewayEVM and GatewayZEVM contracts +// It deploy new gateway contract implementation with the current imported artifacts and upgrade the gateway contract +func (r *E2ERunner) UpgradeGateways() { + r.UpgradeGatewayZEVM() + r.UpgradeGatewayEVM() +} + +// UpgradeGatewayZEVM upgrades the GatewayZEVM contract +func (r *E2ERunner) UpgradeGatewayZEVM() { + ensureTxReceipt := func(tx *ethtypes.Transaction, failMessage string) { + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + r.requireTxSuccessful(receipt, failMessage+" tx hash: "+tx.Hash().Hex()) + } + + r.Logger.Info("Upgrading Gateway ZEVM contract") + // Deploy the new gateway contract implementation + newImplementationAddress, txDeploy, _, err := gatewayzevm.DeployGatewayZEVM(r.ZEVMAuth, r.ZEVMClient) + require.NoError(r, err) + ensureTxReceipt(txDeploy, "New GatewayZEVM implementation deployment failed") + + // Upgrade + txUpgrade, err := r.GatewayZEVM.UpgradeToAndCall(r.ZEVMAuth, newImplementationAddress, []byte{}) + require.NoError(r, err) + ensureTxReceipt(txUpgrade, "GatewayZEVM upgrade failed") +} + +// UpgradeGatewayEVM upgrades the GatewayEVM contract +func (r *E2ERunner) UpgradeGatewayEVM() { + ensureTxReceipt := func(tx *ethtypes.Transaction, failMessage string) { + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + r.requireTxSuccessful(receipt, failMessage+" tx hash: "+tx.Hash().Hex()) + } + + r.Logger.Info("Upgrading Gateway EVM contract") + // Deploy the new gateway contract implementation + newImplementationAddress, txDeploy, _, err := gatewayevm.DeployGatewayEVM(r.EVMAuth, r.EVMClient) + require.NoError(r, err) + ensureTxReceipt(txDeploy, "New GatewayEVM implementation deployment failed") + + // Upgrade + txUpgrade, err := r.GatewayEVM.UpgradeToAndCall(r.EVMAuth, newImplementationAddress, []byte{}) + require.NoError(r, err) + ensureTxReceipt(txUpgrade, "GatewayEVM upgrade failed") +} From a178d6f61a97d2fe59cdcd4dc151fb8835d39b29 Mon Sep 17 00:00:00 2001 From: Alex Gartner Date: Tue, 1 Oct 2024 03:27:44 -0700 Subject: [PATCH 13/14] chore: improve localnet build performance (#2928) * chore: improve localnet build performance * propagate NODE_VERSION and NODE_COMMIT --- .dockerignore | 1 + Dockerfile-localnet | 8 ++++++-- Makefile | 14 +++++++------- version.sh | 21 ++++++++++++++------- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/.dockerignore b/.dockerignore index d53ebfff61..1e084d8263 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,6 +4,7 @@ yarn.lock .github/ .gitignore dist/** +.git # dockerfiles are not needed inside the docker build Dockerfile diff --git a/Dockerfile-localnet b/Dockerfile-localnet index cfe5e19a48..0ec2408120 100644 --- a/Dockerfile-localnet +++ b/Dockerfile-localnet @@ -19,9 +19,13 @@ COPY go.sum . RUN go mod download COPY version.sh . COPY --exclude=*.sh --exclude=*.md --exclude=*.yml . . +ARG NODE_VERSION +ARG NODE_COMMIT -RUN --mount=type=cache,target="/root/.cache/go-build" make install -RUN --mount=type=cache,target="/root/.cache/go-build" make install-zetae2e +RUN --mount=type=cache,target="/root/.cache/go-build" \ + NODE_VERSION=${NODE_VERSION} \ + NODE_COMMIT=${NODE_COMMIT} \ + make install install-zetae2e FROM ghcr.io/zeta-chain/golang:1.22.5-bookworm AS cosmovisor-build RUN go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@v1.6.0 diff --git a/Makefile b/Makefile index 40053db864..36e414f012 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ .PHONY: build PACKAGE_NAME := github.com/zeta-chain/node -VERSION := $(shell ./version.sh) -COMMIT := $(shell [ -z "${COMMIT_ID}" ] && git log -1 --format='%H' || echo ${COMMIT_ID} ) +NODE_VERSION := $(shell ./version.sh) +NODE_COMMIT := $(shell [ -z "${NODE_COMMIT}" ] && git log -1 --format='%H' || echo ${NODE_COMMIT} ) BUILDTIME := $(shell date -u +"%Y%m%d.%H%M%S" ) DOCKER ?= docker # allow setting of NODE_COMPOSE_ARGS to pass additional args to docker compose @@ -17,11 +17,11 @@ GOPATH ?= '$(HOME)/go' ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=zetacore \ -X github.com/cosmos/cosmos-sdk/version.ServerName=zetacored \ -X github.com/cosmos/cosmos-sdk/version.ClientName=zetaclientd \ - -X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \ - -X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \ + -X github.com/cosmos/cosmos-sdk/version.Version=$(NODE_VERSION) \ + -X github.com/cosmos/cosmos-sdk/version.Commit=$(NODE_COMMIT) \ -X github.com/zeta-chain/node/pkg/constant.Name=zetacored \ - -X github.com/zeta-chain/node/pkg/constant.Version=$(VERSION) \ - -X github.com/zeta-chain/node/pkg/constant.CommitHash=$(COMMIT) \ + -X github.com/zeta-chain/node/pkg/constant.Version=$(NODE_VERSION) \ + -X github.com/zeta-chain/node/pkg/constant.CommitHash=$(NODE_COMMIT) \ -X github.com/zeta-chain/node/pkg/constant.BuildTime=$(BUILDTIME) \ -X github.com/cosmos/cosmos-sdk/types.DBBackend=pebbledb @@ -233,7 +233,7 @@ stop-localnet: zetanode: @echo "Building zetanode" - $(DOCKER) build -t zetanode --target latest-runtime -f ./Dockerfile-localnet . + $(DOCKER) build -t zetanode --build-arg NODE_VERSION=$(NODE_VERSION) --build-arg NODE_COMMIT=$(NODE_COMMIT) --target latest-runtime -f ./Dockerfile-localnet . $(DOCKER) build -t orchestrator -f contrib/localnet/orchestrator/Dockerfile.fastbuild . .PHONY: zetanode diff --git a/version.sh b/version.sh index ac8987e430..aedbfa5eeb 100755 --- a/version.sh +++ b/version.sh @@ -1,5 +1,12 @@ #!/bin/bash +# if NODE_VERSION is set, just return it immediately +# this allows you to do docker builds without the git directory +if [[ -n $NODE_VERSION ]]; then + echo $NODE_VERSION + exit +fi + # --exact-match will ensure the tag is only returned if our commit is a tag version=$(git describe --exact-match --tags 2>/dev/null) if [[ $? -eq 0 ]]; then @@ -9,14 +16,14 @@ if [[ $? -eq 0 ]]; then exit fi -# use current timestamp for dirty builds +# develop build and use commit timestamp for version +commit_timestamp=$(git show --no-patch --format=%at) +short_commit=$(git rev-parse --short HEAD) + +# append -dirty for dirty builds if ! git diff --no-ext-diff --quiet --exit-code ; then - current_timestamp=$(date +"%s") - echo "0.0.${current_timestamp}-dirty" + echo "0.0.${commit_timestamp}-${short_commit}-dirty" exit fi -# otherwise assume we are on a develop build and use commit timestamp for version -commit_timestamp=$(git show --no-patch --format=%at) - -echo "0.0.${commit_timestamp}-develop" \ No newline at end of file +echo "0.0.${commit_timestamp}-${short_commit}" \ No newline at end of file From c7bb9c7a6c6b71bf1021ab90f5ae334cff1d83a2 Mon Sep 17 00:00:00 2001 From: Peter Lee Date: Tue, 1 Oct 2024 17:53:36 -0700 Subject: [PATCH 14/14] update hashes --- .github/actions/performance-tests/art.yaml | 24 ++++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/.github/actions/performance-tests/art.yaml b/.github/actions/performance-tests/art.yaml index a1ccf1418d..0424eb96a1 100644 --- a/.github/actions/performance-tests/art.yaml +++ b/.github/actions/performance-tests/art.yaml @@ -174,6 +174,7 @@ scenarios: jsonrpc: "2.0" method: "eth_getTransactionByBlockHashAndIndex" params: + - "0xbd8bd16e5d4375ed4bab633c4fb8aca58fdf7ed6c340853b20cfa91ed9a3b9e1" - "0x0" capture: - json: "$" @@ -215,6 +216,7 @@ scenarios: jsonrpc: "2.0" method: "eth_getUncleByBlockHashAndIndex" params: + - "0xbd8bd16e5d4375ed4bab633c4fb8aca58fdf7ed6c340853b20cfa91ed9a3b9e1" - "0x0" capture: - json: "$" @@ -258,7 +260,7 @@ scenarios: params: - fromBlock: "latest" toBlock: "latest" - address: "0x0" + address: "0x81eF14691E9ea2f711cf56a9f0889c49C5Fe995a" topics: [] capture: - json: "$" @@ -279,7 +281,7 @@ scenarios: jsonrpc: "2.0" method: "eth_getFilterChanges" params: - - "0x0" + - "0xbd8bd16e5d4375ed4bab633c4fb8aca58fdf7ed6c340853b20cfa91ed9a3b9e1" capture: - json: "$" as: response @@ -299,7 +301,7 @@ scenarios: jsonrpc: "2.0" method: "eth_getFilterLogs" params: - - "0x0" + - "0xbd8bd16e5d4375ed4bab633c4fb8aca58fdf7ed6c340853b20cfa91ed9a3b9e1" capture: - json: "$" as: response @@ -338,7 +340,7 @@ scenarios: jsonrpc: "2.0" method: "eth_getBlockByHash" params: - - "0x0" + - "0x8716674e0acdbe87bab4595ecd33436f8a1a1b32fcda721362fe98dfc764affe" - true capture: - json: "$" @@ -380,7 +382,7 @@ scenarios: jsonrpc: "2.0" method: "eth_getBlockTransactionCountByHash" params: - - "0x0" + - "0x8716674e0acdbe87bab4595ecd33436f8a1a1b32fcda721362fe98dfc764affe" capture: - json: "$" as: response @@ -420,7 +422,7 @@ scenarios: jsonrpc: "2.0" method: "eth_getCode" params: - - "0x05BA149A7bd6dC1F937fA9046A9e05C05f3b18b0" + - "0x0cbe0dF132a6c6B4a2974Fa1b7Fb953CF0Cc798a" - "latest" capture: - json: "$" @@ -441,7 +443,7 @@ scenarios: jsonrpc: "2.0" method: "eth_getTransactionByHash" params: - - "0x0" + - "0x1a363840b12fa22aae5920edf11e2c59dde5260ffe5c9bc108250fe8380f5e75" capture: - json: "$" as: response @@ -461,7 +463,7 @@ scenarios: jsonrpc: "2.0" method: "eth_getTransactionReceipt" params: - - "0x0" + - "0x1a363840b12fa22aae5920edf11e2c59dde5260ffe5c9bc108250fe8380f5e75" capture: - json: "$" as: response @@ -481,7 +483,7 @@ scenarios: jsonrpc: "2.0" method: "eth_getLogs" params: - - address: "0x05BA149A7bd6dC1F937fA9046A9e05C05f3b18b0" + - address: "0x0cbe0dF132a6c6B4a2974Fa1b7Fb953CF0Cc798a" capture: - json: "$" as: response @@ -501,7 +503,7 @@ scenarios: jsonrpc: "2.0" method: "eth_getBalance" params: - - "0x05BA149A7bd6dC1F937fA9046A9e05C05f3b18b0" + - "0x735b14BB79463307AAcBED86DAf3322B1e6226aB" - "latest" capture: - json: "$" @@ -523,7 +525,7 @@ scenarios: method: "eth_estimateGas" params: - from: "0x239e96c8f17C85c30100AC26F635Ea15f23E9c67" - to: "0x05BA149A7bd6dC1F937fA9046A9e05C05f3b18b0" + to: "0x0cbe0dF132a6c6B4a2974Fa1b7Fb953CF0Cc798a" capture: - json: "$" as: response