diff --git a/changelog.md b/changelog.md index 26fcf31204..c2cd8f9b93 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,7 @@ ### Features +* [3414](https://github.com/zeta-chain/node/pull/3414) - support advanced abort workflow (onAbort) * [3461](https://github.com/zeta-chain/node/pull/3461) - add new `ConfirmationParams` field to chain params to enable multiple confirmation count values, deprecating `confirmation_count` * [3489](https://github.com/zeta-chain/node/pull/3489) - add Sui chain info * [3455](https://github.com/zeta-chain/node/pull/3455) - add `track-cctx` command to zetatools diff --git a/cmd/zetae2e/local/evm.go b/cmd/zetae2e/local/evm.go index bcb88041e8..d5afd6837e 100644 --- a/cmd/zetae2e/local/evm.go +++ b/cmd/zetae2e/local/evm.go @@ -57,8 +57,10 @@ func startEVMTests(eg *errgroup.Group, conf config.Config, deployerRunner *runne e2etests.TestETHDepositName, // necessary to pay fees on ZEVM and withdraw e2etests.TestETHDepositAndCallRevertName, e2etests.TestETHDepositAndCallRevertWithCallName, + e2etests.TestETHDepositRevertAndAbortName, e2etests.TestETHWithdrawAndCallRevertName, e2etests.TestETHWithdrawAndCallRevertWithCallName, + e2etests.TestETHWithdrawRevertAndAbortName, e2etests.TestETHWithdrawAndCallRevertWithWithdrawName, e2etests.TestDepositAndCallOutOfGasName, ), @@ -79,8 +81,10 @@ func startEVMTests(eg *errgroup.Group, conf config.Config, deployerRunner *runne e2etests.TestOperationAddLiquidityERC20Name, e2etests.TestERC20DepositAndCallRevertName, e2etests.TestERC20DepositAndCallRevertWithCallName, + e2etests.TestERC20DepositRevertAndAbortName, e2etests.TestERC20WithdrawAndCallRevertName, e2etests.TestERC20WithdrawAndCallRevertWithCallName, + e2etests.TestERC20WithdrawRevertAndAbortName, ), ) } diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 9ca5c1c3b4..3ecada09bb 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -60435,6 +60435,9 @@ definitions: title: |- error_message_revert carries information about the revert outbound tx , which is created if the first outbound tx fails + error_message_abort: + type: string + title: error_message_abort carries information when aborting the CCTX fails zetacoreemissionsParams: type: object properties: diff --git a/e2e/contracts/testabort/TestAbort.abi b/e2e/contracts/testabort/TestAbort.abi new file mode 100644 index 0000000000..29c335c323 --- /dev/null +++ b/e2e/contracts/testabort/TestAbort.abi @@ -0,0 +1,176 @@ +[ + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "aborted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "abortedWithMessage", + "outputs": [ + { + "internalType": "bytes", + "name": "sender", + "type": "bytes" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "outgoing", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "chainID", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "revertMessage", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "message", + "type": "string" + } + ], + "name": "getAbortedWithMessage", + "outputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "sender", + "type": "bytes" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "outgoing", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "chainID", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "revertMessage", + "type": "bytes" + } + ], + "internalType": "struct AbortContext", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isAborted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "sender", + "type": "bytes" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "outgoing", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "chainID", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "revertMessage", + "type": "bytes" + } + ], + "internalType": "struct AbortContext", + "name": "abortContext", + "type": "tuple" + } + ], + "name": "onAbort", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/e2e/contracts/testabort/TestAbort.bin b/e2e/contracts/testabort/TestAbort.bin new file mode 100644 index 0000000000..9a6d7c5bd2 --- /dev/null +++ b/e2e/contracts/testabort/TestAbort.bin @@ -0,0 +1 @@ +6080604052348015600f57600080fd5b506111c28061001f6000396000f3fe60806040526004361061004e5760003560e01c80632d4cfb7e1461005757806372748f7d1461008057806380b62b70146100c25780639e59f463146100ed578063fe4caa641461012a57610055565b3661005557005b005b34801561006357600080fd5b5061007e600480360381019061007991906106e2565b610155565b005b34801561008c57600080fd5b506100a760048036038101906100a29190610761565b6101bd565b6040516100b996959493929190610893565b60405180910390f35b3480156100ce57600080fd5b506100d7610336565b6040516100e49190610902565b60405180910390f35b3480156100f957600080fd5b50610114600480360381019061010f9190610a52565b610349565b6040516101219190610ba2565b60405180910390f35b34801561013657600080fd5b5061013f610544565b60405161014c9190610902565b60405180910390f35b6101ba818060a001906101689190610bd3565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050826101b590610e3d565b61055b565b50565b60006020528060005260406000206000915090508060000180546101e090610e7f565b80601f016020809104026020016040519081016040528092919081815260200182805461020c90610e7f565b80156102595780601f1061022e57610100808354040283529160200191610259565b820191906000526020600020905b81548152906001019060200180831161023c57829003601f168201915b5050505050908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030160009054906101000a900460ff16908060040154908060050180546102b390610e7f565b80601f01602080910402602001604051908101604052809291908181526020018280546102df90610e7f565b801561032c5780601f106103015761010080835404028352916020019161032c565b820191906000526020600020905b81548152906001019060200180831161030f57829003601f168201915b5050505050905086565b600160009054906101000a900460ff1681565b61035161065c565b600080836040516020016103659190610ef7565b6040516020818303038152906040528051906020012081526020019081526020016000206040518060c00160405290816000820180546103a490610e7f565b80601f01602080910402602001604051908101604052809291908181526020018280546103d090610e7f565b801561041d5780601f106103f25761010080835404028352916020019161041d565b820191906000526020600020905b81548152906001019060200180831161040057829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481526020016003820160009054906101000a900460ff16151515158152602001600482015481526020016005820180546104bb90610e7f565b80601f01602080910402602001604051908101604052809291908181526020018280546104e790610e7f565b80156105345780601f1061050957610100808354040283529160200191610534565b820191906000526020600020905b81548152906001019060200180831161051757829003601f168201915b5050505050815250509050919050565b6000600160009054906101000a900460ff16905090565b80600080846040516020016105709190610ef7565b60405160208183030381529060405280519060200120815260200190815260200160002060008201518160000190816105a991906110ba565b5060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040820151816002015560608201518160030160006101000a81548160ff0219169083151502179055506080820151816004015560a082015181600501908161063a91906110ba565b5090505060018060006101000a81548160ff0219169083151502179055505050565b6040518060c0016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160001515815260200160008152602001606081525090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600060c082840312156106d9576106d86106be565b5b81905092915050565b6000602082840312156106f8576106f76106b4565b5b600082013567ffffffffffffffff811115610716576107156106b9565b5b610722848285016106c3565b91505092915050565b6000819050919050565b61073e8161072b565b811461074957600080fd5b50565b60008135905061075b81610735565b92915050565b600060208284031215610777576107766106b4565b5b60006107858482850161074c565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156107c85780820151818401526020810190506107ad565b60008484015250505050565b6000601f19601f8301169050919050565b60006107f08261078e565b6107fa8185610799565b935061080a8185602086016107aa565b610813816107d4565b840191505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006108498261081e565b9050919050565b6108598161083e565b82525050565b6000819050919050565b6108728161085f565b82525050565b60008115159050919050565b61088d81610878565b82525050565b600060c08201905081810360008301526108ad81896107e5565b90506108bc6020830188610850565b6108c96040830187610869565b6108d66060830186610884565b6108e36080830185610869565b81810360a08301526108f581846107e5565b9050979650505050505050565b60006020820190506109176000830184610884565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61095f826107d4565b810181811067ffffffffffffffff8211171561097e5761097d610927565b5b80604052505050565b60006109916106aa565b905061099d8282610956565b919050565b600067ffffffffffffffff8211156109bd576109bc610927565b5b6109c6826107d4565b9050602081019050919050565b82818337600083830152505050565b60006109f56109f0846109a2565b610987565b905082815260208101848484011115610a1157610a10610922565b5b610a1c8482856109d3565b509392505050565b600082601f830112610a3957610a3861091d565b5b8135610a498482602086016109e2565b91505092915050565b600060208284031215610a6857610a676106b4565b5b600082013567ffffffffffffffff811115610a8657610a856106b9565b5b610a9284828501610a24565b91505092915050565b600082825260208201905092915050565b6000610ab78261078e565b610ac18185610a9b565b9350610ad18185602086016107aa565b610ada816107d4565b840191505092915050565b610aee8161083e565b82525050565b610afd8161085f565b82525050565b610b0c81610878565b82525050565b600060c0830160008301518482036000860152610b2f8282610aac565b9150506020830151610b446020860182610ae5565b506040830151610b576040860182610af4565b506060830151610b6a6060860182610b03565b506080830151610b7d6080860182610af4565b5060a083015184820360a0860152610b958282610aac565b9150508091505092915050565b60006020820190508181036000830152610bbc8184610b12565b905092915050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112610bf057610bef610bc4565b5b80840192508235915067ffffffffffffffff821115610c1257610c11610bc9565b5b602083019250600182023603831315610c2e57610c2d610bce565b5b509250929050565b600080fd5b600080fd5b600067ffffffffffffffff821115610c5b57610c5a610927565b5b610c64826107d4565b9050602081019050919050565b6000610c84610c7f84610c40565b610987565b905082815260208101848484011115610ca057610c9f610922565b5b610cab8482856109d3565b509392505050565b600082601f830112610cc857610cc761091d565b5b8135610cd8848260208601610c71565b91505092915050565b610cea8161083e565b8114610cf557600080fd5b50565b600081359050610d0781610ce1565b92915050565b610d168161085f565b8114610d2157600080fd5b50565b600081359050610d3381610d0d565b92915050565b610d4281610878565b8114610d4d57600080fd5b50565b600081359050610d5f81610d39565b92915050565b600060c08284031215610d7b57610d7a610c36565b5b610d8560c0610987565b9050600082013567ffffffffffffffff811115610da557610da4610c3b565b5b610db184828501610cb3565b6000830152506020610dc584828501610cf8565b6020830152506040610dd984828501610d24565b6040830152506060610ded84828501610d50565b6060830152506080610e0184828501610d24565b60808301525060a082013567ffffffffffffffff811115610e2557610e24610c3b565b5b610e3184828501610cb3565b60a08301525092915050565b6000610e493683610d65565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610e9757607f821691505b602082108103610eaa57610ea9610e50565b5b50919050565b600081519050919050565b600081905092915050565b6000610ed182610eb0565b610edb8185610ebb565b9350610eeb8185602086016107aa565b80840191505092915050565b6000610f038284610ec6565b915081905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302610f707fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610f33565b610f7a8683610f33565b95508019841693508086168417925050509392505050565b6000819050919050565b6000610fb7610fb2610fad8461085f565b610f92565b61085f565b9050919050565b6000819050919050565b610fd183610f9c565b610fe5610fdd82610fbe565b848454610f40565b825550505050565b600090565b610ffa610fed565b611005818484610fc8565b505050565b5b818110156110295761101e600082610ff2565b60018101905061100b565b5050565b601f82111561106e5761103f81610f0e565b61104884610f23565b81016020851015611057578190505b61106b61106385610f23565b83018261100a565b50505b505050565b600082821c905092915050565b600061109160001984600802611073565b1980831691505092915050565b60006110aa8383611080565b9150826002028217905092915050565b6110c38261078e565b67ffffffffffffffff8111156110dc576110db610927565b5b6110e68254610e7f565b6110f182828561102d565b600060209050601f8311600181146111245760008415611112578287015190505b61111c858261109e565b865550611184565b601f19841661113286610f0e565b60005b8281101561115a57848901518255600182019150602085019450602081019050611135565b868310156111775784890151611173601f891682611080565b8355505b6001600288020188555050505b50505050505056fea264697066735822122073b672b76653cfb3aa192e6bbbea81b40276e37f9ae4e034167d2012fb55ebaa64736f6c634300081a0033 diff --git a/e2e/contracts/testabort/TestAbort.go b/e2e/contracts/testabort/TestAbort.go new file mode 100644 index 0000000000..e9522b5085 --- /dev/null +++ b/e2e/contracts/testabort/TestAbort.go @@ -0,0 +1,434 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package testabort + +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 +) + +// AbortContext is an auto generated low-level Go binding around an user-defined struct. +type AbortContext struct { + Sender []byte + Asset common.Address + Amount *big.Int + Outgoing bool + ChainID *big.Int + RevertMessage []byte +} + +// TestAbortMetaData contains all meta data concerning the TestAbort contract. +var TestAbortMetaData = &bind.MetaData{ + ABI: "[{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"aborted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"abortedWithMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"outgoing\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"chainID\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"revertMessage\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"getAbortedWithMessage\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"outgoing\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"chainID\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"revertMessage\",\"type\":\"bytes\"}],\"internalType\":\"structAbortContext\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isAborted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"outgoing\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"chainID\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"revertMessage\",\"type\":\"bytes\"}],\"internalType\":\"structAbortContext\",\"name\":\"abortContext\",\"type\":\"tuple\"}],\"name\":\"onAbort\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x6080604052348015600f57600080fd5b506111c28061001f6000396000f3fe60806040526004361061004e5760003560e01c80632d4cfb7e1461005757806372748f7d1461008057806380b62b70146100c25780639e59f463146100ed578063fe4caa641461012a57610055565b3661005557005b005b34801561006357600080fd5b5061007e600480360381019061007991906106e2565b610155565b005b34801561008c57600080fd5b506100a760048036038101906100a29190610761565b6101bd565b6040516100b996959493929190610893565b60405180910390f35b3480156100ce57600080fd5b506100d7610336565b6040516100e49190610902565b60405180910390f35b3480156100f957600080fd5b50610114600480360381019061010f9190610a52565b610349565b6040516101219190610ba2565b60405180910390f35b34801561013657600080fd5b5061013f610544565b60405161014c9190610902565b60405180910390f35b6101ba818060a001906101689190610bd3565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050826101b590610e3d565b61055b565b50565b60006020528060005260406000206000915090508060000180546101e090610e7f565b80601f016020809104026020016040519081016040528092919081815260200182805461020c90610e7f565b80156102595780601f1061022e57610100808354040283529160200191610259565b820191906000526020600020905b81548152906001019060200180831161023c57829003601f168201915b5050505050908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030160009054906101000a900460ff16908060040154908060050180546102b390610e7f565b80601f01602080910402602001604051908101604052809291908181526020018280546102df90610e7f565b801561032c5780601f106103015761010080835404028352916020019161032c565b820191906000526020600020905b81548152906001019060200180831161030f57829003601f168201915b5050505050905086565b600160009054906101000a900460ff1681565b61035161065c565b600080836040516020016103659190610ef7565b6040516020818303038152906040528051906020012081526020019081526020016000206040518060c00160405290816000820180546103a490610e7f565b80601f01602080910402602001604051908101604052809291908181526020018280546103d090610e7f565b801561041d5780601f106103f25761010080835404028352916020019161041d565b820191906000526020600020905b81548152906001019060200180831161040057829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481526020016003820160009054906101000a900460ff16151515158152602001600482015481526020016005820180546104bb90610e7f565b80601f01602080910402602001604051908101604052809291908181526020018280546104e790610e7f565b80156105345780601f1061050957610100808354040283529160200191610534565b820191906000526020600020905b81548152906001019060200180831161051757829003601f168201915b5050505050815250509050919050565b6000600160009054906101000a900460ff16905090565b80600080846040516020016105709190610ef7565b60405160208183030381529060405280519060200120815260200190815260200160002060008201518160000190816105a991906110ba565b5060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040820151816002015560608201518160030160006101000a81548160ff0219169083151502179055506080820151816004015560a082015181600501908161063a91906110ba565b5090505060018060006101000a81548160ff0219169083151502179055505050565b6040518060c0016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160001515815260200160008152602001606081525090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600060c082840312156106d9576106d86106be565b5b81905092915050565b6000602082840312156106f8576106f76106b4565b5b600082013567ffffffffffffffff811115610716576107156106b9565b5b610722848285016106c3565b91505092915050565b6000819050919050565b61073e8161072b565b811461074957600080fd5b50565b60008135905061075b81610735565b92915050565b600060208284031215610777576107766106b4565b5b60006107858482850161074c565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156107c85780820151818401526020810190506107ad565b60008484015250505050565b6000601f19601f8301169050919050565b60006107f08261078e565b6107fa8185610799565b935061080a8185602086016107aa565b610813816107d4565b840191505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006108498261081e565b9050919050565b6108598161083e565b82525050565b6000819050919050565b6108728161085f565b82525050565b60008115159050919050565b61088d81610878565b82525050565b600060c08201905081810360008301526108ad81896107e5565b90506108bc6020830188610850565b6108c96040830187610869565b6108d66060830186610884565b6108e36080830185610869565b81810360a08301526108f581846107e5565b9050979650505050505050565b60006020820190506109176000830184610884565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61095f826107d4565b810181811067ffffffffffffffff8211171561097e5761097d610927565b5b80604052505050565b60006109916106aa565b905061099d8282610956565b919050565b600067ffffffffffffffff8211156109bd576109bc610927565b5b6109c6826107d4565b9050602081019050919050565b82818337600083830152505050565b60006109f56109f0846109a2565b610987565b905082815260208101848484011115610a1157610a10610922565b5b610a1c8482856109d3565b509392505050565b600082601f830112610a3957610a3861091d565b5b8135610a498482602086016109e2565b91505092915050565b600060208284031215610a6857610a676106b4565b5b600082013567ffffffffffffffff811115610a8657610a856106b9565b5b610a9284828501610a24565b91505092915050565b600082825260208201905092915050565b6000610ab78261078e565b610ac18185610a9b565b9350610ad18185602086016107aa565b610ada816107d4565b840191505092915050565b610aee8161083e565b82525050565b610afd8161085f565b82525050565b610b0c81610878565b82525050565b600060c0830160008301518482036000860152610b2f8282610aac565b9150506020830151610b446020860182610ae5565b506040830151610b576040860182610af4565b506060830151610b6a6060860182610b03565b506080830151610b7d6080860182610af4565b5060a083015184820360a0860152610b958282610aac565b9150508091505092915050565b60006020820190508181036000830152610bbc8184610b12565b905092915050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112610bf057610bef610bc4565b5b80840192508235915067ffffffffffffffff821115610c1257610c11610bc9565b5b602083019250600182023603831315610c2e57610c2d610bce565b5b509250929050565b600080fd5b600080fd5b600067ffffffffffffffff821115610c5b57610c5a610927565b5b610c64826107d4565b9050602081019050919050565b6000610c84610c7f84610c40565b610987565b905082815260208101848484011115610ca057610c9f610922565b5b610cab8482856109d3565b509392505050565b600082601f830112610cc857610cc761091d565b5b8135610cd8848260208601610c71565b91505092915050565b610cea8161083e565b8114610cf557600080fd5b50565b600081359050610d0781610ce1565b92915050565b610d168161085f565b8114610d2157600080fd5b50565b600081359050610d3381610d0d565b92915050565b610d4281610878565b8114610d4d57600080fd5b50565b600081359050610d5f81610d39565b92915050565b600060c08284031215610d7b57610d7a610c36565b5b610d8560c0610987565b9050600082013567ffffffffffffffff811115610da557610da4610c3b565b5b610db184828501610cb3565b6000830152506020610dc584828501610cf8565b6020830152506040610dd984828501610d24565b6040830152506060610ded84828501610d50565b6060830152506080610e0184828501610d24565b60808301525060a082013567ffffffffffffffff811115610e2557610e24610c3b565b5b610e3184828501610cb3565b60a08301525092915050565b6000610e493683610d65565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610e9757607f821691505b602082108103610eaa57610ea9610e50565b5b50919050565b600081519050919050565b600081905092915050565b6000610ed182610eb0565b610edb8185610ebb565b9350610eeb8185602086016107aa565b80840191505092915050565b6000610f038284610ec6565b915081905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302610f707fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610f33565b610f7a8683610f33565b95508019841693508086168417925050509392505050565b6000819050919050565b6000610fb7610fb2610fad8461085f565b610f92565b61085f565b9050919050565b6000819050919050565b610fd183610f9c565b610fe5610fdd82610fbe565b848454610f40565b825550505050565b600090565b610ffa610fed565b611005818484610fc8565b505050565b5b818110156110295761101e600082610ff2565b60018101905061100b565b5050565b601f82111561106e5761103f81610f0e565b61104884610f23565b81016020851015611057578190505b61106b61106385610f23565b83018261100a565b50505b505050565b600082821c905092915050565b600061109160001984600802611073565b1980831691505092915050565b60006110aa8383611080565b9150826002028217905092915050565b6110c38261078e565b67ffffffffffffffff8111156110dc576110db610927565b5b6110e68254610e7f565b6110f182828561102d565b600060209050601f8311600181146111245760008415611112578287015190505b61111c858261109e565b865550611184565b601f19841661113286610f0e565b60005b8281101561115a57848901518255600182019150602085019450602081019050611135565b868310156111775784890151611173601f891682611080565b8355505b6001600288020188555050505b50505050505056fea264697066735822122073b672b76653cfb3aa192e6bbbea81b40276e37f9ae4e034167d2012fb55ebaa64736f6c634300081a0033", +} + +// TestAbortABI is the input ABI used to generate the binding from. +// Deprecated: Use TestAbortMetaData.ABI instead. +var TestAbortABI = TestAbortMetaData.ABI + +// TestAbortBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TestAbortMetaData.Bin instead. +var TestAbortBin = TestAbortMetaData.Bin + +// DeployTestAbort deploys a new Ethereum contract, binding an instance of TestAbort to it. +func DeployTestAbort(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TestAbort, error) { + parsed, err := TestAbortMetaData.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(TestAbortBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &TestAbort{TestAbortCaller: TestAbortCaller{contract: contract}, TestAbortTransactor: TestAbortTransactor{contract: contract}, TestAbortFilterer: TestAbortFilterer{contract: contract}}, nil +} + +// TestAbort is an auto generated Go binding around an Ethereum contract. +type TestAbort struct { + TestAbortCaller // Read-only binding to the contract + TestAbortTransactor // Write-only binding to the contract + TestAbortFilterer // Log filterer for contract events +} + +// TestAbortCaller is an auto generated read-only Go binding around an Ethereum contract. +type TestAbortCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TestAbortTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TestAbortTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TestAbortFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TestAbortFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TestAbortSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TestAbortSession struct { + Contract *TestAbort // 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 +} + +// TestAbortCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TestAbortCallerSession struct { + Contract *TestAbortCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TestAbortTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TestAbortTransactorSession struct { + Contract *TestAbortTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TestAbortRaw is an auto generated low-level Go binding around an Ethereum contract. +type TestAbortRaw struct { + Contract *TestAbort // Generic contract binding to access the raw methods on +} + +// TestAbortCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TestAbortCallerRaw struct { + Contract *TestAbortCaller // Generic read-only contract binding to access the raw methods on +} + +// TestAbortTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TestAbortTransactorRaw struct { + Contract *TestAbortTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTestAbort creates a new instance of TestAbort, bound to a specific deployed contract. +func NewTestAbort(address common.Address, backend bind.ContractBackend) (*TestAbort, error) { + contract, err := bindTestAbort(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TestAbort{TestAbortCaller: TestAbortCaller{contract: contract}, TestAbortTransactor: TestAbortTransactor{contract: contract}, TestAbortFilterer: TestAbortFilterer{contract: contract}}, nil +} + +// NewTestAbortCaller creates a new read-only instance of TestAbort, bound to a specific deployed contract. +func NewTestAbortCaller(address common.Address, caller bind.ContractCaller) (*TestAbortCaller, error) { + contract, err := bindTestAbort(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TestAbortCaller{contract: contract}, nil +} + +// NewTestAbortTransactor creates a new write-only instance of TestAbort, bound to a specific deployed contract. +func NewTestAbortTransactor(address common.Address, transactor bind.ContractTransactor) (*TestAbortTransactor, error) { + contract, err := bindTestAbort(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TestAbortTransactor{contract: contract}, nil +} + +// NewTestAbortFilterer creates a new log filterer instance of TestAbort, bound to a specific deployed contract. +func NewTestAbortFilterer(address common.Address, filterer bind.ContractFilterer) (*TestAbortFilterer, error) { + contract, err := bindTestAbort(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TestAbortFilterer{contract: contract}, nil +} + +// bindTestAbort binds a generic wrapper to an already deployed contract. +func bindTestAbort(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TestAbortMetaData.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 (_TestAbort *TestAbortRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TestAbort.Contract.TestAbortCaller.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 (_TestAbort *TestAbortRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TestAbort.Contract.TestAbortTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TestAbort *TestAbortRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TestAbort.Contract.TestAbortTransactor.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 (_TestAbort *TestAbortCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TestAbort.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 (_TestAbort *TestAbortTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TestAbort.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TestAbort *TestAbortTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TestAbort.Contract.contract.Transact(opts, method, params...) +} + +// Aborted is a free data retrieval call binding the contract method 0x80b62b70. +// +// Solidity: function aborted() view returns(bool) +func (_TestAbort *TestAbortCaller) Aborted(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _TestAbort.contract.Call(opts, &out, "aborted") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Aborted is a free data retrieval call binding the contract method 0x80b62b70. +// +// Solidity: function aborted() view returns(bool) +func (_TestAbort *TestAbortSession) Aborted() (bool, error) { + return _TestAbort.Contract.Aborted(&_TestAbort.CallOpts) +} + +// Aborted is a free data retrieval call binding the contract method 0x80b62b70. +// +// Solidity: function aborted() view returns(bool) +func (_TestAbort *TestAbortCallerSession) Aborted() (bool, error) { + return _TestAbort.Contract.Aborted(&_TestAbort.CallOpts) +} + +// AbortedWithMessage is a free data retrieval call binding the contract method 0x72748f7d. +// +// Solidity: function abortedWithMessage(bytes32 ) view returns(bytes sender, address asset, uint256 amount, bool outgoing, uint256 chainID, bytes revertMessage) +func (_TestAbort *TestAbortCaller) AbortedWithMessage(opts *bind.CallOpts, arg0 [32]byte) (struct { + Sender []byte + Asset common.Address + Amount *big.Int + Outgoing bool + ChainID *big.Int + RevertMessage []byte +}, error) { + var out []interface{} + err := _TestAbort.contract.Call(opts, &out, "abortedWithMessage", arg0) + + outstruct := new(struct { + Sender []byte + Asset common.Address + Amount *big.Int + Outgoing bool + ChainID *big.Int + RevertMessage []byte + }) + if err != nil { + return *outstruct, err + } + + outstruct.Sender = *abi.ConvertType(out[0], new([]byte)).(*[]byte) + outstruct.Asset = *abi.ConvertType(out[1], new(common.Address)).(*common.Address) + outstruct.Amount = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.Outgoing = *abi.ConvertType(out[3], new(bool)).(*bool) + outstruct.ChainID = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + outstruct.RevertMessage = *abi.ConvertType(out[5], new([]byte)).(*[]byte) + + return *outstruct, err + +} + +// AbortedWithMessage is a free data retrieval call binding the contract method 0x72748f7d. +// +// Solidity: function abortedWithMessage(bytes32 ) view returns(bytes sender, address asset, uint256 amount, bool outgoing, uint256 chainID, bytes revertMessage) +func (_TestAbort *TestAbortSession) AbortedWithMessage(arg0 [32]byte) (struct { + Sender []byte + Asset common.Address + Amount *big.Int + Outgoing bool + ChainID *big.Int + RevertMessage []byte +}, error) { + return _TestAbort.Contract.AbortedWithMessage(&_TestAbort.CallOpts, arg0) +} + +// AbortedWithMessage is a free data retrieval call binding the contract method 0x72748f7d. +// +// Solidity: function abortedWithMessage(bytes32 ) view returns(bytes sender, address asset, uint256 amount, bool outgoing, uint256 chainID, bytes revertMessage) +func (_TestAbort *TestAbortCallerSession) AbortedWithMessage(arg0 [32]byte) (struct { + Sender []byte + Asset common.Address + Amount *big.Int + Outgoing bool + ChainID *big.Int + RevertMessage []byte +}, error) { + return _TestAbort.Contract.AbortedWithMessage(&_TestAbort.CallOpts, arg0) +} + +// GetAbortedWithMessage is a free data retrieval call binding the contract method 0x9e59f463. +// +// Solidity: function getAbortedWithMessage(string message) view returns((bytes,address,uint256,bool,uint256,bytes)) +func (_TestAbort *TestAbortCaller) GetAbortedWithMessage(opts *bind.CallOpts, message string) (AbortContext, error) { + var out []interface{} + err := _TestAbort.contract.Call(opts, &out, "getAbortedWithMessage", message) + + if err != nil { + return *new(AbortContext), err + } + + out0 := *abi.ConvertType(out[0], new(AbortContext)).(*AbortContext) + + return out0, err + +} + +// GetAbortedWithMessage is a free data retrieval call binding the contract method 0x9e59f463. +// +// Solidity: function getAbortedWithMessage(string message) view returns((bytes,address,uint256,bool,uint256,bytes)) +func (_TestAbort *TestAbortSession) GetAbortedWithMessage(message string) (AbortContext, error) { + return _TestAbort.Contract.GetAbortedWithMessage(&_TestAbort.CallOpts, message) +} + +// GetAbortedWithMessage is a free data retrieval call binding the contract method 0x9e59f463. +// +// Solidity: function getAbortedWithMessage(string message) view returns((bytes,address,uint256,bool,uint256,bytes)) +func (_TestAbort *TestAbortCallerSession) GetAbortedWithMessage(message string) (AbortContext, error) { + return _TestAbort.Contract.GetAbortedWithMessage(&_TestAbort.CallOpts, message) +} + +// IsAborted is a free data retrieval call binding the contract method 0xfe4caa64. +// +// Solidity: function isAborted() view returns(bool) +func (_TestAbort *TestAbortCaller) IsAborted(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _TestAbort.contract.Call(opts, &out, "isAborted") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsAborted is a free data retrieval call binding the contract method 0xfe4caa64. +// +// Solidity: function isAborted() view returns(bool) +func (_TestAbort *TestAbortSession) IsAborted() (bool, error) { + return _TestAbort.Contract.IsAborted(&_TestAbort.CallOpts) +} + +// IsAborted is a free data retrieval call binding the contract method 0xfe4caa64. +// +// Solidity: function isAborted() view returns(bool) +func (_TestAbort *TestAbortCallerSession) IsAborted() (bool, error) { + return _TestAbort.Contract.IsAborted(&_TestAbort.CallOpts) +} + +// OnAbort is a paid mutator transaction binding the contract method 0x2d4cfb7e. +// +// Solidity: function onAbort((bytes,address,uint256,bool,uint256,bytes) abortContext) returns() +func (_TestAbort *TestAbortTransactor) OnAbort(opts *bind.TransactOpts, abortContext AbortContext) (*types.Transaction, error) { + return _TestAbort.contract.Transact(opts, "onAbort", abortContext) +} + +// OnAbort is a paid mutator transaction binding the contract method 0x2d4cfb7e. +// +// Solidity: function onAbort((bytes,address,uint256,bool,uint256,bytes) abortContext) returns() +func (_TestAbort *TestAbortSession) OnAbort(abortContext AbortContext) (*types.Transaction, error) { + return _TestAbort.Contract.OnAbort(&_TestAbort.TransactOpts, abortContext) +} + +// OnAbort is a paid mutator transaction binding the contract method 0x2d4cfb7e. +// +// Solidity: function onAbort((bytes,address,uint256,bool,uint256,bytes) abortContext) returns() +func (_TestAbort *TestAbortTransactorSession) OnAbort(abortContext AbortContext) (*types.Transaction, error) { + return _TestAbort.Contract.OnAbort(&_TestAbort.TransactOpts, abortContext) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_TestAbort *TestAbortTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _TestAbort.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_TestAbort *TestAbortSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _TestAbort.Contract.Fallback(&_TestAbort.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_TestAbort *TestAbortTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _TestAbort.Contract.Fallback(&_TestAbort.TransactOpts, calldata) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_TestAbort *TestAbortTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TestAbort.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 (_TestAbort *TestAbortSession) Receive() (*types.Transaction, error) { + return _TestAbort.Contract.Receive(&_TestAbort.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_TestAbort *TestAbortTransactorSession) Receive() (*types.Transaction, error) { + return _TestAbort.Contract.Receive(&_TestAbort.TransactOpts) +} diff --git a/e2e/contracts/testabort/TestAbort.json b/e2e/contracts/testabort/TestAbort.json new file mode 100644 index 0000000000..a6c841daee --- /dev/null +++ b/e2e/contracts/testabort/TestAbort.json @@ -0,0 +1,179 @@ +{ + "abi": [ + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "aborted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "abortedWithMessage", + "outputs": [ + { + "internalType": "bytes", + "name": "sender", + "type": "bytes" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "outgoing", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "chainID", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "revertMessage", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "message", + "type": "string" + } + ], + "name": "getAbortedWithMessage", + "outputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "sender", + "type": "bytes" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "outgoing", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "chainID", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "revertMessage", + "type": "bytes" + } + ], + "internalType": "struct AbortContext", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isAborted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "sender", + "type": "bytes" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "outgoing", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "chainID", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "revertMessage", + "type": "bytes" + } + ], + "internalType": "struct AbortContext", + "name": "abortContext", + "type": "tuple" + } + ], + "name": "onAbort", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bin": "6080604052348015600f57600080fd5b506111c28061001f6000396000f3fe60806040526004361061004e5760003560e01c80632d4cfb7e1461005757806372748f7d1461008057806380b62b70146100c25780639e59f463146100ed578063fe4caa641461012a57610055565b3661005557005b005b34801561006357600080fd5b5061007e600480360381019061007991906106e2565b610155565b005b34801561008c57600080fd5b506100a760048036038101906100a29190610761565b6101bd565b6040516100b996959493929190610893565b60405180910390f35b3480156100ce57600080fd5b506100d7610336565b6040516100e49190610902565b60405180910390f35b3480156100f957600080fd5b50610114600480360381019061010f9190610a52565b610349565b6040516101219190610ba2565b60405180910390f35b34801561013657600080fd5b5061013f610544565b60405161014c9190610902565b60405180910390f35b6101ba818060a001906101689190610bd3565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050826101b590610e3d565b61055b565b50565b60006020528060005260406000206000915090508060000180546101e090610e7f565b80601f016020809104026020016040519081016040528092919081815260200182805461020c90610e7f565b80156102595780601f1061022e57610100808354040283529160200191610259565b820191906000526020600020905b81548152906001019060200180831161023c57829003601f168201915b5050505050908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030160009054906101000a900460ff16908060040154908060050180546102b390610e7f565b80601f01602080910402602001604051908101604052809291908181526020018280546102df90610e7f565b801561032c5780601f106103015761010080835404028352916020019161032c565b820191906000526020600020905b81548152906001019060200180831161030f57829003601f168201915b5050505050905086565b600160009054906101000a900460ff1681565b61035161065c565b600080836040516020016103659190610ef7565b6040516020818303038152906040528051906020012081526020019081526020016000206040518060c00160405290816000820180546103a490610e7f565b80601f01602080910402602001604051908101604052809291908181526020018280546103d090610e7f565b801561041d5780601f106103f25761010080835404028352916020019161041d565b820191906000526020600020905b81548152906001019060200180831161040057829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481526020016003820160009054906101000a900460ff16151515158152602001600482015481526020016005820180546104bb90610e7f565b80601f01602080910402602001604051908101604052809291908181526020018280546104e790610e7f565b80156105345780601f1061050957610100808354040283529160200191610534565b820191906000526020600020905b81548152906001019060200180831161051757829003601f168201915b5050505050815250509050919050565b6000600160009054906101000a900460ff16905090565b80600080846040516020016105709190610ef7565b60405160208183030381529060405280519060200120815260200190815260200160002060008201518160000190816105a991906110ba565b5060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040820151816002015560608201518160030160006101000a81548160ff0219169083151502179055506080820151816004015560a082015181600501908161063a91906110ba565b5090505060018060006101000a81548160ff0219169083151502179055505050565b6040518060c0016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160001515815260200160008152602001606081525090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600060c082840312156106d9576106d86106be565b5b81905092915050565b6000602082840312156106f8576106f76106b4565b5b600082013567ffffffffffffffff811115610716576107156106b9565b5b610722848285016106c3565b91505092915050565b6000819050919050565b61073e8161072b565b811461074957600080fd5b50565b60008135905061075b81610735565b92915050565b600060208284031215610777576107766106b4565b5b60006107858482850161074c565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156107c85780820151818401526020810190506107ad565b60008484015250505050565b6000601f19601f8301169050919050565b60006107f08261078e565b6107fa8185610799565b935061080a8185602086016107aa565b610813816107d4565b840191505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006108498261081e565b9050919050565b6108598161083e565b82525050565b6000819050919050565b6108728161085f565b82525050565b60008115159050919050565b61088d81610878565b82525050565b600060c08201905081810360008301526108ad81896107e5565b90506108bc6020830188610850565b6108c96040830187610869565b6108d66060830186610884565b6108e36080830185610869565b81810360a08301526108f581846107e5565b9050979650505050505050565b60006020820190506109176000830184610884565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61095f826107d4565b810181811067ffffffffffffffff8211171561097e5761097d610927565b5b80604052505050565b60006109916106aa565b905061099d8282610956565b919050565b600067ffffffffffffffff8211156109bd576109bc610927565b5b6109c6826107d4565b9050602081019050919050565b82818337600083830152505050565b60006109f56109f0846109a2565b610987565b905082815260208101848484011115610a1157610a10610922565b5b610a1c8482856109d3565b509392505050565b600082601f830112610a3957610a3861091d565b5b8135610a498482602086016109e2565b91505092915050565b600060208284031215610a6857610a676106b4565b5b600082013567ffffffffffffffff811115610a8657610a856106b9565b5b610a9284828501610a24565b91505092915050565b600082825260208201905092915050565b6000610ab78261078e565b610ac18185610a9b565b9350610ad18185602086016107aa565b610ada816107d4565b840191505092915050565b610aee8161083e565b82525050565b610afd8161085f565b82525050565b610b0c81610878565b82525050565b600060c0830160008301518482036000860152610b2f8282610aac565b9150506020830151610b446020860182610ae5565b506040830151610b576040860182610af4565b506060830151610b6a6060860182610b03565b506080830151610b7d6080860182610af4565b5060a083015184820360a0860152610b958282610aac565b9150508091505092915050565b60006020820190508181036000830152610bbc8184610b12565b905092915050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112610bf057610bef610bc4565b5b80840192508235915067ffffffffffffffff821115610c1257610c11610bc9565b5b602083019250600182023603831315610c2e57610c2d610bce565b5b509250929050565b600080fd5b600080fd5b600067ffffffffffffffff821115610c5b57610c5a610927565b5b610c64826107d4565b9050602081019050919050565b6000610c84610c7f84610c40565b610987565b905082815260208101848484011115610ca057610c9f610922565b5b610cab8482856109d3565b509392505050565b600082601f830112610cc857610cc761091d565b5b8135610cd8848260208601610c71565b91505092915050565b610cea8161083e565b8114610cf557600080fd5b50565b600081359050610d0781610ce1565b92915050565b610d168161085f565b8114610d2157600080fd5b50565b600081359050610d3381610d0d565b92915050565b610d4281610878565b8114610d4d57600080fd5b50565b600081359050610d5f81610d39565b92915050565b600060c08284031215610d7b57610d7a610c36565b5b610d8560c0610987565b9050600082013567ffffffffffffffff811115610da557610da4610c3b565b5b610db184828501610cb3565b6000830152506020610dc584828501610cf8565b6020830152506040610dd984828501610d24565b6040830152506060610ded84828501610d50565b6060830152506080610e0184828501610d24565b60808301525060a082013567ffffffffffffffff811115610e2557610e24610c3b565b5b610e3184828501610cb3565b60a08301525092915050565b6000610e493683610d65565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610e9757607f821691505b602082108103610eaa57610ea9610e50565b5b50919050565b600081519050919050565b600081905092915050565b6000610ed182610eb0565b610edb8185610ebb565b9350610eeb8185602086016107aa565b80840191505092915050565b6000610f038284610ec6565b915081905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302610f707fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610f33565b610f7a8683610f33565b95508019841693508086168417925050509392505050565b6000819050919050565b6000610fb7610fb2610fad8461085f565b610f92565b61085f565b9050919050565b6000819050919050565b610fd183610f9c565b610fe5610fdd82610fbe565b848454610f40565b825550505050565b600090565b610ffa610fed565b611005818484610fc8565b505050565b5b818110156110295761101e600082610ff2565b60018101905061100b565b5050565b601f82111561106e5761103f81610f0e565b61104884610f23565b81016020851015611057578190505b61106b61106385610f23565b83018261100a565b50505b505050565b600082821c905092915050565b600061109160001984600802611073565b1980831691505092915050565b60006110aa8383611080565b9150826002028217905092915050565b6110c38261078e565b67ffffffffffffffff8111156110dc576110db610927565b5b6110e68254610e7f565b6110f182828561102d565b600060209050601f8311600181146111245760008415611112578287015190505b61111c858261109e565b865550611184565b601f19841661113286610f0e565b60005b8281101561115a57848901518255600182019150602085019450602081019050611135565b868310156111775784890151611173601f891682611080565b8355505b6001600288020188555050505b50505050505056fea264697066735822122073b672b76653cfb3aa192e6bbbea81b40276e37f9ae4e034167d2012fb55ebaa64736f6c634300081a0033" +} diff --git a/e2e/contracts/testabort/TestAbort.sol b/e2e/contracts/testabort/TestAbort.sol new file mode 100644 index 0000000000..4b638b898c --- /dev/null +++ b/e2e/contracts/testabort/TestAbort.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; + +struct AbortContext { + bytes sender; + address asset; + uint256 amount; + bool outgoing; + uint256 chainID; + bytes revertMessage; +} + +contract TestAbort { + // allow to assess onAbort calls + mapping(bytes32 => AbortContext) public abortedWithMessage; + bool public aborted; + + function setAbortedWithMessage(string memory message, AbortContext memory abortContext) internal { + abortedWithMessage[keccak256(abi.encodePacked(message))] = abortContext; + aborted = true; + } + + function getAbortedWithMessage(string memory message) public view returns (AbortContext memory) { + return abortedWithMessage[keccak256(abi.encodePacked(message))]; + } + + function isAborted() public view returns (bool) { + return aborted; + } + + function onAbort(AbortContext calldata abortContext) external { + setAbortedWithMessage(string(abortContext.revertMessage), abortContext); + } + + fallback() external payable {} + + receive() external payable {} +} diff --git a/e2e/contracts/testabort/bindings.go b/e2e/contracts/testabort/bindings.go new file mode 100644 index 0000000000..a014f83f66 --- /dev/null +++ b/e2e/contracts/testabort/bindings.go @@ -0,0 +1,6 @@ +//go:generate sh -c "solc --evm-version paris TestAbort.sol --combined-json abi,bin --allow-paths .. | jq '.contracts.\"TestAbort.sol:TestAbort\"' > TestAbort.json" +//go:generate sh -c "cat TestAbort.json | jq .abi > TestAbort.abi" +//go:generate sh -c "cat TestAbort.json | jq .bin | tr -d '\"' > TestAbort.bin" +//go:generate sh -c "abigen --abi TestAbort.abi --bin TestAbort.bin --pkg testabort --type TestAbort --out TestAbort.go" + +package testabort diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index 9103646b38..a8db769485 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -11,11 +11,13 @@ const ( /* EVM chain tests */ - TestETHDepositName = "eth_deposit" - TestETHDepositAndCallName = "eth_deposit_and_call" - TestETHDepositAndCallNoMessageName = "eth_deposit_and_call_no_message" - TestETHDepositAndCallRevertName = "eth_deposit_and_call_revert" - TestETHDepositAndCallRevertWithCallName = "eth_deposit_and_call_revert_with_call" + TestETHDepositName = "eth_deposit" + TestETHDepositAndCallName = "eth_deposit_and_call" + TestETHDepositAndCallNoMessageName = "eth_deposit_and_call_no_message" + TestETHDepositAndCallRevertName = "eth_deposit_and_call_revert" + TestETHDepositAndCallRevertWithCallName = "eth_deposit_and_call_revert_with_call" + TestETHDepositRevertAndAbortName = "eth_deposit_revert_and_abort" + TestETHWithdrawName = "eth_withdraw" TestETHWithdrawAndArbitraryCallName = "eth_withdraw_and_arbitrary_call" TestETHWithdrawAndCallName = "eth_withdraw_and_call" @@ -23,26 +25,33 @@ const ( TestETHWithdrawAndCallThroughContractName = "eth_withdraw_and_call_through_contract" TestETHWithdrawAndCallRevertName = "eth_withdraw_and_call_revert" TestETHWithdrawAndCallRevertWithCallName = "eth_withdraw_and_call_revert_with_call" + TestETHWithdrawRevertAndAbortName = "eth_withdraw_revert_and_abort" TestETHWithdrawAndCallRevertWithWithdrawName = "eth_withdraw_and_call_revert_with_withdraw" TestDepositAndCallOutOfGasName = "deposit_and_call_out_of_gas" - TestERC20DepositName = "erc20_deposit" - TestERC20DepositAndCallName = "erc20_deposit_and_call" - TestERC20DepositAndCallNoMessageName = "erc20_deposit_and_call_no_message" - TestERC20DepositAndCallRevertName = "erc20_deposit_and_call_revert" - TestERC20DepositAndCallRevertWithCallName = "erc20_deposit_and_call_revert_with_call" - TestERC20WithdrawName = "erc20_withdraw" - TestERC20WithdrawAndArbitraryCallName = "erc20_withdraw_and_arbitrary_call" - TestERC20WithdrawAndCallName = "erc20_withdraw_and_call" - TestERC20WithdrawAndCallNoMessageName = "erc20_withdraw_and_call_no_message" - TestERC20WithdrawAndCallRevertName = "erc20_withdraw_and_call_revert" - TestERC20WithdrawAndCallRevertWithCallName = "erc20_withdraw_and_call_revert_with_call" - TestZEVMToEVMArbitraryCallName = "zevm_to_evm_arbitrary_call" - TestZEVMToEVMCallName = "zevm_to_evm_call" - TestZEVMToEVMCallThroughContractName = "zevm_to_evm_call_through_contract" - TestEVMToZEVMCallName = "evm_to_zevm_call" - TestDepositAndCallSwapName = "deposit_and_call_swap" - TestEtherWithdrawRestrictedName = "eth_withdraw_restricted" - TestERC20DepositRestrictedName = "erc20_deposit_restricted" // #nosec G101: Potential hardcoded credentials (gosec), not a credential + + TestERC20DepositName = "erc20_deposit" + TestERC20DepositAndCallName = "erc20_deposit_and_call" + TestERC20DepositAndCallNoMessageName = "erc20_deposit_and_call_no_message" + TestERC20DepositAndCallRevertName = "erc20_deposit_and_call_revert" + TestERC20DepositAndCallRevertWithCallName = "erc20_deposit_and_call_revert_with_call" + TestERC20DepositRevertAndAbortName = "erc20_deposit_revert_and_abort" + + TestERC20WithdrawName = "erc20_withdraw" + TestERC20WithdrawAndArbitraryCallName = "erc20_withdraw_and_arbitrary_call" + TestERC20WithdrawAndCallName = "erc20_withdraw_and_call" + TestERC20WithdrawAndCallNoMessageName = "erc20_withdraw_and_call_no_message" + TestERC20WithdrawAndCallRevertName = "erc20_withdraw_and_call_revert" + TestERC20WithdrawAndCallRevertWithCallName = "erc20_withdraw_and_call_revert_with_call" + TestERC20WithdrawRevertAndAbortName = "erc20_withdraw_revert_and_abort" + + TestZEVMToEVMArbitraryCallName = "zevm_to_evm_arbitrary_call" + TestZEVMToEVMCallName = "zevm_to_evm_call" + TestZEVMToEVMCallThroughContractName = "zevm_to_evm_call_through_contract" + TestEVMToZEVMCallName = "evm_to_zevm_call" + + TestDepositAndCallSwapName = "deposit_and_call_swap" + TestEtherWithdrawRestrictedName = "eth_withdraw_restricted" + TestERC20DepositRestrictedName = "erc20_deposit_restricted" // #nosec G101: Potential hardcoded credentials (gosec), not a credential /* * Solana tests @@ -244,6 +253,15 @@ var AllE2ETests = []runner.E2ETest{ }, TestETHDepositAndCallRevertWithCall, ), + runner.NewE2ETest( + TestETHDepositRevertAndAbortName, + "deposit Ether into ZEVM, revert, then abort with onAbort", + []runner.ArgDefinition{ + {Description: "amount in wei", DefaultValue: "10000000000000000"}, + }, + TestETHDepositRevertAndAbort, + runner.WithMinimumVersion("v28.0.0"), + ), runner.NewE2ETest( TestETHWithdrawName, "withdraw Ether from ZEVM", @@ -300,6 +318,15 @@ var AllE2ETests = []runner.E2ETest{ }, TestETHWithdrawAndCallRevertWithCall, ), + runner.NewE2ETest( + TestETHWithdrawRevertAndAbortName, + "withdraw Ether from ZEVM, revert, then abort with onAbort", + []runner.ArgDefinition{ + {Description: "amount in wei", DefaultValue: "100000"}, + }, + TestETHWithdrawRevertAndAbort, + runner.WithMinimumVersion("v28.0.0"), + ), runner.NewE2ETest( TestETHWithdrawAndCallRevertWithWithdrawName, "withdraw Ether from ZEVM and call a contract that reverts with a onRevert call that triggers a withdraw", @@ -357,6 +384,15 @@ var AllE2ETests = []runner.E2ETest{ }, TestERC20DepositAndCallRevertWithCall, ), + runner.NewE2ETest( + TestERC20DepositRevertAndAbortName, + "deposit ERC20 into ZEVM, revert, then abort with onAbort", + []runner.ArgDefinition{ + {Description: "amount", DefaultValue: "10000000000000000000"}, + }, + TestERC20DepositRevertAndAbort, + runner.WithMinimumVersion("v28.0.0"), + ), runner.NewE2ETest( TestERC20WithdrawName, "withdraw ERC20 from ZEVM", @@ -405,6 +441,15 @@ var AllE2ETests = []runner.E2ETest{ }, TestERC20WithdrawAndCallRevertWithCall, ), + runner.NewE2ETest( + TestERC20WithdrawRevertAndAbortName, + "withdraw ERC20 from ZEVM, revert, then abort with onAbort", + []runner.ArgDefinition{ + {Description: "amount", DefaultValue: "1000"}, + }, + TestERC20WithdrawRevertAndAbort, + runner.WithMinimumVersion("v28.0.0"), + ), runner.NewE2ETest( TestZEVMToEVMArbitraryCallName, "zevm -> evm call", diff --git a/e2e/e2etests/test_erc20_deposit_revert_and_abort.go b/e2e/e2etests/test_erc20_deposit_revert_and_abort.go new file mode 100644 index 0000000000..19269add20 --- /dev/null +++ b/e2e/e2etests/test_erc20_deposit_revert_and_abort.go @@ -0,0 +1,59 @@ +package e2etests + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/protocol-contracts/pkg/gatewayevm.sol" + + "github.com/zeta-chain/node/e2e/contracts/testabort" + "github.com/zeta-chain/node/e2e/runner" + "github.com/zeta-chain/node/e2e/utils" + "github.com/zeta-chain/node/testutil/sample" + crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" +) + +func TestERC20DepositRevertAndAbort(r *runner.E2ERunner, args []string) { + require.Len(r, args, 1) + + amount := utils.ParseBigInt(r, args[0]) + + r.ApproveERC20OnEVM(r.GatewayEVMAddr) + + // deploy testabort contract + testAbortAddr, _, testAbort, err := testabort.DeployTestAbort(r.ZEVMAuth, r.ZEVMClient) + require.NoError(r, err) + + // perform the deposit + tx := r.ERC20DepositAndCall( + sample.EthAddress(), // non-existing address + amount, []byte("revert"), + gatewayevm.RevertOptions{ + RevertAddress: sample.EthAddress(), // non-existing address + CallOnRevert: true, + RevertMessage: []byte("revert"), + OnRevertGasLimit: big.NewInt(200000), + AbortAddress: testAbortAddr, + }) + + // wait for the cctx to be reverted + cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) + r.Logger.CCTX(*cctx, "deposit_and_call") + require.Equal(r, crosschaintypes.CctxStatus_Aborted, cctx.CctxStatus.Status) + + // check onAbort was called + aborted, err := testAbort.IsAborted(&bind.CallOpts{}) + require.NoError(r, err) + require.True(r, aborted) + + // check abort context was passed + abortContext, err := testAbort.GetAbortedWithMessage(&bind.CallOpts{}, "revert") + require.NoError(r, err) + require.EqualValues(r, r.ERC20ZRC20Addr.Hex(), abortContext.Asset.Hex()) + + // check abort contract received the tokens + balance, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{}, testAbortAddr) + require.NoError(r, err) + require.True(r, balance.Uint64() > 0) +} diff --git a/e2e/e2etests/test_erc20_withdraw_revert_and_abort.go b/e2e/e2etests/test_erc20_withdraw_revert_and_abort.go new file mode 100644 index 0000000000..3af776a08c --- /dev/null +++ b/e2e/e2etests/test_erc20_withdraw_revert_and_abort.go @@ -0,0 +1,62 @@ +package e2etests + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/protocol-contracts/pkg/gatewayzevm.sol" + + "github.com/zeta-chain/node/e2e/contracts/testabort" + "github.com/zeta-chain/node/e2e/runner" + "github.com/zeta-chain/node/e2e/utils" + "github.com/zeta-chain/node/testutil/sample" + crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" +) + +func TestERC20WithdrawRevertAndAbort(r *runner.E2ERunner, args []string) { + require.Len(r, args, 1) + + amount := utils.ParseBigInt(r, args[0]) + + r.ApproveERC20ZRC20(r.GatewayZEVMAddr) + r.ApproveETHZRC20(r.GatewayZEVMAddr) + + // deploy testabort contract + testAbortAddr, _, testAbort, err := testabort.DeployTestAbort(r.ZEVMAuth, r.ZEVMClient) + require.NoError(r, err) + + // perform the withdraw + tx := r.ERC20WithdrawAndCall( + sample.EthAddress(), // non-existing address + amount, + []byte("revert"), + gatewayzevm.RevertOptions{ + RevertAddress: sample.EthAddress(), // non-existing address + CallOnRevert: true, + RevertMessage: []byte("revert"), + OnRevertGasLimit: big.NewInt(200000), + AbortAddress: testAbortAddr, + }, + ) + + // 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_Aborted, cctx.CctxStatus.Status) + + // check onAbort was called + aborted, err := testAbort.IsAborted(&bind.CallOpts{}) + require.NoError(r, err) + require.True(r, aborted) + + // check abort context was passed + abortContext, err := testAbort.GetAbortedWithMessage(&bind.CallOpts{}, "revert") + require.NoError(r, err) + require.EqualValues(r, r.ERC20ZRC20Addr.Hex(), abortContext.Asset.Hex()) + + // check abort contract received the tokens + balance, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{}, testAbortAddr) + require.NoError(r, err) + require.True(r, balance.Uint64() > 0) +} diff --git a/e2e/e2etests/test_eth_deposit_and_call_no_message.go b/e2e/e2etests/test_eth_deposit_and_call_no_message.go index b4b01cbbce..9789fbb565 100644 --- a/e2e/e2etests/test_eth_deposit_and_call_no_message.go +++ b/e2e/e2etests/test_eth_deposit_and_call_no_message.go @@ -17,9 +17,6 @@ func TestETHDepositAndCallNoMessage(r *runner.E2ERunner, args []string) { amount := utils.ParseBigInt(r, args[0]) - oldBalance, err := r.ETHZRC20.BalanceOf(&bind.CallOpts{}, r.TestDAppV2ZEVMAddr) - require.NoError(r, err) - // perform the deposit and call to the TestDAppV2ZEVMAddr tx := r.ETHDepositAndCall( r.TestDAppV2ZEVMAddr, @@ -37,9 +34,4 @@ func TestETHDepositAndCallNoMessage(r *runner.E2ERunner, args []string) { messageIndex, err := r.TestDAppV2ZEVM.GetNoMessageIndex(&bind.CallOpts{}, r.EVMAddress()) require.NoError(r, err) r.AssertTestDAppZEVMCalled(true, messageIndex, amount) - - // check the balance was updated - newBalance, err := r.ETHZRC20.BalanceOf(&bind.CallOpts{}, r.TestDAppV2ZEVMAddr) - require.NoError(r, err) - require.Equal(r, new(big.Int).Add(oldBalance, amount), newBalance) } diff --git a/e2e/e2etests/test_eth_deposit_revert_and_abort.go b/e2e/e2etests/test_eth_deposit_revert_and_abort.go new file mode 100644 index 0000000000..f93ab9f496 --- /dev/null +++ b/e2e/e2etests/test_eth_deposit_revert_and_abort.go @@ -0,0 +1,89 @@ +package e2etests + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/protocol-contracts/pkg/gatewayevm.sol" + + "github.com/zeta-chain/node/e2e/contracts/testabort" + "github.com/zeta-chain/node/e2e/runner" + "github.com/zeta-chain/node/e2e/utils" + "github.com/zeta-chain/node/testutil/sample" + crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" +) + +func TestETHDepositRevertAndAbort(r *runner.E2ERunner, args []string) { + require.Len(r, args, 1) + + amount := utils.ParseBigInt(r, args[0]) + + r.ApproveERC20OnEVM(r.GatewayEVMAddr) + + // deploy testabort contract + testAbortAddr, _, testAbort, err := testabort.DeployTestAbort(r.ZEVMAuth, r.ZEVMClient) + require.NoError(r, err) + + // perform the deposit + tx := r.ETHDepositAndCall( + r.TestDAppV2ZEVMAddr, + amount, + []byte("revert"), + gatewayevm.RevertOptions{ + RevertAddress: r.TestDAppV2EVMAddr, + CallOnRevert: true, + RevertMessage: []byte("revert"), + OnRevertGasLimit: big.NewInt(200000), + AbortAddress: testAbortAddr, + }, + ) + + // 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, "deposit") + require.Equal(r, crosschaintypes.CctxStatus_Aborted, cctx.CctxStatus.Status) + + // check onAbort was called + aborted, err := testAbort.IsAborted(&bind.CallOpts{}) + require.NoError(r, err) + require.True(r, aborted) + + // check abort context was passed + abortContext, err := testAbort.GetAbortedWithMessage(&bind.CallOpts{}, "revert") + require.NoError(r, err) + require.EqualValues(r, r.ETHZRC20Addr.Hex(), abortContext.Asset.Hex()) + + // check abort contract received the tokens + balance, err := r.ETHZRC20.BalanceOf(&bind.CallOpts{}, testAbortAddr) + require.NoError(r, err) + require.True(r, balance.Uint64() > 0) + + // Test 2: no contract for abort + + // check that funds are still received if onAbort is not called or fails + eoaAddress := sample.EthAddress() + + tx = r.ETHDepositAndCall( + r.TestDAppV2ZEVMAddr, + amount, + []byte("revert"), + gatewayevm.RevertOptions{ + RevertAddress: r.TestDAppV2EVMAddr, + CallOnRevert: true, + RevertMessage: []byte("revert"), + OnRevertGasLimit: big.NewInt(200000), + AbortAddress: eoaAddress, + }, + ) + + // 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, "deposit") + require.Equal(r, crosschaintypes.CctxStatus_Aborted, cctx.CctxStatus.Status) + + // check abort contract received the tokens + balance, err = r.ETHZRC20.BalanceOf(&bind.CallOpts{}, eoaAddress) + require.NoError(r, err) + require.True(r, balance.Uint64() > 0) +} diff --git a/e2e/e2etests/test_eth_withdraw_revert_and_abort.go b/e2e/e2etests/test_eth_withdraw_revert_and_abort.go new file mode 100644 index 0000000000..2a1a4c83cb --- /dev/null +++ b/e2e/e2etests/test_eth_withdraw_revert_and_abort.go @@ -0,0 +1,61 @@ +package e2etests + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/protocol-contracts/pkg/gatewayzevm.sol" + + "github.com/zeta-chain/node/e2e/contracts/testabort" + "github.com/zeta-chain/node/e2e/runner" + "github.com/zeta-chain/node/e2e/utils" + "github.com/zeta-chain/node/testutil/sample" + crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" +) + +func TestETHWithdrawRevertAndAbort(r *runner.E2ERunner, args []string) { + require.Len(r, args, 1) + + amount := utils.ParseBigInt(r, args[0]) + + r.ApproveETHZRC20(r.GatewayZEVMAddr) + + // deploy testabort contract + testAbortAddr, _, testAbort, err := testabort.DeployTestAbort(r.ZEVMAuth, r.ZEVMClient) + require.NoError(r, err) + + // perform the withdraw + tx := r.ETHWithdrawAndCall( + sample.EthAddress(), // non-existing address + amount, + []byte("revert"), + gatewayzevm.RevertOptions{ + RevertAddress: sample.EthAddress(), // non-existing address + CallOnRevert: true, + RevertMessage: []byte("revert"), + OnRevertGasLimit: big.NewInt(200000), + AbortAddress: testAbortAddr, + }, + ) + + // 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_Aborted, cctx.CctxStatus.Status) + + // check onAbort was called + aborted, err := testAbort.IsAborted(&bind.CallOpts{}) + require.NoError(r, err) + require.True(r, aborted) + + // check abort context was passed + abortContext, err := testAbort.GetAbortedWithMessage(&bind.CallOpts{}, "revert") + require.NoError(r, err) + require.EqualValues(r, r.ETHZRC20Addr.Hex(), abortContext.Asset.Hex()) + + // check abort contract received the tokens + balance, err := r.ETHZRC20.BalanceOf(&bind.CallOpts{}, testAbortAddr) + require.NoError(r, err) + require.True(r, balance.Uint64() > 0) +} diff --git a/go.mod b/go.mod index 698b33dbc5..236fa5964b 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,7 @@ require ( github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.10.0 github.com/zeta-chain/ethermint v0.0.0-20250210141109-c8cb0fa0d95d - github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20250115133723-7232d7838789 + github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20250124151021-87b63e845f1c gitlab.com/thorchain/tss/go-tss v1.6.5 go.nhat.io/grpcmock v0.25.0 golang.org/x/crypto v0.32.0 diff --git a/go.sum b/go.sum index 77bf6585b3..43b6819cb6 100644 --- a/go.sum +++ b/go.sum @@ -1402,8 +1402,8 @@ github.com/zeta-chain/go-libp2p v0.0.0-20240710192637-567fbaacc2b4 h1:FmO3HfVdZ7 github.com/zeta-chain/go-libp2p v0.0.0-20240710192637-567fbaacc2b4/go.mod h1:TBv5NY/CqWYIfUstXO1fDWrt4bDoqgCw79yihqBspg8= github.com/zeta-chain/go-tss v0.0.0-20241216161449-be92b20f8102 h1:jMb9ydfDFjgdlxpn8zClEPlUIJcz9ElahaAAXUPNFv0= github.com/zeta-chain/go-tss v0.0.0-20241216161449-be92b20f8102/go.mod h1:nqelgf4HKkqlXaVg8X38a61WfyYB+ivCt6nnjoTIgCc= -github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20250115133723-7232d7838789 h1:8DAZ5bgu+1ZbZ+VQh2eW15NPziwMy1g2k5rlKSfUFRI= -github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20250115133723-7232d7838789/go.mod h1:SjT7QirtJE8stnAe1SlNOanxtfSfijJm3MGJ+Ax7w7w= +github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20250124151021-87b63e845f1c h1:iD7O6gFot1QHM6ggrt96N9eXnZ7vqkg2mFVm7OTaisw= +github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20250124151021-87b63e845f1c/go.mod h1:SjT7QirtJE8stnAe1SlNOanxtfSfijJm3MGJ+Ax7w7w= github.com/zeta-chain/protocol-contracts-solana/go-idl v0.0.0-20250211174435-9680e27af84a h1:+TVuNWQK8j7yc9TkH+JOplMae7Ym/yADoIMnO1yIQzo= github.com/zeta-chain/protocol-contracts-solana/go-idl v0.0.0-20250211174435-9680e27af84a/go.mod h1:DcDY828o773soiU/h0XpC+naxitrIMFVZqEvq/EJxMA= github.com/zeta-chain/tss-lib v0.0.0-20240916163010-2e6b438bd901 h1:9whtN5fjYHfk4yXIuAsYP2EHxImwDWDVUOnZJ2pfL3w= diff --git a/pkg/contracts/testdappv2/TestDAppV2.bin b/pkg/contracts/testdappv2/TestDAppV2.bin index 71cbe43269..38bcf3cd8a 100644 --- a/pkg/contracts/testdappv2/TestDAppV2.bin +++ b/pkg/contracts/testdappv2/TestDAppV2.bin @@ -1 +1 @@ -60c060405234801561001057600080fd5b5060405161252f38038061252f83398181016040528101906100329190610114565b8115156080811515815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050610154565b600080fd5b60008115159050919050565b6100938161007e565b811461009e57600080fd5b50565b6000815190506100b08161008a565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100e1826100b6565b9050919050565b6100f1816100d6565b81146100fc57600080fd5b50565b60008151905061010e816100e8565b92915050565b6000806040838503121561012b5761012a610079565b5b6000610139858286016100a1565b925050602061014a858286016100ff565b9150509250929050565b60805160a0516123856101aa6000396000818161045b015281816104d40152818161084e0152610fe90152600081816104a90152818161082301528181610abb01528181610f9a0152610fbe01526123856000f3fe60806040526004361061010d5760003560e01c8063ad23b28b11610095578063c91f356711610064578063c91f35671461035b578063deb3b1e414610386578063e2842ed7146103a2578063f592cbfb146103df578063f936ae851461041c57610114565b8063ad23b28b146102a1578063c7a339a9146102de578063c85f843414610307578063c9028a361461033257610114565b80635bcfd616116100dc5780635bcfd616146101d3578063676cc054146101fc5780639291fe261461022c5780639ca016ed14610269578063a799911f1461028557610114565b8063116191b61461011957806336e980a01461014457806341a3cd4a1461016d5780634297a2631461019657610114565b3661011457005b600080fd5b34801561012557600080fd5b5061012e610459565b60405161013b91906113d1565b60405180910390f35b34801561015057600080fd5b5061016b60048036038101906101669190611546565b61047d565b005b34801561017957600080fd5b50610194600480360381019061018f919061161b565b6104a7565b005b3480156101a257600080fd5b506101bd60048036038101906101b891906116b1565b6105ce565b6040516101ca91906116f7565b60405180910390f35b3480156101df57600080fd5b506101fa60048036038101906101f59190611762565b6105e6565b005b61021660048036038101906102119190611825565b6106cc565b6040516102239190611904565b60405180910390f35b34801561023857600080fd5b50610253600480360381019061024e9190611546565b6107de565b60405161026091906116f7565b60405180910390f35b610283600480360381019061027e9190611926565b610821565b005b61029f600480360381019061029a9190611546565b610943565b005b3480156102ad57600080fd5b506102c860048036038101906102c39190611926565b61096c565b6040516102d591906119a8565b60405180910390f35b3480156102ea57600080fd5b5061030560048036038101906103009190611a08565b6109cc565b005b34801561031357600080fd5b5061031c610a80565b60405161032991906119a8565b60405180910390f35b34801561033e57600080fd5b5061035960048036038101906103549190611a96565b610ab9565b005b34801561036757600080fd5b50610370610f98565b60405161037d9190611afa565b60405180910390f35b6103a0600480360381019061039b919061161b565b610fbc565b005b3480156103ae57600080fd5b506103c960048036038101906103c491906116b1565b6110e4565b6040516103d69190611afa565b60405180910390f35b3480156103eb57600080fd5b5061040660048036038101906104019190611546565b611104565b6040516104139190611afa565b60405180910390f35b34801561042857600080fd5b50610443600480360381019061043e9190611bb6565b611154565b60405161045091906113d1565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b6104868161119d565b1561049057600080fd5b610499816111f3565b6104a4816000611247565b50565b7f0000000000000000000000000000000000000000000000000000000000000000156104d257600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631becceb48484846040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518563ffffffff1660e01b81526004016105979493929190611d19565b600060405180830381600087803b1580156105b157600080fd5b505af11580156105c5573d6000803e3d6000fd5b50505050505050565b60036020528060005260406000206000915090505481565b61063382828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061119d565b1561063d57600080fd5b60008083839050146106935782828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506106af565b6106ae8660200160208101906106a99190611926565b61096c565b5b90506106ba816111f3565b6106c48185611247565b505050505050565b606060008084849050146107245783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610740565b61073f85600001602081019061073a9190611926565b61096c565b5b905061074b816111f3565b6107558134611247565b8460000160208101906107689190611926565b6002826040516107789190611d9c565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550604051806020016040528060008152509150509392505050565b600060036000836040516020016107f59190611def565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b7f00000000000000000000000000000000000000000000000000000000000000001561084c57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663726ac97c34836040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518463ffffffff1660e01b815260040161090e929190611e06565b6000604051808303818588803b15801561092757600080fd5b505af115801561093b573d6000803e3d6000fd5b505050505050565b61094c8161119d565b1561095657600080fd5b61095f816111f3565b6109698134611247565b50565b60606040518060400160405280601681526020017f63616c6c65642077697468206e6f206d65737361676500000000000000000000815250826040516020016109b6929190611e7e565b6040516020818303038152906040529050919050565b6109d58161119d565b156109df57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401610a1c93929190611ea6565b6020604051808303816000875af1158015610a3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5f9190611f09565b610a6857600080fd5b610a71816111f3565b610a7b8183611247565b505050565b6040518060400160405280601681526020017f63616c6c65642077697468206e6f206d6573736167650000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000015610e5e57610ae7611289565b610b42818060600190610afa9190611f45565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506112fc565b15610e5d57600080826020016020810190610b5d9190611926565b73ffffffffffffffffffffffffffffffffffffffff1663d9eeebed6040518163ffffffff1660e01b81526004016040805180830381865afa158015610ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bca9190611fd2565b91509150826020016020810190610be19190611926565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610c4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c459061205e565b60405180910390fd5b8260400135811115610c95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8c906120f0565b60405180910390fd5b6000818460400135610ca7919061213f565b9050836020016020810190610cbc9190611926565b73ffffffffffffffffffffffffffffffffffffffff1663095ea7b33386604001356040518363ffffffff1660e01b8152600401610cfa929190612173565b6020604051808303816000875af1158015610d19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3d9190611f09565b503373ffffffffffffffffffffffffffffffffffffffff16637c0dcb5f856000016020810190610d6d9190611926565b604051602001610d7d91906113d1565b60405160208183030381529060405283876020016020810190610da09190611926565b6040518060a00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518563ffffffff1660e01b8152600401610e27949392919061219c565b600060405180830381600087803b158015610e4157600080fd5b505af1158015610e55573d6000803e3d6000fd5b505050505050505b5b610eb9818060600190610e719190611f45565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506111f3565b610f16818060600190610ecc9190611f45565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506000611247565b806000016020810190610f299190611926565b6002828060600190610f3b9190611f45565b604051610f49929190612214565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000015610fe757600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663744b9b8b348585856040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518663ffffffff1660e01b81526004016110ad9493929190611d19565b6000604051808303818588803b1580156110c657600080fd5b505af11580156110da573d6000803e3d6000fd5b5050505050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b6000600160008360405160200161111b9190611def565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b6002818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040516020016111ae90612279565b60405160208183030381529060405280519060200120826040516020016111d59190611def565b60405160208183030381529060405280519060200120149050919050565b6001806000836040516020016112099190611def565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b80600360008460405160200161125d9190611def565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b60006207a12090506000614e209050600081836112a691906122bd565b905060005b818110156112e957600081908060018154018082558091505060019003906000526020600020016000909190919091505580806001019150506112ab565b506000806112f79190611352565b505050565b600060405160200161130d9061233a565b60405160208183030381529060405280519060200120826040516020016113349190611def565b60405160208183030381529060405280519060200120149050919050565b50805460008255906000526020600020908101906113709190611373565b50565b5b8082111561138c576000816000905550600101611374565b5090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006113bb82611390565b9050919050565b6113cb816113b0565b82525050565b60006020820190506113e660008301846113c2565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6114538261140a565b810181811067ffffffffffffffff821117156114725761147161141b565b5b80604052505050565b60006114856113ec565b9050611491828261144a565b919050565b600067ffffffffffffffff8211156114b1576114b061141b565b5b6114ba8261140a565b9050602081019050919050565b82818337600083830152505050565b60006114e96114e484611496565b61147b565b90508281526020810184848401111561150557611504611405565b5b6115108482856114c7565b509392505050565b600082601f83011261152d5761152c611400565b5b813561153d8482602086016114d6565b91505092915050565b60006020828403121561155c5761155b6113f6565b5b600082013567ffffffffffffffff81111561157a576115796113fb565b5b61158684828501611518565b91505092915050565b611598816113b0565b81146115a357600080fd5b50565b6000813590506115b58161158f565b92915050565b600080fd5b600080fd5b60008083601f8401126115db576115da611400565b5b8235905067ffffffffffffffff8111156115f8576115f76115bb565b5b602083019150836001820283011115611614576116136115c0565b5b9250929050565b600080600060408486031215611634576116336113f6565b5b6000611642868287016115a6565b935050602084013567ffffffffffffffff811115611663576116626113fb565b5b61166f868287016115c5565b92509250509250925092565b6000819050919050565b61168e8161167b565b811461169957600080fd5b50565b6000813590506116ab81611685565b92915050565b6000602082840312156116c7576116c66113f6565b5b60006116d58482850161169c565b91505092915050565b6000819050919050565b6116f1816116de565b82525050565b600060208201905061170c60008301846116e8565b92915050565b600080fd5b60006060828403121561172d5761172c611712565b5b81905092915050565b61173f816116de565b811461174a57600080fd5b50565b60008135905061175c81611736565b92915050565b60008060008060006080868803121561177e5761177d6113f6565b5b600086013567ffffffffffffffff81111561179c5761179b6113fb565b5b6117a888828901611717565b95505060206117b9888289016115a6565b94505060406117ca8882890161174d565b935050606086013567ffffffffffffffff8111156117eb576117ea6113fb565b5b6117f7888289016115c5565b92509250509295509295909350565b60006020828403121561181c5761181b611712565b5b81905092915050565b60008060006040848603121561183e5761183d6113f6565b5b600061184c86828701611806565b935050602084013567ffffffffffffffff81111561186d5761186c6113fb565b5b611879868287016115c5565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b60005b838110156118bf5780820151818401526020810190506118a4565b60008484015250505050565b60006118d682611885565b6118e08185611890565b93506118f08185602086016118a1565b6118f98161140a565b840191505092915050565b6000602082019050818103600083015261191e81846118cb565b905092915050565b60006020828403121561193c5761193b6113f6565b5b600061194a848285016115a6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b600061197a82611953565b611984818561195e565b93506119948185602086016118a1565b61199d8161140a565b840191505092915050565b600060208201905081810360008301526119c2818461196f565b905092915050565b60006119d5826113b0565b9050919050565b6119e5816119ca565b81146119f057600080fd5b50565b600081359050611a02816119dc565b92915050565b600080600060608486031215611a2157611a206113f6565b5b6000611a2f868287016119f3565b9350506020611a408682870161174d565b925050604084013567ffffffffffffffff811115611a6157611a606113fb565b5b611a6d86828701611518565b9150509250925092565b600060808284031215611a8d57611a8c611712565b5b81905092915050565b600060208284031215611aac57611aab6113f6565b5b600082013567ffffffffffffffff811115611aca57611ac96113fb565b5b611ad684828501611a77565b91505092915050565b60008115159050919050565b611af481611adf565b82525050565b6000602082019050611b0f6000830184611aeb565b92915050565b600067ffffffffffffffff821115611b3057611b2f61141b565b5b611b398261140a565b9050602081019050919050565b6000611b59611b5484611b15565b61147b565b905082815260208101848484011115611b7557611b74611405565b5b611b808482856114c7565b509392505050565b600082601f830112611b9d57611b9c611400565b5b8135611bad848260208601611b46565b91505092915050565b600060208284031215611bcc57611bcb6113f6565b5b600082013567ffffffffffffffff811115611bea57611be96113fb565b5b611bf684828501611b88565b91505092915050565b6000611c0b8385611890565b9350611c188385846114c7565b611c218361140a565b840190509392505050565b611c35816113b0565b82525050565b611c4481611adf565b82525050565b600082825260208201905092915050565b6000611c6682611885565b611c708185611c4a565b9350611c808185602086016118a1565b611c898161140a565b840191505092915050565b611c9d816116de565b82525050565b600060a083016000830151611cbb6000860182611c2c565b506020830151611cce6020860182611c3b565b506040830151611ce16040860182611c2c565b5060608301518482036060860152611cf98282611c5b565b9150506080830151611d0e6080860182611c94565b508091505092915050565b6000606082019050611d2e60008301876113c2565b8181036020830152611d41818587611bff565b90508181036040830152611d558184611ca3565b905095945050505050565b600081905092915050565b6000611d7682611885565b611d808185611d60565b9350611d908185602086016118a1565b80840191505092915050565b6000611da88284611d6b565b915081905092915050565b600081905092915050565b6000611dc982611953565b611dd38185611db3565b9350611de38185602086016118a1565b80840191505092915050565b6000611dfb8284611dbe565b915081905092915050565b6000604082019050611e1b60008301856113c2565b8181036020830152611e2d8184611ca3565b90509392505050565b60008160601b9050919050565b6000611e4e82611e36565b9050919050565b6000611e6082611e43565b9050919050565b611e78611e73826113b0565b611e55565b82525050565b6000611e8a8285611dbe565b9150611e968284611e67565b6014820191508190509392505050565b6000606082019050611ebb60008301866113c2565b611ec860208301856113c2565b611ed560408301846116e8565b949350505050565b611ee681611adf565b8114611ef157600080fd5b50565b600081519050611f0381611edd565b92915050565b600060208284031215611f1f57611f1e6113f6565b5b6000611f2d84828501611ef4565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112611f6257611f61611f36565b5b80840192508235915067ffffffffffffffff821115611f8457611f83611f3b565b5b602083019250600182023603831315611fa057611f9f611f40565b5b509250929050565b600081519050611fb78161158f565b92915050565b600081519050611fcc81611736565b92915050565b60008060408385031215611fe957611fe86113f6565b5b6000611ff785828601611fa8565b925050602061200885828601611fbd565b9150509250929050565b7f7a72633230206973206e6f742067617320746f6b656e00000000000000000000600082015250565b600061204860168361195e565b915061205382612012565b602082019050919050565b600060208201905081810360008301526120778161203b565b9050919050565b7f66656520616d6f756e7420697320686967686572207468616e2074686520616d60008201527f6f756e7400000000000000000000000000000000000000000000000000000000602082015250565b60006120da60248361195e565b91506120e58261207e565b604082019050919050565b60006020820190508181036000830152612109816120cd565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061214a826116de565b9150612155836116de565b925082820390508181111561216d5761216c612110565b5b92915050565b600060408201905061218860008301856113c2565b61219560208301846116e8565b9392505050565b600060808201905081810360008301526121b681876118cb565b90506121c560208301866116e8565b6121d260408301856113c2565b81810360608301526121e48184611ca3565b905095945050505050565b60006121fb8385611d60565b93506122088385846114c7565b82840190509392505050565b60006122218284866121ef565b91508190509392505050565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b6000612263600683611db3565b915061226e8261222d565b600682019050919050565b600061228482612256565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006122c8826116de565b91506122d3836116de565b9250826122e3576122e261228e565b5b828204905092915050565b7f7769746864726177000000000000000000000000000000000000000000000000600082015250565b6000612324600883611db3565b915061232f826122ee565b600882019050919050565b600061234582612317565b915081905091905056fea2646970667358221220cc1d392f0803f3c30b8da3699bebbbdf5e1711d9c77c2bd74f9a96c12336d8f564736f6c634300081a0033 +60c060405234801561001057600080fd5b5060405161259438038061259483398181016040528101906100329190610114565b8115156080811515815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050610154565b600080fd5b60008115159050919050565b6100938161007e565b811461009e57600080fd5b50565b6000815190506100b08161008a565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100e1826100b6565b9050919050565b6100f1816100d6565b81146100fc57600080fd5b50565b60008151905061010e816100e8565b92915050565b6000806040838503121561012b5761012a610079565b5b6000610139858286016100a1565b925050602061014a858286016100ff565b9150509250929050565b60805160a0516123ea6101aa6000396000818161045b015281816104d40152818161084e015261104e0152600081816104a90152818161082301528181610b2001528181610fff015261102301526123ea6000f3fe60806040526004361061010d5760003560e01c8063ad23b28b11610095578063c91f356711610064578063c91f35671461035b578063deb3b1e414610386578063e2842ed7146103a2578063f592cbfb146103df578063f936ae851461041c57610114565b8063ad23b28b146102a1578063c7a339a9146102de578063c85f843414610307578063c9028a361461033257610114565b80635bcfd616116100dc5780635bcfd616146101d3578063676cc054146101fc5780639291fe261461022c5780639ca016ed14610269578063a799911f1461028557610114565b8063116191b61461011957806336e980a01461014457806341a3cd4a1461016d5780634297a2631461019657610114565b3661011457005b600080fd5b34801561012557600080fd5b5061012e610459565b60405161013b9190611436565b60405180910390f35b34801561015057600080fd5b5061016b600480360381019061016691906115ab565b61047d565b005b34801561017957600080fd5b50610194600480360381019061018f9190611680565b6104a7565b005b3480156101a257600080fd5b506101bd60048036038101906101b89190611716565b6105ce565b6040516101ca919061175c565b60405180910390f35b3480156101df57600080fd5b506101fa60048036038101906101f591906117c7565b6105e6565b005b6102166004803603810190610211919061188a565b6106cc565b6040516102239190611969565b60405180910390f35b34801561023857600080fd5b50610253600480360381019061024e91906115ab565b6107de565b604051610260919061175c565b60405180910390f35b610283600480360381019061027e919061198b565b610821565b005b61029f600480360381019061029a91906115ab565b610943565b005b3480156102ad57600080fd5b506102c860048036038101906102c3919061198b565b61096c565b6040516102d59190611a0d565b60405180910390f35b3480156102ea57600080fd5b5061030560048036038101906103009190611a6d565b6109cc565b005b34801561031357600080fd5b5061031c610a80565b6040516103299190611a0d565b60405180910390f35b34801561033e57600080fd5b5061035960048036038101906103549190611afb565b610ab9565b005b34801561036757600080fd5b50610370610ffd565b60405161037d9190611b5f565b60405180910390f35b6103a0600480360381019061039b9190611680565b611021565b005b3480156103ae57600080fd5b506103c960048036038101906103c49190611716565b611149565b6040516103d69190611b5f565b60405180910390f35b3480156103eb57600080fd5b50610406600480360381019061040191906115ab565b611169565b6040516104139190611b5f565b60405180910390f35b34801561042857600080fd5b50610443600480360381019061043e9190611c1b565b6111b9565b6040516104509190611436565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b61048681611202565b1561049057600080fd5b61049981611258565b6104a48160006112ac565b50565b7f0000000000000000000000000000000000000000000000000000000000000000156104d257600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631becceb48484846040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518563ffffffff1660e01b81526004016105979493929190611d7e565b600060405180830381600087803b1580156105b157600080fd5b505af11580156105c5573d6000803e3d6000fd5b50505050505050565b60036020528060005260406000206000915090505481565b61063382828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611202565b1561063d57600080fd5b60008083839050146106935782828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506106af565b6106ae8660200160208101906106a9919061198b565b61096c565b5b90506106ba81611258565b6106c481856112ac565b505050505050565b606060008084849050146107245783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610740565b61073f85600001602081019061073a919061198b565b61096c565b5b905061074b81611258565b61075581346112ac565b846000016020810190610768919061198b565b6002826040516107789190611e01565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550604051806020016040528060008152509150509392505050565b600060036000836040516020016107f59190611e54565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b7f00000000000000000000000000000000000000000000000000000000000000001561084c57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663726ac97c34836040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518463ffffffff1660e01b815260040161090e929190611e6b565b6000604051808303818588803b15801561092757600080fd5b505af115801561093b573d6000803e3d6000fd5b505050505050565b61094c81611202565b1561095657600080fd5b61095f81611258565b61096981346112ac565b50565b60606040518060400160405280601681526020017f63616c6c65642077697468206e6f206d65737361676500000000000000000000815250826040516020016109b6929190611ee3565b6040516020818303038152906040529050919050565b6109d581611202565b156109df57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401610a1c93929190611f0b565b6020604051808303816000875af1158015610a3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5f9190611f6e565b610a6857600080fd5b610a7181611258565b610a7b81836112ac565b505050565b6040518060400160405280601681526020017f63616c6c65642077697468206e6f206d6573736167650000000000000000000081525081565b610b14818060600190610acc9190611faa565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611202565b15610b1e57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000015610ec357610b4c6112ee565b610ba7818060600190610b5f9190611faa565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611361565b15610ec257600080826020016020810190610bc2919061198b565b73ffffffffffffffffffffffffffffffffffffffff1663d9eeebed6040518163ffffffff1660e01b81526004016040805180830381865afa158015610c0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2f9190612037565b91509150826020016020810190610c46919061198b565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610cb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610caa906120c3565b60405180910390fd5b8260400135811115610cfa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf190612155565b60405180910390fd5b6000818460400135610d0c91906121a4565b9050836020016020810190610d21919061198b565b73ffffffffffffffffffffffffffffffffffffffff1663095ea7b33386604001356040518363ffffffff1660e01b8152600401610d5f9291906121d8565b6020604051808303816000875af1158015610d7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da29190611f6e565b503373ffffffffffffffffffffffffffffffffffffffff16637c0dcb5f856000016020810190610dd2919061198b565b604051602001610de29190611436565b60405160208183030381529060405283876020016020810190610e05919061198b565b6040518060a00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518563ffffffff1660e01b8152600401610e8c9493929190612201565b600060405180830381600087803b158015610ea657600080fd5b505af1158015610eba573d6000803e3d6000fd5b505050505050505b5b610f1e818060600190610ed69190611faa565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611258565b610f7b818060600190610f319190611faa565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060006112ac565b806000016020810190610f8e919061198b565b6002828060600190610fa09190611faa565b604051610fae929190612279565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f00000000000000000000000000000000000000000000000000000000000000001561104c57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663744b9b8b348585856040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518663ffffffff1660e01b81526004016111129493929190611d7e565b6000604051808303818588803b15801561112b57600080fd5b505af115801561113f573d6000803e3d6000fd5b5050505050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b600060016000836040516020016111809190611e54565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b6002818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000604051602001611213906122de565b604051602081830303815290604052805190602001208260405160200161123a9190611e54565b60405160208183030381529060405280519060200120149050919050565b60018060008360405160200161126e9190611e54565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b8060036000846040516020016112c29190611e54565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b60006207a12090506000614e2090506000818361130b9190612322565b905060005b8181101561134e5760008190806001815401808255809150506001900390600052602060002001600090919091909150558080600101915050611310565b5060008061135c91906113b7565b505050565b60006040516020016113729061239f565b60405160208183030381529060405280519060200120826040516020016113999190611e54565b60405160208183030381529060405280519060200120149050919050565b50805460008255906000526020600020908101906113d591906113d8565b50565b5b808211156113f15760008160009055506001016113d9565b5090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611420826113f5565b9050919050565b61143081611415565b82525050565b600060208201905061144b6000830184611427565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6114b88261146f565b810181811067ffffffffffffffff821117156114d7576114d6611480565b5b80604052505050565b60006114ea611451565b90506114f682826114af565b919050565b600067ffffffffffffffff82111561151657611515611480565b5b61151f8261146f565b9050602081019050919050565b82818337600083830152505050565b600061154e611549846114fb565b6114e0565b90508281526020810184848401111561156a5761156961146a565b5b61157584828561152c565b509392505050565b600082601f83011261159257611591611465565b5b81356115a284826020860161153b565b91505092915050565b6000602082840312156115c1576115c061145b565b5b600082013567ffffffffffffffff8111156115df576115de611460565b5b6115eb8482850161157d565b91505092915050565b6115fd81611415565b811461160857600080fd5b50565b60008135905061161a816115f4565b92915050565b600080fd5b600080fd5b60008083601f8401126116405761163f611465565b5b8235905067ffffffffffffffff81111561165d5761165c611620565b5b60208301915083600182028301111561167957611678611625565b5b9250929050565b6000806000604084860312156116995761169861145b565b5b60006116a78682870161160b565b935050602084013567ffffffffffffffff8111156116c8576116c7611460565b5b6116d48682870161162a565b92509250509250925092565b6000819050919050565b6116f3816116e0565b81146116fe57600080fd5b50565b600081359050611710816116ea565b92915050565b60006020828403121561172c5761172b61145b565b5b600061173a84828501611701565b91505092915050565b6000819050919050565b61175681611743565b82525050565b6000602082019050611771600083018461174d565b92915050565b600080fd5b60006060828403121561179257611791611777565b5b81905092915050565b6117a481611743565b81146117af57600080fd5b50565b6000813590506117c18161179b565b92915050565b6000806000806000608086880312156117e3576117e261145b565b5b600086013567ffffffffffffffff81111561180157611800611460565b5b61180d8882890161177c565b955050602061181e8882890161160b565b945050604061182f888289016117b2565b935050606086013567ffffffffffffffff8111156118505761184f611460565b5b61185c8882890161162a565b92509250509295509295909350565b60006020828403121561188157611880611777565b5b81905092915050565b6000806000604084860312156118a3576118a261145b565b5b60006118b18682870161186b565b935050602084013567ffffffffffffffff8111156118d2576118d1611460565b5b6118de8682870161162a565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b60005b83811015611924578082015181840152602081019050611909565b60008484015250505050565b600061193b826118ea565b61194581856118f5565b9350611955818560208601611906565b61195e8161146f565b840191505092915050565b600060208201905081810360008301526119838184611930565b905092915050565b6000602082840312156119a1576119a061145b565b5b60006119af8482850161160b565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60006119df826119b8565b6119e981856119c3565b93506119f9818560208601611906565b611a028161146f565b840191505092915050565b60006020820190508181036000830152611a2781846119d4565b905092915050565b6000611a3a82611415565b9050919050565b611a4a81611a2f565b8114611a5557600080fd5b50565b600081359050611a6781611a41565b92915050565b600080600060608486031215611a8657611a8561145b565b5b6000611a9486828701611a58565b9350506020611aa5868287016117b2565b925050604084013567ffffffffffffffff811115611ac657611ac5611460565b5b611ad28682870161157d565b9150509250925092565b600060808284031215611af257611af1611777565b5b81905092915050565b600060208284031215611b1157611b1061145b565b5b600082013567ffffffffffffffff811115611b2f57611b2e611460565b5b611b3b84828501611adc565b91505092915050565b60008115159050919050565b611b5981611b44565b82525050565b6000602082019050611b746000830184611b50565b92915050565b600067ffffffffffffffff821115611b9557611b94611480565b5b611b9e8261146f565b9050602081019050919050565b6000611bbe611bb984611b7a565b6114e0565b905082815260208101848484011115611bda57611bd961146a565b5b611be584828561152c565b509392505050565b600082601f830112611c0257611c01611465565b5b8135611c12848260208601611bab565b91505092915050565b600060208284031215611c3157611c3061145b565b5b600082013567ffffffffffffffff811115611c4f57611c4e611460565b5b611c5b84828501611bed565b91505092915050565b6000611c7083856118f5565b9350611c7d83858461152c565b611c868361146f565b840190509392505050565b611c9a81611415565b82525050565b611ca981611b44565b82525050565b600082825260208201905092915050565b6000611ccb826118ea565b611cd58185611caf565b9350611ce5818560208601611906565b611cee8161146f565b840191505092915050565b611d0281611743565b82525050565b600060a083016000830151611d206000860182611c91565b506020830151611d336020860182611ca0565b506040830151611d466040860182611c91565b5060608301518482036060860152611d5e8282611cc0565b9150506080830151611d736080860182611cf9565b508091505092915050565b6000606082019050611d936000830187611427565b8181036020830152611da6818587611c64565b90508181036040830152611dba8184611d08565b905095945050505050565b600081905092915050565b6000611ddb826118ea565b611de58185611dc5565b9350611df5818560208601611906565b80840191505092915050565b6000611e0d8284611dd0565b915081905092915050565b600081905092915050565b6000611e2e826119b8565b611e388185611e18565b9350611e48818560208601611906565b80840191505092915050565b6000611e608284611e23565b915081905092915050565b6000604082019050611e806000830185611427565b8181036020830152611e928184611d08565b90509392505050565b60008160601b9050919050565b6000611eb382611e9b565b9050919050565b6000611ec582611ea8565b9050919050565b611edd611ed882611415565b611eba565b82525050565b6000611eef8285611e23565b9150611efb8284611ecc565b6014820191508190509392505050565b6000606082019050611f206000830186611427565b611f2d6020830185611427565b611f3a604083018461174d565b949350505050565b611f4b81611b44565b8114611f5657600080fd5b50565b600081519050611f6881611f42565b92915050565b600060208284031215611f8457611f8361145b565b5b6000611f9284828501611f59565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112611fc757611fc6611f9b565b5b80840192508235915067ffffffffffffffff821115611fe957611fe8611fa0565b5b60208301925060018202360383131561200557612004611fa5565b5b509250929050565b60008151905061201c816115f4565b92915050565b6000815190506120318161179b565b92915050565b6000806040838503121561204e5761204d61145b565b5b600061205c8582860161200d565b925050602061206d85828601612022565b9150509250929050565b7f7a72633230206973206e6f742067617320746f6b656e00000000000000000000600082015250565b60006120ad6016836119c3565b91506120b882612077565b602082019050919050565b600060208201905081810360008301526120dc816120a0565b9050919050565b7f66656520616d6f756e7420697320686967686572207468616e2074686520616d60008201527f6f756e7400000000000000000000000000000000000000000000000000000000602082015250565b600061213f6024836119c3565b915061214a826120e3565b604082019050919050565b6000602082019050818103600083015261216e81612132565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006121af82611743565b91506121ba83611743565b92508282039050818111156121d2576121d1612175565b5b92915050565b60006040820190506121ed6000830185611427565b6121fa602083018461174d565b9392505050565b6000608082019050818103600083015261221b8187611930565b905061222a602083018661174d565b6122376040830185611427565b81810360608301526122498184611d08565b905095945050505050565b60006122608385611dc5565b935061226d83858461152c565b82840190509392505050565b6000612286828486612254565b91508190509392505050565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b60006122c8600683611e18565b91506122d382612292565b600682019050919050565b60006122e9826122bb565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061232d82611743565b915061233883611743565b925082612348576123476122f3565b5b828204905092915050565b7f7769746864726177000000000000000000000000000000000000000000000000600082015250565b6000612389600883611e18565b915061239482612353565b600882019050919050565b60006123aa8261237c565b915081905091905056fea2646970667358221220e0e7dfdd94bdbc9796b718d6cbbf5d94e34a34e70ed21a1f60997215fbaed17964736f6c634300081a0033 diff --git a/pkg/contracts/testdappv2/TestDAppV2.go b/pkg/contracts/testdappv2/TestDAppV2.go index 4c580efc3a..b91eca4590 100644 --- a/pkg/contracts/testdappv2/TestDAppV2.go +++ b/pkg/contracts/testdappv2/TestDAppV2.go @@ -52,7 +52,7 @@ type TestDAppV2zContext struct { // TestDAppV2MetaData contains all meta data concerning the TestDAppV2 contract. var TestDAppV2MetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"isZetaChain_\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"gateway_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"NO_MESSAGE_CALL\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"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\":[],\"name\":\"gateway\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"gatewayCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"}],\"name\":\"gatewayDeposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"gatewayDepositAndCall\",\"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\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getNoMessageIndex\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isZetaChain\",\"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\":\"onCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"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\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"simpleCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", - Bin: "0x60c060405234801561001057600080fd5b5060405161252f38038061252f83398181016040528101906100329190610114565b8115156080811515815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050610154565b600080fd5b60008115159050919050565b6100938161007e565b811461009e57600080fd5b50565b6000815190506100b08161008a565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100e1826100b6565b9050919050565b6100f1816100d6565b81146100fc57600080fd5b50565b60008151905061010e816100e8565b92915050565b6000806040838503121561012b5761012a610079565b5b6000610139858286016100a1565b925050602061014a858286016100ff565b9150509250929050565b60805160a0516123856101aa6000396000818161045b015281816104d40152818161084e0152610fe90152600081816104a90152818161082301528181610abb01528181610f9a0152610fbe01526123856000f3fe60806040526004361061010d5760003560e01c8063ad23b28b11610095578063c91f356711610064578063c91f35671461035b578063deb3b1e414610386578063e2842ed7146103a2578063f592cbfb146103df578063f936ae851461041c57610114565b8063ad23b28b146102a1578063c7a339a9146102de578063c85f843414610307578063c9028a361461033257610114565b80635bcfd616116100dc5780635bcfd616146101d3578063676cc054146101fc5780639291fe261461022c5780639ca016ed14610269578063a799911f1461028557610114565b8063116191b61461011957806336e980a01461014457806341a3cd4a1461016d5780634297a2631461019657610114565b3661011457005b600080fd5b34801561012557600080fd5b5061012e610459565b60405161013b91906113d1565b60405180910390f35b34801561015057600080fd5b5061016b60048036038101906101669190611546565b61047d565b005b34801561017957600080fd5b50610194600480360381019061018f919061161b565b6104a7565b005b3480156101a257600080fd5b506101bd60048036038101906101b891906116b1565b6105ce565b6040516101ca91906116f7565b60405180910390f35b3480156101df57600080fd5b506101fa60048036038101906101f59190611762565b6105e6565b005b61021660048036038101906102119190611825565b6106cc565b6040516102239190611904565b60405180910390f35b34801561023857600080fd5b50610253600480360381019061024e9190611546565b6107de565b60405161026091906116f7565b60405180910390f35b610283600480360381019061027e9190611926565b610821565b005b61029f600480360381019061029a9190611546565b610943565b005b3480156102ad57600080fd5b506102c860048036038101906102c39190611926565b61096c565b6040516102d591906119a8565b60405180910390f35b3480156102ea57600080fd5b5061030560048036038101906103009190611a08565b6109cc565b005b34801561031357600080fd5b5061031c610a80565b60405161032991906119a8565b60405180910390f35b34801561033e57600080fd5b5061035960048036038101906103549190611a96565b610ab9565b005b34801561036757600080fd5b50610370610f98565b60405161037d9190611afa565b60405180910390f35b6103a0600480360381019061039b919061161b565b610fbc565b005b3480156103ae57600080fd5b506103c960048036038101906103c491906116b1565b6110e4565b6040516103d69190611afa565b60405180910390f35b3480156103eb57600080fd5b5061040660048036038101906104019190611546565b611104565b6040516104139190611afa565b60405180910390f35b34801561042857600080fd5b50610443600480360381019061043e9190611bb6565b611154565b60405161045091906113d1565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b6104868161119d565b1561049057600080fd5b610499816111f3565b6104a4816000611247565b50565b7f0000000000000000000000000000000000000000000000000000000000000000156104d257600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631becceb48484846040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518563ffffffff1660e01b81526004016105979493929190611d19565b600060405180830381600087803b1580156105b157600080fd5b505af11580156105c5573d6000803e3d6000fd5b50505050505050565b60036020528060005260406000206000915090505481565b61063382828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061119d565b1561063d57600080fd5b60008083839050146106935782828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506106af565b6106ae8660200160208101906106a99190611926565b61096c565b5b90506106ba816111f3565b6106c48185611247565b505050505050565b606060008084849050146107245783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610740565b61073f85600001602081019061073a9190611926565b61096c565b5b905061074b816111f3565b6107558134611247565b8460000160208101906107689190611926565b6002826040516107789190611d9c565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550604051806020016040528060008152509150509392505050565b600060036000836040516020016107f59190611def565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b7f00000000000000000000000000000000000000000000000000000000000000001561084c57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663726ac97c34836040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518463ffffffff1660e01b815260040161090e929190611e06565b6000604051808303818588803b15801561092757600080fd5b505af115801561093b573d6000803e3d6000fd5b505050505050565b61094c8161119d565b1561095657600080fd5b61095f816111f3565b6109698134611247565b50565b60606040518060400160405280601681526020017f63616c6c65642077697468206e6f206d65737361676500000000000000000000815250826040516020016109b6929190611e7e565b6040516020818303038152906040529050919050565b6109d58161119d565b156109df57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401610a1c93929190611ea6565b6020604051808303816000875af1158015610a3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5f9190611f09565b610a6857600080fd5b610a71816111f3565b610a7b8183611247565b505050565b6040518060400160405280601681526020017f63616c6c65642077697468206e6f206d6573736167650000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000015610e5e57610ae7611289565b610b42818060600190610afa9190611f45565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506112fc565b15610e5d57600080826020016020810190610b5d9190611926565b73ffffffffffffffffffffffffffffffffffffffff1663d9eeebed6040518163ffffffff1660e01b81526004016040805180830381865afa158015610ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bca9190611fd2565b91509150826020016020810190610be19190611926565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610c4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c459061205e565b60405180910390fd5b8260400135811115610c95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8c906120f0565b60405180910390fd5b6000818460400135610ca7919061213f565b9050836020016020810190610cbc9190611926565b73ffffffffffffffffffffffffffffffffffffffff1663095ea7b33386604001356040518363ffffffff1660e01b8152600401610cfa929190612173565b6020604051808303816000875af1158015610d19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3d9190611f09565b503373ffffffffffffffffffffffffffffffffffffffff16637c0dcb5f856000016020810190610d6d9190611926565b604051602001610d7d91906113d1565b60405160208183030381529060405283876020016020810190610da09190611926565b6040518060a00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518563ffffffff1660e01b8152600401610e27949392919061219c565b600060405180830381600087803b158015610e4157600080fd5b505af1158015610e55573d6000803e3d6000fd5b505050505050505b5b610eb9818060600190610e719190611f45565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506111f3565b610f16818060600190610ecc9190611f45565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506000611247565b806000016020810190610f299190611926565b6002828060600190610f3b9190611f45565b604051610f49929190612214565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000015610fe757600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663744b9b8b348585856040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518663ffffffff1660e01b81526004016110ad9493929190611d19565b6000604051808303818588803b1580156110c657600080fd5b505af11580156110da573d6000803e3d6000fd5b5050505050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b6000600160008360405160200161111b9190611def565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b6002818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040516020016111ae90612279565b60405160208183030381529060405280519060200120826040516020016111d59190611def565b60405160208183030381529060405280519060200120149050919050565b6001806000836040516020016112099190611def565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b80600360008460405160200161125d9190611def565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b60006207a12090506000614e209050600081836112a691906122bd565b905060005b818110156112e957600081908060018154018082558091505060019003906000526020600020016000909190919091505580806001019150506112ab565b506000806112f79190611352565b505050565b600060405160200161130d9061233a565b60405160208183030381529060405280519060200120826040516020016113349190611def565b60405160208183030381529060405280519060200120149050919050565b50805460008255906000526020600020908101906113709190611373565b50565b5b8082111561138c576000816000905550600101611374565b5090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006113bb82611390565b9050919050565b6113cb816113b0565b82525050565b60006020820190506113e660008301846113c2565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6114538261140a565b810181811067ffffffffffffffff821117156114725761147161141b565b5b80604052505050565b60006114856113ec565b9050611491828261144a565b919050565b600067ffffffffffffffff8211156114b1576114b061141b565b5b6114ba8261140a565b9050602081019050919050565b82818337600083830152505050565b60006114e96114e484611496565b61147b565b90508281526020810184848401111561150557611504611405565b5b6115108482856114c7565b509392505050565b600082601f83011261152d5761152c611400565b5b813561153d8482602086016114d6565b91505092915050565b60006020828403121561155c5761155b6113f6565b5b600082013567ffffffffffffffff81111561157a576115796113fb565b5b61158684828501611518565b91505092915050565b611598816113b0565b81146115a357600080fd5b50565b6000813590506115b58161158f565b92915050565b600080fd5b600080fd5b60008083601f8401126115db576115da611400565b5b8235905067ffffffffffffffff8111156115f8576115f76115bb565b5b602083019150836001820283011115611614576116136115c0565b5b9250929050565b600080600060408486031215611634576116336113f6565b5b6000611642868287016115a6565b935050602084013567ffffffffffffffff811115611663576116626113fb565b5b61166f868287016115c5565b92509250509250925092565b6000819050919050565b61168e8161167b565b811461169957600080fd5b50565b6000813590506116ab81611685565b92915050565b6000602082840312156116c7576116c66113f6565b5b60006116d58482850161169c565b91505092915050565b6000819050919050565b6116f1816116de565b82525050565b600060208201905061170c60008301846116e8565b92915050565b600080fd5b60006060828403121561172d5761172c611712565b5b81905092915050565b61173f816116de565b811461174a57600080fd5b50565b60008135905061175c81611736565b92915050565b60008060008060006080868803121561177e5761177d6113f6565b5b600086013567ffffffffffffffff81111561179c5761179b6113fb565b5b6117a888828901611717565b95505060206117b9888289016115a6565b94505060406117ca8882890161174d565b935050606086013567ffffffffffffffff8111156117eb576117ea6113fb565b5b6117f7888289016115c5565b92509250509295509295909350565b60006020828403121561181c5761181b611712565b5b81905092915050565b60008060006040848603121561183e5761183d6113f6565b5b600061184c86828701611806565b935050602084013567ffffffffffffffff81111561186d5761186c6113fb565b5b611879868287016115c5565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b60005b838110156118bf5780820151818401526020810190506118a4565b60008484015250505050565b60006118d682611885565b6118e08185611890565b93506118f08185602086016118a1565b6118f98161140a565b840191505092915050565b6000602082019050818103600083015261191e81846118cb565b905092915050565b60006020828403121561193c5761193b6113f6565b5b600061194a848285016115a6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b600061197a82611953565b611984818561195e565b93506119948185602086016118a1565b61199d8161140a565b840191505092915050565b600060208201905081810360008301526119c2818461196f565b905092915050565b60006119d5826113b0565b9050919050565b6119e5816119ca565b81146119f057600080fd5b50565b600081359050611a02816119dc565b92915050565b600080600060608486031215611a2157611a206113f6565b5b6000611a2f868287016119f3565b9350506020611a408682870161174d565b925050604084013567ffffffffffffffff811115611a6157611a606113fb565b5b611a6d86828701611518565b9150509250925092565b600060808284031215611a8d57611a8c611712565b5b81905092915050565b600060208284031215611aac57611aab6113f6565b5b600082013567ffffffffffffffff811115611aca57611ac96113fb565b5b611ad684828501611a77565b91505092915050565b60008115159050919050565b611af481611adf565b82525050565b6000602082019050611b0f6000830184611aeb565b92915050565b600067ffffffffffffffff821115611b3057611b2f61141b565b5b611b398261140a565b9050602081019050919050565b6000611b59611b5484611b15565b61147b565b905082815260208101848484011115611b7557611b74611405565b5b611b808482856114c7565b509392505050565b600082601f830112611b9d57611b9c611400565b5b8135611bad848260208601611b46565b91505092915050565b600060208284031215611bcc57611bcb6113f6565b5b600082013567ffffffffffffffff811115611bea57611be96113fb565b5b611bf684828501611b88565b91505092915050565b6000611c0b8385611890565b9350611c188385846114c7565b611c218361140a565b840190509392505050565b611c35816113b0565b82525050565b611c4481611adf565b82525050565b600082825260208201905092915050565b6000611c6682611885565b611c708185611c4a565b9350611c808185602086016118a1565b611c898161140a565b840191505092915050565b611c9d816116de565b82525050565b600060a083016000830151611cbb6000860182611c2c565b506020830151611cce6020860182611c3b565b506040830151611ce16040860182611c2c565b5060608301518482036060860152611cf98282611c5b565b9150506080830151611d0e6080860182611c94565b508091505092915050565b6000606082019050611d2e60008301876113c2565b8181036020830152611d41818587611bff565b90508181036040830152611d558184611ca3565b905095945050505050565b600081905092915050565b6000611d7682611885565b611d808185611d60565b9350611d908185602086016118a1565b80840191505092915050565b6000611da88284611d6b565b915081905092915050565b600081905092915050565b6000611dc982611953565b611dd38185611db3565b9350611de38185602086016118a1565b80840191505092915050565b6000611dfb8284611dbe565b915081905092915050565b6000604082019050611e1b60008301856113c2565b8181036020830152611e2d8184611ca3565b90509392505050565b60008160601b9050919050565b6000611e4e82611e36565b9050919050565b6000611e6082611e43565b9050919050565b611e78611e73826113b0565b611e55565b82525050565b6000611e8a8285611dbe565b9150611e968284611e67565b6014820191508190509392505050565b6000606082019050611ebb60008301866113c2565b611ec860208301856113c2565b611ed560408301846116e8565b949350505050565b611ee681611adf565b8114611ef157600080fd5b50565b600081519050611f0381611edd565b92915050565b600060208284031215611f1f57611f1e6113f6565b5b6000611f2d84828501611ef4565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112611f6257611f61611f36565b5b80840192508235915067ffffffffffffffff821115611f8457611f83611f3b565b5b602083019250600182023603831315611fa057611f9f611f40565b5b509250929050565b600081519050611fb78161158f565b92915050565b600081519050611fcc81611736565b92915050565b60008060408385031215611fe957611fe86113f6565b5b6000611ff785828601611fa8565b925050602061200885828601611fbd565b9150509250929050565b7f7a72633230206973206e6f742067617320746f6b656e00000000000000000000600082015250565b600061204860168361195e565b915061205382612012565b602082019050919050565b600060208201905081810360008301526120778161203b565b9050919050565b7f66656520616d6f756e7420697320686967686572207468616e2074686520616d60008201527f6f756e7400000000000000000000000000000000000000000000000000000000602082015250565b60006120da60248361195e565b91506120e58261207e565b604082019050919050565b60006020820190508181036000830152612109816120cd565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061214a826116de565b9150612155836116de565b925082820390508181111561216d5761216c612110565b5b92915050565b600060408201905061218860008301856113c2565b61219560208301846116e8565b9392505050565b600060808201905081810360008301526121b681876118cb565b90506121c560208301866116e8565b6121d260408301856113c2565b81810360608301526121e48184611ca3565b905095945050505050565b60006121fb8385611d60565b93506122088385846114c7565b82840190509392505050565b60006122218284866121ef565b91508190509392505050565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b6000612263600683611db3565b915061226e8261222d565b600682019050919050565b600061228482612256565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006122c8826116de565b91506122d3836116de565b9250826122e3576122e261228e565b5b828204905092915050565b7f7769746864726177000000000000000000000000000000000000000000000000600082015250565b6000612324600883611db3565b915061232f826122ee565b600882019050919050565b600061234582612317565b915081905091905056fea2646970667358221220cc1d392f0803f3c30b8da3699bebbbdf5e1711d9c77c2bd74f9a96c12336d8f564736f6c634300081a0033", + Bin: "0x60c060405234801561001057600080fd5b5060405161259438038061259483398181016040528101906100329190610114565b8115156080811515815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050610154565b600080fd5b60008115159050919050565b6100938161007e565b811461009e57600080fd5b50565b6000815190506100b08161008a565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100e1826100b6565b9050919050565b6100f1816100d6565b81146100fc57600080fd5b50565b60008151905061010e816100e8565b92915050565b6000806040838503121561012b5761012a610079565b5b6000610139858286016100a1565b925050602061014a858286016100ff565b9150509250929050565b60805160a0516123ea6101aa6000396000818161045b015281816104d40152818161084e015261104e0152600081816104a90152818161082301528181610b2001528181610fff015261102301526123ea6000f3fe60806040526004361061010d5760003560e01c8063ad23b28b11610095578063c91f356711610064578063c91f35671461035b578063deb3b1e414610386578063e2842ed7146103a2578063f592cbfb146103df578063f936ae851461041c57610114565b8063ad23b28b146102a1578063c7a339a9146102de578063c85f843414610307578063c9028a361461033257610114565b80635bcfd616116100dc5780635bcfd616146101d3578063676cc054146101fc5780639291fe261461022c5780639ca016ed14610269578063a799911f1461028557610114565b8063116191b61461011957806336e980a01461014457806341a3cd4a1461016d5780634297a2631461019657610114565b3661011457005b600080fd5b34801561012557600080fd5b5061012e610459565b60405161013b9190611436565b60405180910390f35b34801561015057600080fd5b5061016b600480360381019061016691906115ab565b61047d565b005b34801561017957600080fd5b50610194600480360381019061018f9190611680565b6104a7565b005b3480156101a257600080fd5b506101bd60048036038101906101b89190611716565b6105ce565b6040516101ca919061175c565b60405180910390f35b3480156101df57600080fd5b506101fa60048036038101906101f591906117c7565b6105e6565b005b6102166004803603810190610211919061188a565b6106cc565b6040516102239190611969565b60405180910390f35b34801561023857600080fd5b50610253600480360381019061024e91906115ab565b6107de565b604051610260919061175c565b60405180910390f35b610283600480360381019061027e919061198b565b610821565b005b61029f600480360381019061029a91906115ab565b610943565b005b3480156102ad57600080fd5b506102c860048036038101906102c3919061198b565b61096c565b6040516102d59190611a0d565b60405180910390f35b3480156102ea57600080fd5b5061030560048036038101906103009190611a6d565b6109cc565b005b34801561031357600080fd5b5061031c610a80565b6040516103299190611a0d565b60405180910390f35b34801561033e57600080fd5b5061035960048036038101906103549190611afb565b610ab9565b005b34801561036757600080fd5b50610370610ffd565b60405161037d9190611b5f565b60405180910390f35b6103a0600480360381019061039b9190611680565b611021565b005b3480156103ae57600080fd5b506103c960048036038101906103c49190611716565b611149565b6040516103d69190611b5f565b60405180910390f35b3480156103eb57600080fd5b50610406600480360381019061040191906115ab565b611169565b6040516104139190611b5f565b60405180910390f35b34801561042857600080fd5b50610443600480360381019061043e9190611c1b565b6111b9565b6040516104509190611436565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b61048681611202565b1561049057600080fd5b61049981611258565b6104a48160006112ac565b50565b7f0000000000000000000000000000000000000000000000000000000000000000156104d257600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631becceb48484846040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518563ffffffff1660e01b81526004016105979493929190611d7e565b600060405180830381600087803b1580156105b157600080fd5b505af11580156105c5573d6000803e3d6000fd5b50505050505050565b60036020528060005260406000206000915090505481565b61063382828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611202565b1561063d57600080fd5b60008083839050146106935782828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506106af565b6106ae8660200160208101906106a9919061198b565b61096c565b5b90506106ba81611258565b6106c481856112ac565b505050505050565b606060008084849050146107245783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610740565b61073f85600001602081019061073a919061198b565b61096c565b5b905061074b81611258565b61075581346112ac565b846000016020810190610768919061198b565b6002826040516107789190611e01565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550604051806020016040528060008152509150509392505050565b600060036000836040516020016107f59190611e54565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b7f00000000000000000000000000000000000000000000000000000000000000001561084c57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663726ac97c34836040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518463ffffffff1660e01b815260040161090e929190611e6b565b6000604051808303818588803b15801561092757600080fd5b505af115801561093b573d6000803e3d6000fd5b505050505050565b61094c81611202565b1561095657600080fd5b61095f81611258565b61096981346112ac565b50565b60606040518060400160405280601681526020017f63616c6c65642077697468206e6f206d65737361676500000000000000000000815250826040516020016109b6929190611ee3565b6040516020818303038152906040529050919050565b6109d581611202565b156109df57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401610a1c93929190611f0b565b6020604051808303816000875af1158015610a3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5f9190611f6e565b610a6857600080fd5b610a7181611258565b610a7b81836112ac565b505050565b6040518060400160405280601681526020017f63616c6c65642077697468206e6f206d6573736167650000000000000000000081525081565b610b14818060600190610acc9190611faa565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611202565b15610b1e57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000015610ec357610b4c6112ee565b610ba7818060600190610b5f9190611faa565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611361565b15610ec257600080826020016020810190610bc2919061198b565b73ffffffffffffffffffffffffffffffffffffffff1663d9eeebed6040518163ffffffff1660e01b81526004016040805180830381865afa158015610c0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2f9190612037565b91509150826020016020810190610c46919061198b565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610cb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610caa906120c3565b60405180910390fd5b8260400135811115610cfa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf190612155565b60405180910390fd5b6000818460400135610d0c91906121a4565b9050836020016020810190610d21919061198b565b73ffffffffffffffffffffffffffffffffffffffff1663095ea7b33386604001356040518363ffffffff1660e01b8152600401610d5f9291906121d8565b6020604051808303816000875af1158015610d7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da29190611f6e565b503373ffffffffffffffffffffffffffffffffffffffff16637c0dcb5f856000016020810190610dd2919061198b565b604051602001610de29190611436565b60405160208183030381529060405283876020016020810190610e05919061198b565b6040518060a00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518563ffffffff1660e01b8152600401610e8c9493929190612201565b600060405180830381600087803b158015610ea657600080fd5b505af1158015610eba573d6000803e3d6000fd5b505050505050505b5b610f1e818060600190610ed69190611faa565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611258565b610f7b818060600190610f319190611faa565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060006112ac565b806000016020810190610f8e919061198b565b6002828060600190610fa09190611faa565b604051610fae929190612279565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f00000000000000000000000000000000000000000000000000000000000000001561104c57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663744b9b8b348585856040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518663ffffffff1660e01b81526004016111129493929190611d7e565b6000604051808303818588803b15801561112b57600080fd5b505af115801561113f573d6000803e3d6000fd5b5050505050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b600060016000836040516020016111809190611e54565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b6002818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000604051602001611213906122de565b604051602081830303815290604052805190602001208260405160200161123a9190611e54565b60405160208183030381529060405280519060200120149050919050565b60018060008360405160200161126e9190611e54565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b8060036000846040516020016112c29190611e54565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b60006207a12090506000614e2090506000818361130b9190612322565b905060005b8181101561134e5760008190806001815401808255809150506001900390600052602060002001600090919091909150558080600101915050611310565b5060008061135c91906113b7565b505050565b60006040516020016113729061239f565b60405160208183030381529060405280519060200120826040516020016113999190611e54565b60405160208183030381529060405280519060200120149050919050565b50805460008255906000526020600020908101906113d591906113d8565b50565b5b808211156113f15760008160009055506001016113d9565b5090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611420826113f5565b9050919050565b61143081611415565b82525050565b600060208201905061144b6000830184611427565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6114b88261146f565b810181811067ffffffffffffffff821117156114d7576114d6611480565b5b80604052505050565b60006114ea611451565b90506114f682826114af565b919050565b600067ffffffffffffffff82111561151657611515611480565b5b61151f8261146f565b9050602081019050919050565b82818337600083830152505050565b600061154e611549846114fb565b6114e0565b90508281526020810184848401111561156a5761156961146a565b5b61157584828561152c565b509392505050565b600082601f83011261159257611591611465565b5b81356115a284826020860161153b565b91505092915050565b6000602082840312156115c1576115c061145b565b5b600082013567ffffffffffffffff8111156115df576115de611460565b5b6115eb8482850161157d565b91505092915050565b6115fd81611415565b811461160857600080fd5b50565b60008135905061161a816115f4565b92915050565b600080fd5b600080fd5b60008083601f8401126116405761163f611465565b5b8235905067ffffffffffffffff81111561165d5761165c611620565b5b60208301915083600182028301111561167957611678611625565b5b9250929050565b6000806000604084860312156116995761169861145b565b5b60006116a78682870161160b565b935050602084013567ffffffffffffffff8111156116c8576116c7611460565b5b6116d48682870161162a565b92509250509250925092565b6000819050919050565b6116f3816116e0565b81146116fe57600080fd5b50565b600081359050611710816116ea565b92915050565b60006020828403121561172c5761172b61145b565b5b600061173a84828501611701565b91505092915050565b6000819050919050565b61175681611743565b82525050565b6000602082019050611771600083018461174d565b92915050565b600080fd5b60006060828403121561179257611791611777565b5b81905092915050565b6117a481611743565b81146117af57600080fd5b50565b6000813590506117c18161179b565b92915050565b6000806000806000608086880312156117e3576117e261145b565b5b600086013567ffffffffffffffff81111561180157611800611460565b5b61180d8882890161177c565b955050602061181e8882890161160b565b945050604061182f888289016117b2565b935050606086013567ffffffffffffffff8111156118505761184f611460565b5b61185c8882890161162a565b92509250509295509295909350565b60006020828403121561188157611880611777565b5b81905092915050565b6000806000604084860312156118a3576118a261145b565b5b60006118b18682870161186b565b935050602084013567ffffffffffffffff8111156118d2576118d1611460565b5b6118de8682870161162a565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b60005b83811015611924578082015181840152602081019050611909565b60008484015250505050565b600061193b826118ea565b61194581856118f5565b9350611955818560208601611906565b61195e8161146f565b840191505092915050565b600060208201905081810360008301526119838184611930565b905092915050565b6000602082840312156119a1576119a061145b565b5b60006119af8482850161160b565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60006119df826119b8565b6119e981856119c3565b93506119f9818560208601611906565b611a028161146f565b840191505092915050565b60006020820190508181036000830152611a2781846119d4565b905092915050565b6000611a3a82611415565b9050919050565b611a4a81611a2f565b8114611a5557600080fd5b50565b600081359050611a6781611a41565b92915050565b600080600060608486031215611a8657611a8561145b565b5b6000611a9486828701611a58565b9350506020611aa5868287016117b2565b925050604084013567ffffffffffffffff811115611ac657611ac5611460565b5b611ad28682870161157d565b9150509250925092565b600060808284031215611af257611af1611777565b5b81905092915050565b600060208284031215611b1157611b1061145b565b5b600082013567ffffffffffffffff811115611b2f57611b2e611460565b5b611b3b84828501611adc565b91505092915050565b60008115159050919050565b611b5981611b44565b82525050565b6000602082019050611b746000830184611b50565b92915050565b600067ffffffffffffffff821115611b9557611b94611480565b5b611b9e8261146f565b9050602081019050919050565b6000611bbe611bb984611b7a565b6114e0565b905082815260208101848484011115611bda57611bd961146a565b5b611be584828561152c565b509392505050565b600082601f830112611c0257611c01611465565b5b8135611c12848260208601611bab565b91505092915050565b600060208284031215611c3157611c3061145b565b5b600082013567ffffffffffffffff811115611c4f57611c4e611460565b5b611c5b84828501611bed565b91505092915050565b6000611c7083856118f5565b9350611c7d83858461152c565b611c868361146f565b840190509392505050565b611c9a81611415565b82525050565b611ca981611b44565b82525050565b600082825260208201905092915050565b6000611ccb826118ea565b611cd58185611caf565b9350611ce5818560208601611906565b611cee8161146f565b840191505092915050565b611d0281611743565b82525050565b600060a083016000830151611d206000860182611c91565b506020830151611d336020860182611ca0565b506040830151611d466040860182611c91565b5060608301518482036060860152611d5e8282611cc0565b9150506080830151611d736080860182611cf9565b508091505092915050565b6000606082019050611d936000830187611427565b8181036020830152611da6818587611c64565b90508181036040830152611dba8184611d08565b905095945050505050565b600081905092915050565b6000611ddb826118ea565b611de58185611dc5565b9350611df5818560208601611906565b80840191505092915050565b6000611e0d8284611dd0565b915081905092915050565b600081905092915050565b6000611e2e826119b8565b611e388185611e18565b9350611e48818560208601611906565b80840191505092915050565b6000611e608284611e23565b915081905092915050565b6000604082019050611e806000830185611427565b8181036020830152611e928184611d08565b90509392505050565b60008160601b9050919050565b6000611eb382611e9b565b9050919050565b6000611ec582611ea8565b9050919050565b611edd611ed882611415565b611eba565b82525050565b6000611eef8285611e23565b9150611efb8284611ecc565b6014820191508190509392505050565b6000606082019050611f206000830186611427565b611f2d6020830185611427565b611f3a604083018461174d565b949350505050565b611f4b81611b44565b8114611f5657600080fd5b50565b600081519050611f6881611f42565b92915050565b600060208284031215611f8457611f8361145b565b5b6000611f9284828501611f59565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112611fc757611fc6611f9b565b5b80840192508235915067ffffffffffffffff821115611fe957611fe8611fa0565b5b60208301925060018202360383131561200557612004611fa5565b5b509250929050565b60008151905061201c816115f4565b92915050565b6000815190506120318161179b565b92915050565b6000806040838503121561204e5761204d61145b565b5b600061205c8582860161200d565b925050602061206d85828601612022565b9150509250929050565b7f7a72633230206973206e6f742067617320746f6b656e00000000000000000000600082015250565b60006120ad6016836119c3565b91506120b882612077565b602082019050919050565b600060208201905081810360008301526120dc816120a0565b9050919050565b7f66656520616d6f756e7420697320686967686572207468616e2074686520616d60008201527f6f756e7400000000000000000000000000000000000000000000000000000000602082015250565b600061213f6024836119c3565b915061214a826120e3565b604082019050919050565b6000602082019050818103600083015261216e81612132565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006121af82611743565b91506121ba83611743565b92508282039050818111156121d2576121d1612175565b5b92915050565b60006040820190506121ed6000830185611427565b6121fa602083018461174d565b9392505050565b6000608082019050818103600083015261221b8187611930565b905061222a602083018661174d565b6122376040830185611427565b81810360608301526122498184611d08565b905095945050505050565b60006122608385611dc5565b935061226d83858461152c565b82840190509392505050565b6000612286828486612254565b91508190509392505050565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b60006122c8600683611e18565b91506122d382612292565b600682019050919050565b60006122e9826122bb565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061232d82611743565b915061233883611743565b925082612348576123476122f3565b5b828204905092915050565b7f7769746864726177000000000000000000000000000000000000000000000000600082015250565b6000612389600883611e18565b915061239482612353565b600882019050919050565b60006123aa8261237c565b915081905091905056fea2646970667358221220e0e7dfdd94bdbc9796b718d6cbbf5d94e34a34e70ed21a1f60997215fbaed17964736f6c634300081a0033", } // TestDAppV2ABI is the input ABI used to generate the binding from. diff --git a/pkg/contracts/testdappv2/TestDAppV2.json b/pkg/contracts/testdappv2/TestDAppV2.json index 97604c40a9..8b27abc4b5 100644 --- a/pkg/contracts/testdappv2/TestDAppV2.json +++ b/pkg/contracts/testdappv2/TestDAppV2.json @@ -383,5 +383,5 @@ "type": "receive" } ], - "bin": "60c060405234801561001057600080fd5b5060405161252f38038061252f83398181016040528101906100329190610114565b8115156080811515815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050610154565b600080fd5b60008115159050919050565b6100938161007e565b811461009e57600080fd5b50565b6000815190506100b08161008a565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100e1826100b6565b9050919050565b6100f1816100d6565b81146100fc57600080fd5b50565b60008151905061010e816100e8565b92915050565b6000806040838503121561012b5761012a610079565b5b6000610139858286016100a1565b925050602061014a858286016100ff565b9150509250929050565b60805160a0516123856101aa6000396000818161045b015281816104d40152818161084e0152610fe90152600081816104a90152818161082301528181610abb01528181610f9a0152610fbe01526123856000f3fe60806040526004361061010d5760003560e01c8063ad23b28b11610095578063c91f356711610064578063c91f35671461035b578063deb3b1e414610386578063e2842ed7146103a2578063f592cbfb146103df578063f936ae851461041c57610114565b8063ad23b28b146102a1578063c7a339a9146102de578063c85f843414610307578063c9028a361461033257610114565b80635bcfd616116100dc5780635bcfd616146101d3578063676cc054146101fc5780639291fe261461022c5780639ca016ed14610269578063a799911f1461028557610114565b8063116191b61461011957806336e980a01461014457806341a3cd4a1461016d5780634297a2631461019657610114565b3661011457005b600080fd5b34801561012557600080fd5b5061012e610459565b60405161013b91906113d1565b60405180910390f35b34801561015057600080fd5b5061016b60048036038101906101669190611546565b61047d565b005b34801561017957600080fd5b50610194600480360381019061018f919061161b565b6104a7565b005b3480156101a257600080fd5b506101bd60048036038101906101b891906116b1565b6105ce565b6040516101ca91906116f7565b60405180910390f35b3480156101df57600080fd5b506101fa60048036038101906101f59190611762565b6105e6565b005b61021660048036038101906102119190611825565b6106cc565b6040516102239190611904565b60405180910390f35b34801561023857600080fd5b50610253600480360381019061024e9190611546565b6107de565b60405161026091906116f7565b60405180910390f35b610283600480360381019061027e9190611926565b610821565b005b61029f600480360381019061029a9190611546565b610943565b005b3480156102ad57600080fd5b506102c860048036038101906102c39190611926565b61096c565b6040516102d591906119a8565b60405180910390f35b3480156102ea57600080fd5b5061030560048036038101906103009190611a08565b6109cc565b005b34801561031357600080fd5b5061031c610a80565b60405161032991906119a8565b60405180910390f35b34801561033e57600080fd5b5061035960048036038101906103549190611a96565b610ab9565b005b34801561036757600080fd5b50610370610f98565b60405161037d9190611afa565b60405180910390f35b6103a0600480360381019061039b919061161b565b610fbc565b005b3480156103ae57600080fd5b506103c960048036038101906103c491906116b1565b6110e4565b6040516103d69190611afa565b60405180910390f35b3480156103eb57600080fd5b5061040660048036038101906104019190611546565b611104565b6040516104139190611afa565b60405180910390f35b34801561042857600080fd5b50610443600480360381019061043e9190611bb6565b611154565b60405161045091906113d1565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b6104868161119d565b1561049057600080fd5b610499816111f3565b6104a4816000611247565b50565b7f0000000000000000000000000000000000000000000000000000000000000000156104d257600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631becceb48484846040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518563ffffffff1660e01b81526004016105979493929190611d19565b600060405180830381600087803b1580156105b157600080fd5b505af11580156105c5573d6000803e3d6000fd5b50505050505050565b60036020528060005260406000206000915090505481565b61063382828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061119d565b1561063d57600080fd5b60008083839050146106935782828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506106af565b6106ae8660200160208101906106a99190611926565b61096c565b5b90506106ba816111f3565b6106c48185611247565b505050505050565b606060008084849050146107245783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610740565b61073f85600001602081019061073a9190611926565b61096c565b5b905061074b816111f3565b6107558134611247565b8460000160208101906107689190611926565b6002826040516107789190611d9c565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550604051806020016040528060008152509150509392505050565b600060036000836040516020016107f59190611def565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b7f00000000000000000000000000000000000000000000000000000000000000001561084c57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663726ac97c34836040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518463ffffffff1660e01b815260040161090e929190611e06565b6000604051808303818588803b15801561092757600080fd5b505af115801561093b573d6000803e3d6000fd5b505050505050565b61094c8161119d565b1561095657600080fd5b61095f816111f3565b6109698134611247565b50565b60606040518060400160405280601681526020017f63616c6c65642077697468206e6f206d65737361676500000000000000000000815250826040516020016109b6929190611e7e565b6040516020818303038152906040529050919050565b6109d58161119d565b156109df57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401610a1c93929190611ea6565b6020604051808303816000875af1158015610a3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5f9190611f09565b610a6857600080fd5b610a71816111f3565b610a7b8183611247565b505050565b6040518060400160405280601681526020017f63616c6c65642077697468206e6f206d6573736167650000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000015610e5e57610ae7611289565b610b42818060600190610afa9190611f45565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506112fc565b15610e5d57600080826020016020810190610b5d9190611926565b73ffffffffffffffffffffffffffffffffffffffff1663d9eeebed6040518163ffffffff1660e01b81526004016040805180830381865afa158015610ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bca9190611fd2565b91509150826020016020810190610be19190611926565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610c4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c459061205e565b60405180910390fd5b8260400135811115610c95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8c906120f0565b60405180910390fd5b6000818460400135610ca7919061213f565b9050836020016020810190610cbc9190611926565b73ffffffffffffffffffffffffffffffffffffffff1663095ea7b33386604001356040518363ffffffff1660e01b8152600401610cfa929190612173565b6020604051808303816000875af1158015610d19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3d9190611f09565b503373ffffffffffffffffffffffffffffffffffffffff16637c0dcb5f856000016020810190610d6d9190611926565b604051602001610d7d91906113d1565b60405160208183030381529060405283876020016020810190610da09190611926565b6040518060a00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518563ffffffff1660e01b8152600401610e27949392919061219c565b600060405180830381600087803b158015610e4157600080fd5b505af1158015610e55573d6000803e3d6000fd5b505050505050505b5b610eb9818060600190610e719190611f45565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506111f3565b610f16818060600190610ecc9190611f45565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506000611247565b806000016020810190610f299190611926565b6002828060600190610f3b9190611f45565b604051610f49929190612214565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000015610fe757600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663744b9b8b348585856040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518663ffffffff1660e01b81526004016110ad9493929190611d19565b6000604051808303818588803b1580156110c657600080fd5b505af11580156110da573d6000803e3d6000fd5b5050505050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b6000600160008360405160200161111b9190611def565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b6002818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040516020016111ae90612279565b60405160208183030381529060405280519060200120826040516020016111d59190611def565b60405160208183030381529060405280519060200120149050919050565b6001806000836040516020016112099190611def565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b80600360008460405160200161125d9190611def565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b60006207a12090506000614e209050600081836112a691906122bd565b905060005b818110156112e957600081908060018154018082558091505060019003906000526020600020016000909190919091505580806001019150506112ab565b506000806112f79190611352565b505050565b600060405160200161130d9061233a565b60405160208183030381529060405280519060200120826040516020016113349190611def565b60405160208183030381529060405280519060200120149050919050565b50805460008255906000526020600020908101906113709190611373565b50565b5b8082111561138c576000816000905550600101611374565b5090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006113bb82611390565b9050919050565b6113cb816113b0565b82525050565b60006020820190506113e660008301846113c2565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6114538261140a565b810181811067ffffffffffffffff821117156114725761147161141b565b5b80604052505050565b60006114856113ec565b9050611491828261144a565b919050565b600067ffffffffffffffff8211156114b1576114b061141b565b5b6114ba8261140a565b9050602081019050919050565b82818337600083830152505050565b60006114e96114e484611496565b61147b565b90508281526020810184848401111561150557611504611405565b5b6115108482856114c7565b509392505050565b600082601f83011261152d5761152c611400565b5b813561153d8482602086016114d6565b91505092915050565b60006020828403121561155c5761155b6113f6565b5b600082013567ffffffffffffffff81111561157a576115796113fb565b5b61158684828501611518565b91505092915050565b611598816113b0565b81146115a357600080fd5b50565b6000813590506115b58161158f565b92915050565b600080fd5b600080fd5b60008083601f8401126115db576115da611400565b5b8235905067ffffffffffffffff8111156115f8576115f76115bb565b5b602083019150836001820283011115611614576116136115c0565b5b9250929050565b600080600060408486031215611634576116336113f6565b5b6000611642868287016115a6565b935050602084013567ffffffffffffffff811115611663576116626113fb565b5b61166f868287016115c5565b92509250509250925092565b6000819050919050565b61168e8161167b565b811461169957600080fd5b50565b6000813590506116ab81611685565b92915050565b6000602082840312156116c7576116c66113f6565b5b60006116d58482850161169c565b91505092915050565b6000819050919050565b6116f1816116de565b82525050565b600060208201905061170c60008301846116e8565b92915050565b600080fd5b60006060828403121561172d5761172c611712565b5b81905092915050565b61173f816116de565b811461174a57600080fd5b50565b60008135905061175c81611736565b92915050565b60008060008060006080868803121561177e5761177d6113f6565b5b600086013567ffffffffffffffff81111561179c5761179b6113fb565b5b6117a888828901611717565b95505060206117b9888289016115a6565b94505060406117ca8882890161174d565b935050606086013567ffffffffffffffff8111156117eb576117ea6113fb565b5b6117f7888289016115c5565b92509250509295509295909350565b60006020828403121561181c5761181b611712565b5b81905092915050565b60008060006040848603121561183e5761183d6113f6565b5b600061184c86828701611806565b935050602084013567ffffffffffffffff81111561186d5761186c6113fb565b5b611879868287016115c5565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b60005b838110156118bf5780820151818401526020810190506118a4565b60008484015250505050565b60006118d682611885565b6118e08185611890565b93506118f08185602086016118a1565b6118f98161140a565b840191505092915050565b6000602082019050818103600083015261191e81846118cb565b905092915050565b60006020828403121561193c5761193b6113f6565b5b600061194a848285016115a6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b600061197a82611953565b611984818561195e565b93506119948185602086016118a1565b61199d8161140a565b840191505092915050565b600060208201905081810360008301526119c2818461196f565b905092915050565b60006119d5826113b0565b9050919050565b6119e5816119ca565b81146119f057600080fd5b50565b600081359050611a02816119dc565b92915050565b600080600060608486031215611a2157611a206113f6565b5b6000611a2f868287016119f3565b9350506020611a408682870161174d565b925050604084013567ffffffffffffffff811115611a6157611a606113fb565b5b611a6d86828701611518565b9150509250925092565b600060808284031215611a8d57611a8c611712565b5b81905092915050565b600060208284031215611aac57611aab6113f6565b5b600082013567ffffffffffffffff811115611aca57611ac96113fb565b5b611ad684828501611a77565b91505092915050565b60008115159050919050565b611af481611adf565b82525050565b6000602082019050611b0f6000830184611aeb565b92915050565b600067ffffffffffffffff821115611b3057611b2f61141b565b5b611b398261140a565b9050602081019050919050565b6000611b59611b5484611b15565b61147b565b905082815260208101848484011115611b7557611b74611405565b5b611b808482856114c7565b509392505050565b600082601f830112611b9d57611b9c611400565b5b8135611bad848260208601611b46565b91505092915050565b600060208284031215611bcc57611bcb6113f6565b5b600082013567ffffffffffffffff811115611bea57611be96113fb565b5b611bf684828501611b88565b91505092915050565b6000611c0b8385611890565b9350611c188385846114c7565b611c218361140a565b840190509392505050565b611c35816113b0565b82525050565b611c4481611adf565b82525050565b600082825260208201905092915050565b6000611c6682611885565b611c708185611c4a565b9350611c808185602086016118a1565b611c898161140a565b840191505092915050565b611c9d816116de565b82525050565b600060a083016000830151611cbb6000860182611c2c565b506020830151611cce6020860182611c3b565b506040830151611ce16040860182611c2c565b5060608301518482036060860152611cf98282611c5b565b9150506080830151611d0e6080860182611c94565b508091505092915050565b6000606082019050611d2e60008301876113c2565b8181036020830152611d41818587611bff565b90508181036040830152611d558184611ca3565b905095945050505050565b600081905092915050565b6000611d7682611885565b611d808185611d60565b9350611d908185602086016118a1565b80840191505092915050565b6000611da88284611d6b565b915081905092915050565b600081905092915050565b6000611dc982611953565b611dd38185611db3565b9350611de38185602086016118a1565b80840191505092915050565b6000611dfb8284611dbe565b915081905092915050565b6000604082019050611e1b60008301856113c2565b8181036020830152611e2d8184611ca3565b90509392505050565b60008160601b9050919050565b6000611e4e82611e36565b9050919050565b6000611e6082611e43565b9050919050565b611e78611e73826113b0565b611e55565b82525050565b6000611e8a8285611dbe565b9150611e968284611e67565b6014820191508190509392505050565b6000606082019050611ebb60008301866113c2565b611ec860208301856113c2565b611ed560408301846116e8565b949350505050565b611ee681611adf565b8114611ef157600080fd5b50565b600081519050611f0381611edd565b92915050565b600060208284031215611f1f57611f1e6113f6565b5b6000611f2d84828501611ef4565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112611f6257611f61611f36565b5b80840192508235915067ffffffffffffffff821115611f8457611f83611f3b565b5b602083019250600182023603831315611fa057611f9f611f40565b5b509250929050565b600081519050611fb78161158f565b92915050565b600081519050611fcc81611736565b92915050565b60008060408385031215611fe957611fe86113f6565b5b6000611ff785828601611fa8565b925050602061200885828601611fbd565b9150509250929050565b7f7a72633230206973206e6f742067617320746f6b656e00000000000000000000600082015250565b600061204860168361195e565b915061205382612012565b602082019050919050565b600060208201905081810360008301526120778161203b565b9050919050565b7f66656520616d6f756e7420697320686967686572207468616e2074686520616d60008201527f6f756e7400000000000000000000000000000000000000000000000000000000602082015250565b60006120da60248361195e565b91506120e58261207e565b604082019050919050565b60006020820190508181036000830152612109816120cd565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061214a826116de565b9150612155836116de565b925082820390508181111561216d5761216c612110565b5b92915050565b600060408201905061218860008301856113c2565b61219560208301846116e8565b9392505050565b600060808201905081810360008301526121b681876118cb565b90506121c560208301866116e8565b6121d260408301856113c2565b81810360608301526121e48184611ca3565b905095945050505050565b60006121fb8385611d60565b93506122088385846114c7565b82840190509392505050565b60006122218284866121ef565b91508190509392505050565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b6000612263600683611db3565b915061226e8261222d565b600682019050919050565b600061228482612256565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006122c8826116de565b91506122d3836116de565b9250826122e3576122e261228e565b5b828204905092915050565b7f7769746864726177000000000000000000000000000000000000000000000000600082015250565b6000612324600883611db3565b915061232f826122ee565b600882019050919050565b600061234582612317565b915081905091905056fea2646970667358221220cc1d392f0803f3c30b8da3699bebbbdf5e1711d9c77c2bd74f9a96c12336d8f564736f6c634300081a0033" + "bin": "60c060405234801561001057600080fd5b5060405161259438038061259483398181016040528101906100329190610114565b8115156080811515815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050610154565b600080fd5b60008115159050919050565b6100938161007e565b811461009e57600080fd5b50565b6000815190506100b08161008a565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100e1826100b6565b9050919050565b6100f1816100d6565b81146100fc57600080fd5b50565b60008151905061010e816100e8565b92915050565b6000806040838503121561012b5761012a610079565b5b6000610139858286016100a1565b925050602061014a858286016100ff565b9150509250929050565b60805160a0516123ea6101aa6000396000818161045b015281816104d40152818161084e015261104e0152600081816104a90152818161082301528181610b2001528181610fff015261102301526123ea6000f3fe60806040526004361061010d5760003560e01c8063ad23b28b11610095578063c91f356711610064578063c91f35671461035b578063deb3b1e414610386578063e2842ed7146103a2578063f592cbfb146103df578063f936ae851461041c57610114565b8063ad23b28b146102a1578063c7a339a9146102de578063c85f843414610307578063c9028a361461033257610114565b80635bcfd616116100dc5780635bcfd616146101d3578063676cc054146101fc5780639291fe261461022c5780639ca016ed14610269578063a799911f1461028557610114565b8063116191b61461011957806336e980a01461014457806341a3cd4a1461016d5780634297a2631461019657610114565b3661011457005b600080fd5b34801561012557600080fd5b5061012e610459565b60405161013b9190611436565b60405180910390f35b34801561015057600080fd5b5061016b600480360381019061016691906115ab565b61047d565b005b34801561017957600080fd5b50610194600480360381019061018f9190611680565b6104a7565b005b3480156101a257600080fd5b506101bd60048036038101906101b89190611716565b6105ce565b6040516101ca919061175c565b60405180910390f35b3480156101df57600080fd5b506101fa60048036038101906101f591906117c7565b6105e6565b005b6102166004803603810190610211919061188a565b6106cc565b6040516102239190611969565b60405180910390f35b34801561023857600080fd5b50610253600480360381019061024e91906115ab565b6107de565b604051610260919061175c565b60405180910390f35b610283600480360381019061027e919061198b565b610821565b005b61029f600480360381019061029a91906115ab565b610943565b005b3480156102ad57600080fd5b506102c860048036038101906102c3919061198b565b61096c565b6040516102d59190611a0d565b60405180910390f35b3480156102ea57600080fd5b5061030560048036038101906103009190611a6d565b6109cc565b005b34801561031357600080fd5b5061031c610a80565b6040516103299190611a0d565b60405180910390f35b34801561033e57600080fd5b5061035960048036038101906103549190611afb565b610ab9565b005b34801561036757600080fd5b50610370610ffd565b60405161037d9190611b5f565b60405180910390f35b6103a0600480360381019061039b9190611680565b611021565b005b3480156103ae57600080fd5b506103c960048036038101906103c49190611716565b611149565b6040516103d69190611b5f565b60405180910390f35b3480156103eb57600080fd5b50610406600480360381019061040191906115ab565b611169565b6040516104139190611b5f565b60405180910390f35b34801561042857600080fd5b50610443600480360381019061043e9190611c1b565b6111b9565b6040516104509190611436565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b61048681611202565b1561049057600080fd5b61049981611258565b6104a48160006112ac565b50565b7f0000000000000000000000000000000000000000000000000000000000000000156104d257600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631becceb48484846040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518563ffffffff1660e01b81526004016105979493929190611d7e565b600060405180830381600087803b1580156105b157600080fd5b505af11580156105c5573d6000803e3d6000fd5b50505050505050565b60036020528060005260406000206000915090505481565b61063382828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611202565b1561063d57600080fd5b60008083839050146106935782828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506106af565b6106ae8660200160208101906106a9919061198b565b61096c565b5b90506106ba81611258565b6106c481856112ac565b505050505050565b606060008084849050146107245783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610740565b61073f85600001602081019061073a919061198b565b61096c565b5b905061074b81611258565b61075581346112ac565b846000016020810190610768919061198b565b6002826040516107789190611e01565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550604051806020016040528060008152509150509392505050565b600060036000836040516020016107f59190611e54565b604051602081830303815290604052805190602001208152602001908152602001600020549050919050565b7f00000000000000000000000000000000000000000000000000000000000000001561084c57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663726ac97c34836040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518463ffffffff1660e01b815260040161090e929190611e6b565b6000604051808303818588803b15801561092757600080fd5b505af115801561093b573d6000803e3d6000fd5b505050505050565b61094c81611202565b1561095657600080fd5b61095f81611258565b61096981346112ac565b50565b60606040518060400160405280601681526020017f63616c6c65642077697468206e6f206d65737361676500000000000000000000815250826040516020016109b6929190611ee3565b6040516020818303038152906040529050919050565b6109d581611202565b156109df57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401610a1c93929190611f0b565b6020604051808303816000875af1158015610a3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5f9190611f6e565b610a6857600080fd5b610a7181611258565b610a7b81836112ac565b505050565b6040518060400160405280601681526020017f63616c6c65642077697468206e6f206d6573736167650000000000000000000081525081565b610b14818060600190610acc9190611faa565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611202565b15610b1e57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000015610ec357610b4c6112ee565b610ba7818060600190610b5f9190611faa565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611361565b15610ec257600080826020016020810190610bc2919061198b565b73ffffffffffffffffffffffffffffffffffffffff1663d9eeebed6040518163ffffffff1660e01b81526004016040805180830381865afa158015610c0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2f9190612037565b91509150826020016020810190610c46919061198b565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610cb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610caa906120c3565b60405180910390fd5b8260400135811115610cfa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf190612155565b60405180910390fd5b6000818460400135610d0c91906121a4565b9050836020016020810190610d21919061198b565b73ffffffffffffffffffffffffffffffffffffffff1663095ea7b33386604001356040518363ffffffff1660e01b8152600401610d5f9291906121d8565b6020604051808303816000875af1158015610d7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da29190611f6e565b503373ffffffffffffffffffffffffffffffffffffffff16637c0dcb5f856000016020810190610dd2919061198b565b604051602001610de29190611436565b60405160208183030381529060405283876020016020810190610e05919061198b565b6040518060a00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518563ffffffff1660e01b8152600401610e8c9493929190612201565b600060405180830381600087803b158015610ea657600080fd5b505af1158015610eba573d6000803e3d6000fd5b505050505050505b5b610f1e818060600190610ed69190611faa565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611258565b610f7b818060600190610f319190611faa565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060006112ac565b806000016020810190610f8e919061198b565b6002828060600190610fa09190611faa565b604051610fae929190612279565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f00000000000000000000000000000000000000000000000000000000000000001561104c57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663744b9b8b348585856040518060a001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160405180602001604052806000815250815260200160008152506040518663ffffffff1660e01b81526004016111129493929190611d7e565b6000604051808303818588803b15801561112b57600080fd5b505af115801561113f573d6000803e3d6000fd5b5050505050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b600060016000836040516020016111809190611e54565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900460ff169050919050565b6002818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000604051602001611213906122de565b604051602081830303815290604052805190602001208260405160200161123a9190611e54565b60405160208183030381529060405280519060200120149050919050565b60018060008360405160200161126e9190611e54565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b8060036000846040516020016112c29190611e54565b604051602081830303815290604052805190602001208152602001908152602001600020819055505050565b60006207a12090506000614e2090506000818361130b9190612322565b905060005b8181101561134e5760008190806001815401808255809150506001900390600052602060002001600090919091909150558080600101915050611310565b5060008061135c91906113b7565b505050565b60006040516020016113729061239f565b60405160208183030381529060405280519060200120826040516020016113999190611e54565b60405160208183030381529060405280519060200120149050919050565b50805460008255906000526020600020908101906113d591906113d8565b50565b5b808211156113f15760008160009055506001016113d9565b5090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611420826113f5565b9050919050565b61143081611415565b82525050565b600060208201905061144b6000830184611427565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6114b88261146f565b810181811067ffffffffffffffff821117156114d7576114d6611480565b5b80604052505050565b60006114ea611451565b90506114f682826114af565b919050565b600067ffffffffffffffff82111561151657611515611480565b5b61151f8261146f565b9050602081019050919050565b82818337600083830152505050565b600061154e611549846114fb565b6114e0565b90508281526020810184848401111561156a5761156961146a565b5b61157584828561152c565b509392505050565b600082601f83011261159257611591611465565b5b81356115a284826020860161153b565b91505092915050565b6000602082840312156115c1576115c061145b565b5b600082013567ffffffffffffffff8111156115df576115de611460565b5b6115eb8482850161157d565b91505092915050565b6115fd81611415565b811461160857600080fd5b50565b60008135905061161a816115f4565b92915050565b600080fd5b600080fd5b60008083601f8401126116405761163f611465565b5b8235905067ffffffffffffffff81111561165d5761165c611620565b5b60208301915083600182028301111561167957611678611625565b5b9250929050565b6000806000604084860312156116995761169861145b565b5b60006116a78682870161160b565b935050602084013567ffffffffffffffff8111156116c8576116c7611460565b5b6116d48682870161162a565b92509250509250925092565b6000819050919050565b6116f3816116e0565b81146116fe57600080fd5b50565b600081359050611710816116ea565b92915050565b60006020828403121561172c5761172b61145b565b5b600061173a84828501611701565b91505092915050565b6000819050919050565b61175681611743565b82525050565b6000602082019050611771600083018461174d565b92915050565b600080fd5b60006060828403121561179257611791611777565b5b81905092915050565b6117a481611743565b81146117af57600080fd5b50565b6000813590506117c18161179b565b92915050565b6000806000806000608086880312156117e3576117e261145b565b5b600086013567ffffffffffffffff81111561180157611800611460565b5b61180d8882890161177c565b955050602061181e8882890161160b565b945050604061182f888289016117b2565b935050606086013567ffffffffffffffff8111156118505761184f611460565b5b61185c8882890161162a565b92509250509295509295909350565b60006020828403121561188157611880611777565b5b81905092915050565b6000806000604084860312156118a3576118a261145b565b5b60006118b18682870161186b565b935050602084013567ffffffffffffffff8111156118d2576118d1611460565b5b6118de8682870161162a565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b60005b83811015611924578082015181840152602081019050611909565b60008484015250505050565b600061193b826118ea565b61194581856118f5565b9350611955818560208601611906565b61195e8161146f565b840191505092915050565b600060208201905081810360008301526119838184611930565b905092915050565b6000602082840312156119a1576119a061145b565b5b60006119af8482850161160b565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60006119df826119b8565b6119e981856119c3565b93506119f9818560208601611906565b611a028161146f565b840191505092915050565b60006020820190508181036000830152611a2781846119d4565b905092915050565b6000611a3a82611415565b9050919050565b611a4a81611a2f565b8114611a5557600080fd5b50565b600081359050611a6781611a41565b92915050565b600080600060608486031215611a8657611a8561145b565b5b6000611a9486828701611a58565b9350506020611aa5868287016117b2565b925050604084013567ffffffffffffffff811115611ac657611ac5611460565b5b611ad28682870161157d565b9150509250925092565b600060808284031215611af257611af1611777565b5b81905092915050565b600060208284031215611b1157611b1061145b565b5b600082013567ffffffffffffffff811115611b2f57611b2e611460565b5b611b3b84828501611adc565b91505092915050565b60008115159050919050565b611b5981611b44565b82525050565b6000602082019050611b746000830184611b50565b92915050565b600067ffffffffffffffff821115611b9557611b94611480565b5b611b9e8261146f565b9050602081019050919050565b6000611bbe611bb984611b7a565b6114e0565b905082815260208101848484011115611bda57611bd961146a565b5b611be584828561152c565b509392505050565b600082601f830112611c0257611c01611465565b5b8135611c12848260208601611bab565b91505092915050565b600060208284031215611c3157611c3061145b565b5b600082013567ffffffffffffffff811115611c4f57611c4e611460565b5b611c5b84828501611bed565b91505092915050565b6000611c7083856118f5565b9350611c7d83858461152c565b611c868361146f565b840190509392505050565b611c9a81611415565b82525050565b611ca981611b44565b82525050565b600082825260208201905092915050565b6000611ccb826118ea565b611cd58185611caf565b9350611ce5818560208601611906565b611cee8161146f565b840191505092915050565b611d0281611743565b82525050565b600060a083016000830151611d206000860182611c91565b506020830151611d336020860182611ca0565b506040830151611d466040860182611c91565b5060608301518482036060860152611d5e8282611cc0565b9150506080830151611d736080860182611cf9565b508091505092915050565b6000606082019050611d936000830187611427565b8181036020830152611da6818587611c64565b90508181036040830152611dba8184611d08565b905095945050505050565b600081905092915050565b6000611ddb826118ea565b611de58185611dc5565b9350611df5818560208601611906565b80840191505092915050565b6000611e0d8284611dd0565b915081905092915050565b600081905092915050565b6000611e2e826119b8565b611e388185611e18565b9350611e48818560208601611906565b80840191505092915050565b6000611e608284611e23565b915081905092915050565b6000604082019050611e806000830185611427565b8181036020830152611e928184611d08565b90509392505050565b60008160601b9050919050565b6000611eb382611e9b565b9050919050565b6000611ec582611ea8565b9050919050565b611edd611ed882611415565b611eba565b82525050565b6000611eef8285611e23565b9150611efb8284611ecc565b6014820191508190509392505050565b6000606082019050611f206000830186611427565b611f2d6020830185611427565b611f3a604083018461174d565b949350505050565b611f4b81611b44565b8114611f5657600080fd5b50565b600081519050611f6881611f42565b92915050565b600060208284031215611f8457611f8361145b565b5b6000611f9284828501611f59565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112611fc757611fc6611f9b565b5b80840192508235915067ffffffffffffffff821115611fe957611fe8611fa0565b5b60208301925060018202360383131561200557612004611fa5565b5b509250929050565b60008151905061201c816115f4565b92915050565b6000815190506120318161179b565b92915050565b6000806040838503121561204e5761204d61145b565b5b600061205c8582860161200d565b925050602061206d85828601612022565b9150509250929050565b7f7a72633230206973206e6f742067617320746f6b656e00000000000000000000600082015250565b60006120ad6016836119c3565b91506120b882612077565b602082019050919050565b600060208201905081810360008301526120dc816120a0565b9050919050565b7f66656520616d6f756e7420697320686967686572207468616e2074686520616d60008201527f6f756e7400000000000000000000000000000000000000000000000000000000602082015250565b600061213f6024836119c3565b915061214a826120e3565b604082019050919050565b6000602082019050818103600083015261216e81612132565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006121af82611743565b91506121ba83611743565b92508282039050818111156121d2576121d1612175565b5b92915050565b60006040820190506121ed6000830185611427565b6121fa602083018461174d565b9392505050565b6000608082019050818103600083015261221b8187611930565b905061222a602083018661174d565b6122376040830185611427565b81810360608301526122498184611d08565b905095945050505050565b60006122608385611dc5565b935061226d83858461152c565b82840190509392505050565b6000612286828486612254565b91508190509392505050565b7f7265766572740000000000000000000000000000000000000000000000000000600082015250565b60006122c8600683611e18565b91506122d382612292565b600682019050919050565b60006122e9826122bb565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061232d82611743565b915061233883611743565b925082612348576123476122f3565b5b828204905092915050565b7f7769746864726177000000000000000000000000000000000000000000000000600082015250565b6000612389600883611e18565b915061239482612353565b600882019050919050565b60006123aa8261237c565b915081905091905056fea2646970667358221220e0e7dfdd94bdbc9796b718d6cbbf5d94e34a34e70ed21a1f60997215fbaed17964736f6c634300081a0033" } diff --git a/pkg/contracts/testdappv2/TestDAppV2.sol b/pkg/contracts/testdappv2/TestDAppV2.sol index 40652c41e3..46667d1479 100644 --- a/pkg/contracts/testdappv2/TestDAppV2.sol +++ b/pkg/contracts/testdappv2/TestDAppV2.sol @@ -167,6 +167,7 @@ contract TestDAppV2 { // Revertable interface function onRevert(RevertContext calldata revertContext) external { + require(!isRevertMessage(string(revertContext.revertMessage))); // if the chain is ZetaChain, consume gas to test the gas consumption // we do it specifically for ZetaChain to test the outbound processing workflow diff --git a/proto/zetachain/zetacore/crosschain/cross_chain_tx.proto b/proto/zetachain/zetacore/crosschain/cross_chain_tx.proto index 04bf9c8301..23ec6abc0f 100644 --- a/proto/zetachain/zetacore/crosschain/cross_chain_tx.proto +++ b/proto/zetachain/zetacore/crosschain/cross_chain_tx.proto @@ -141,6 +141,8 @@ message Status { // error_message_revert carries information about the revert outbound tx , // which is created if the first outbound tx fails string error_message_revert = 7; + // error_message_abort carries information when aborting the CCTX fails + string error_message_abort = 8; } // ProtocolContractVersion represents the version of the protocol contract used diff --git a/testutil/keeper/crosschain.go b/testutil/keeper/crosschain.go index 2281e47291..151c7aa6ca 100644 --- a/testutil/keeper/crosschain.go +++ b/testutil/keeper/crosschain.go @@ -319,7 +319,7 @@ func MockProcessV2RevertDeposit( // callOnRevert bool // revertMessage []byte m.On( - "ProcessV2RevertDeposit", + "ProcessRevert", mock.Anything, mock.Anything, mock.Anything, diff --git a/testutil/keeper/mocks/crosschain/fungible.go b/testutil/keeper/mocks/crosschain/fungible.go index cec3fcf6a2..e4f39ee8f9 100644 --- a/testutil/keeper/mocks/crosschain/fungible.go +++ b/testutil/keeper/mocks/crosschain/fungible.go @@ -420,12 +420,42 @@ func (_m *CrosschainFungibleKeeper) GetUniswapV2Router02Address(ctx types.Contex return r0, r1 } -// 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) (*evmtypes.MsgEthereumTxResponse, error) { +// ProcessAbort provides a mock function with given fields: ctx, inboundSender, amount, outgoing, chainID, coinType, asset, abortAddress, revertMessage +func (_m *CrosschainFungibleKeeper) ProcessAbort(ctx types.Context, inboundSender string, amount *big.Int, outgoing bool, chainID int64, coinType coin.CoinType, asset string, abortAddress common.Address, revertMessage []byte) (*evmtypes.MsgEthereumTxResponse, error) { + ret := _m.Called(ctx, inboundSender, amount, outgoing, chainID, coinType, asset, abortAddress, revertMessage) + + if len(ret) == 0 { + panic("no return value specified for ProcessAbort") + } + + var r0 *evmtypes.MsgEthereumTxResponse + var r1 error + if rf, ok := ret.Get(0).(func(types.Context, string, *big.Int, bool, int64, coin.CoinType, string, common.Address, []byte) (*evmtypes.MsgEthereumTxResponse, error)); ok { + return rf(ctx, inboundSender, amount, outgoing, chainID, coinType, asset, abortAddress, revertMessage) + } + if rf, ok := ret.Get(0).(func(types.Context, string, *big.Int, bool, int64, coin.CoinType, string, common.Address, []byte) *evmtypes.MsgEthereumTxResponse); ok { + r0 = rf(ctx, inboundSender, amount, outgoing, chainID, coinType, asset, abortAddress, revertMessage) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*evmtypes.MsgEthereumTxResponse) + } + } + + if rf, ok := ret.Get(1).(func(types.Context, string, *big.Int, bool, int64, coin.CoinType, string, common.Address, []byte) error); ok { + r1 = rf(ctx, inboundSender, amount, outgoing, chainID, coinType, asset, abortAddress, revertMessage) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ProcessRevert provides a mock function with given fields: ctx, inboundSender, amount, chainID, coinType, asset, revertAddress, callOnRevert, revertMessage +func (_m *CrosschainFungibleKeeper) ProcessRevert(ctx types.Context, inboundSender string, amount *big.Int, chainID int64, coinType coin.CoinType, asset string, revertAddress common.Address, callOnRevert bool, revertMessage []byte) (*evmtypes.MsgEthereumTxResponse, error) { ret := _m.Called(ctx, inboundSender, amount, chainID, coinType, asset, revertAddress, callOnRevert, revertMessage) if len(ret) == 0 { - panic("no return value specified for ProcessV2RevertDeposit") + panic("no return value specified for ProcessRevert") } var r0 *evmtypes.MsgEthereumTxResponse 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 1a24ad6674..4bbdb79222 100644 --- a/typescript/zetachain/zetacore/crosschain/cross_chain_tx_pb.d.ts +++ b/typescript/zetachain/zetacore/crosschain/cross_chain_tx_pb.d.ts @@ -470,6 +470,13 @@ export declare class Status extends Message { */ errorMessageRevert: string; + /** + * error_message_abort carries information when aborting the CCTX fails + * + * @generated from field: string error_message_abort = 8; + */ + errorMessageAbort: string; + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; diff --git a/x/crosschain/keeper/abort.go b/x/crosschain/keeper/abort.go new file mode 100644 index 0000000000..4fbc449b18 --- /dev/null +++ b/x/crosschain/keeper/abort.go @@ -0,0 +1,229 @@ +package keeper + +import ( + "fmt" + + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" + + "github.com/zeta-chain/node/pkg/chains" + "github.com/zeta-chain/node/pkg/coin" + "github.com/zeta-chain/node/x/crosschain/types" + fungibletypes "github.com/zeta-chain/node/x/fungible/types" +) + +// ProcessAbort processes the abort of a cctx +// It refunds the amount to the abort address and try calling onAbort +// StatusMessages contains current status messages for cctx (outbound and revert) +func (k Keeper) ProcessAbort( + ctx sdk.Context, + cctx *types.CrossChainTx, + messages types.StatusMessages, +) { + // only support cctx with v2 and with a defined abort address + // also abort can't be processed if the abort amount is already refunded + if cctx.ProtocolContractVersion != types.ProtocolContractVersion_V2 || + cctx.RevertOptions.AbortAddress == "" || + cctx.CctxStatus.IsAbortRefunded { + messages.ErrorMessageAbort = "abort processing not supported for this cctx" + + cctx.CctxStatus.UpdateStatusAndErrorMessages(types.CctxStatus_Aborted, messages) + return + } + + abortedAmount := GetAbortedAmount(*cctx) + abortAddress := ethcommon.HexToAddress(cctx.RevertOptions.AbortAddress) + + connectedChainID, outgoing, err := cctx.GetConnectedChainID() + if err != nil { + messages.ErrorMessageAbort = "failed to get connected chain ID: " + err.Error() + cctx.CctxStatus.UpdateStatusAndErrorMessages(types.CctxStatus_Aborted, messages) + return + } + + // use a temporary context to not commit any state change if processing the abort logs fails + // this is to avoid an inconsistent state where onAbort is called by created cctx inside are not processed + tmpCtx, commit := ctx.CacheContext() + + // process the abort on the zevm + evmTxResponse, err := k.fungibleKeeper.ProcessAbort( + tmpCtx, + cctx.InboundParams.Sender, + abortedAmount.BigInt(), + outgoing, + connectedChainID, + cctx.InboundParams.CoinType, + cctx.InboundParams.Asset, + abortAddress, + cctx.RevertOptions.RevertMessage, + ) + + if evmTxResponse != nil && !fungibletypes.IsContractReverted(evmTxResponse, err) { + logs := evmtypes.LogsToEthereum(evmTxResponse.Logs) + if len(logs) > 0 { + tmpCtx = tmpCtx.WithValue(InCCTXIndexKey, cctx.Index) + txOrigin := cctx.InboundParams.TxOrigin + if txOrigin == "" { + txOrigin = cctx.GetInboundParams().Sender + } + + // process logs to process cctx events initiated during the contract call + processLogsErr := k.ProcessLogs(tmpCtx, logs, abortAddress, txOrigin) + if processLogsErr != nil { + // this happens if the cctx events are not processed correctly with invalid withdrawals + // in this situation we want the CCTX to be reverted, we don't commit the state so the contract call is not persisted + // the contract call is considered as reverted + messages.ErrorMessageAbort = "failed to process logs for abort: " + err.Error() + cctx.CctxStatus.UpdateStatusAndErrorMessages(types.CctxStatus_Aborted, messages) + return + } + ctx.EventManager().EmitEvent( + sdk.NewEvent(sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute("action", "ProcessAbort"), + sdk.NewAttribute("contract", cctx.RevertOptions.AbortAddress), + sdk.NewAttribute("data", ""), + sdk.NewAttribute("cctxIndex", cctx.Index), + ), + ) + } + } + if err != nil { + messages.ErrorMessageAbort = "failed to process abort: " + err.Error() + } + + // commit state change from the deposit and eventual cctx events + commit() + + // note: we still set this value to true if onAbort reverted because the funds will still be deposited to the abortAddress + cctx.CctxStatus.IsAbortRefunded = true + cctx.CctxStatus.UpdateStatusAndErrorMessages(types.CctxStatus_Aborted, messages) + + return +} + +// LegacyRefundAbortedAmountOnZetaChain refunds the amount of the cctx on ZetaChain in case of aborted cctx +// For v2 cctx this logic has been replaced by using ProcessAbort of the fungible module +// TODO: Remove once only v2 workflow is supported +// https://github.com/zeta-chain/node/issues/2627 +func (k Keeper) LegacyRefundAbortedAmountOnZetaChain( + ctx sdk.Context, + cctx types.CrossChainTx, + refundAddress ethcommon.Address, +) error { + coinType := cctx.InboundParams.CoinType + switch coinType { + case coin.CoinType_Gas: + return k.LegacyRefundAbortedAmountOnZetaChainGas(ctx, cctx, refundAddress) + case coin.CoinType_Zeta: + return k.LegacyRefundAbortedAmountOnZetaChainZeta(ctx, cctx, refundAddress) + case coin.CoinType_ERC20: + return k.LegacyRefundAbortedAmountOnZetaChainERC20(ctx, cctx, refundAddress) + default: + return fmt.Errorf("unsupported coin type for refund on ZetaChain : %s", coinType) + } +} + +// LegacyRefundAbortedAmountOnZetaChainGas refunds the amount of the cctx on ZetaChain in case of aborted cctx with cointype gas +// TODO: Remove once only v2 workflow is supported +// https://github.com/zeta-chain/node/issues/2627 +func (k Keeper) LegacyRefundAbortedAmountOnZetaChainGas( + ctx sdk.Context, + cctx types.CrossChainTx, + refundAddress ethcommon.Address, +) error { + // refund in gas token to refund address + // Refund the the amount was previously + refundAmount := GetAbortedAmount(cctx) + if refundAmount.IsNil() || refundAmount.IsZero() { + return errors.New("no amount to refund") + } + chainID := cctx.InboundParams.SenderChainId + // get the zrc20 contract address + fcSenderChain, found := k.fungibleKeeper.GetGasCoinForForeignCoin(ctx, chainID) + if !found { + return types.ErrForeignCoinNotFound + } + zrc20 := ethcommon.HexToAddress(fcSenderChain.Zrc20ContractAddress) + if zrc20 == (ethcommon.Address{}) { + return errorsmod.Wrapf(types.ErrForeignCoinNotFound, "zrc20 contract address not found for chain %d", chainID) + } + // deposit the amount to the tx origin instead of receiver as this is a refund + if _, err := k.fungibleKeeper.DepositZRC20(ctx, zrc20, refundAddress, refundAmount.BigInt()); err != nil { + return errors.New("failed to refund zeta on ZetaChain" + err.Error()) + } + return nil +} + +// LegacyRefundAbortedAmountOnZetaChainZeta refunds the amount of the cctx on ZetaChain in case of aborted cctx with cointype zeta +// TODO: Remove once only v2 workflow is supported +// https://github.com/zeta-chain/node/issues/2627 +func (k Keeper) LegacyRefundAbortedAmountOnZetaChainZeta( + ctx sdk.Context, + cctx types.CrossChainTx, + refundAddress ethcommon.Address, +) error { + // if coin type is Zeta, handle this as a deposit ZETA to zEVM. + refundAmount := GetAbortedAmount(cctx) + chainID := cctx.InboundParams.SenderChainId + // check if chain is an EVM chain + if !chains.IsEVMChain(chainID, k.GetAuthorityKeeper().GetAdditionalChainList(ctx)) { + return errors.New("only EVM chains are supported for refund when coin type is Zeta") + } + if cctx.InboundParams.Amount.IsNil() || cctx.InboundParams.Amount.IsZero() { + return errors.New("no amount to refund") + } + // deposit the amount to refund address + if err := k.fungibleKeeper.DepositCoinZeta(ctx, refundAddress, refundAmount.BigInt()); err != nil { + return fmt.Errorf("failed to refund zeta on ZetaChain: %w", err) + } + return nil +} + +// LegacyRefundAbortedAmountOnZetaChainERC20 refunds the amount of the cctx on ZetaChain in case of aborted cctx +// NOTE: GetCurrentOutboundParam should contain the last up to date cctx amount +// Refund address should already be validated before calling this function +// TODO: Remove once only v2 workflow is supported +// https://github.com/zeta-chain/node/issues/2627 +func (k Keeper) LegacyRefundAbortedAmountOnZetaChainERC20( + ctx sdk.Context, + cctx types.CrossChainTx, + refundAddress ethcommon.Address, +) error { + refundAmount := GetAbortedAmount(cctx) + // preliminary checks + if cctx.InboundParams.CoinType != coin.CoinType_ERC20 { + return errors.New("unsupported coin type for refund on ZetaChain") + } + if !chains.IsEVMChain(cctx.InboundParams.SenderChainId, k.GetAuthorityKeeper().GetAdditionalChainList(ctx)) { + return errors.New("only EVM chains are supported for refund on ZetaChain") + } + + if refundAmount.IsNil() || refundAmount.IsZero() { + return errors.New("no amount to refund") + } + + // get address of the zrc20 + fc, found := k.fungibleKeeper.GetForeignCoinFromAsset( + ctx, + cctx.InboundParams.Asset, + cctx.InboundParams.SenderChainId, + ) + if !found { + return fmt.Errorf("asset %s zrc not found", cctx.InboundParams.Asset) + } + zrc20 := ethcommon.HexToAddress(fc.Zrc20ContractAddress) + if zrc20 == (ethcommon.Address{}) { + return fmt.Errorf("asset %s invalid zrc address", cctx.InboundParams.Asset) + } + + // deposit the amount to the sender + if _, err := k.fungibleKeeper.DepositZRC20(ctx, zrc20, refundAddress, refundAmount.BigInt()); err != nil { + return errors.New("failed to deposit zrc20 on ZetaChain" + err.Error()) + } + + return nil +} diff --git a/x/crosschain/keeper/refund_test.go b/x/crosschain/keeper/abort_test.go similarity index 71% rename from x/crosschain/keeper/refund_test.go rename to x/crosschain/keeper/abort_test.go index 190b79046c..8fbd2bc1fc 100644 --- a/x/crosschain/keeper/refund_test.go +++ b/x/crosschain/keeper/abort_test.go @@ -3,6 +3,7 @@ package keeper_test import ( "errors" "fmt" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "testing" "cosmossdk.io/math" @@ -19,6 +20,134 @@ import ( fungibletypes "github.com/zeta-chain/node/x/fungible/types" ) +func TestKeeper_ProcessAbort(t *testing.T) { + t.Run("set abort status without processing abort if not v2", func(t *testing.T) { + // arrange + // define fungible mock to assess processAbort is not called + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + + cctx := sample.CrossChainTx(t, "index") + cctx.ProtocolContractVersion = types.ProtocolContractVersion_V1 + + // act + k.ProcessAbort(ctx, cctx, types.StatusMessages{}) + + // assert + require.EqualValues(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) + require.False(t, cctx.CctxStatus.IsAbortRefunded) + }) + + t.Run("set abort status without processing abort if no abort address", func(t *testing.T) { + // arrange + // define fungible mock to assess processAbort is not called + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + + cctx := sample.CrossChainTx(t, "index") + cctx.ProtocolContractVersion = types.ProtocolContractVersion_V2 + cctx.RevertOptions.AbortAddress = "" + + // act + k.ProcessAbort(ctx, cctx, types.StatusMessages{}) + + // assert + require.EqualValues(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) + require.False(t, cctx.CctxStatus.IsAbortRefunded) + }) + + t.Run("fail abort with abort error message if connected chain ID can't be retrieved", func(t *testing.T) { + // arrange + // define fungible mock to assess processAbort is not called + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + + cctx := sample.CrossChainTx(t, "index") + cctx.ProtocolContractVersion = types.ProtocolContractVersion_V2 + cctx.RevertOptions.AbortAddress = sample.EthAddress().Hex() + + // set inbound to nil to make GetConnectedChainID fail + cctx.InboundParams = nil + + // act + k.ProcessAbort(ctx, cctx, types.StatusMessages{}) + + // assert + require.EqualValues(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) + require.False(t, cctx.CctxStatus.IsAbortRefunded) + require.Contains(t, cctx.CctxStatus.ErrorMessageAbort, "failed to get connected chain ID") + }) + + t.Run("process abort by calling process abort of fungible", func(t *testing.T) { + // Arrange + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + fungibleMock.On( + "ProcessAbort", + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything, + ).Return(&evmtypes.MsgEthereumTxResponse{}, nil) + + cctx := sample.CrossChainTx(t, "index") + cctx.ProtocolContractVersion = types.ProtocolContractVersion_V2 + cctx.RevertOptions.AbortAddress = sample.EthAddress().Hex() + + // act + k.ProcessAbort(ctx, cctx, types.StatusMessages{}) + + // assert + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) + require.Empty(t, cctx.CctxStatus.ErrorMessageAbort) + require.True(t, cctx.CctxStatus.IsAbortRefunded) + }) + + t.Run("fail abort with abort error message if process abort fails", func(t *testing.T) { + // Arrange + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + fungibleMock.On( + "ProcessAbort", + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything, + ).Return(&evmtypes.MsgEthereumTxResponse{}, errors.New("process abort failed")) + + cctx := sample.CrossChainTx(t, "index") + cctx.ProtocolContractVersion = types.ProtocolContractVersion_V2 + cctx.RevertOptions.AbortAddress = sample.EthAddress().Hex() + + // act + k.ProcessAbort(ctx, cctx, types.StatusMessages{}) + + // assert + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) + require.Contains(t, cctx.CctxStatus.ErrorMessageAbort, "process abort failed") + require.True(t, cctx.CctxStatus.IsAbortRefunded) + }) +} + func TestKeeper_RefundAmountOnZetaChainGas(t *testing.T) { t.Run("should refund amount zrc20 gas on zeta chain", func(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) @@ -28,7 +157,7 @@ func TestKeeper_RefundAmountOnZetaChainGas(t *testing.T) { deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) zrc20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") - err := k.RefundAmountOnZetaChainGas(ctx, types.CrossChainTx{ + err := k.LegacyRefundAbortedAmountOnZetaChainGas(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_Gas, SenderChainId: chainID, @@ -61,7 +190,7 @@ func TestKeeper_RefundAmountOnZetaChainGas(t *testing.T) { Zrc20ContractAddress: "0x", }, true) - err := k.RefundAmountOnZetaChainGas(ctx, types.CrossChainTx{ + err := k.LegacyRefundAbortedAmountOnZetaChainGas(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_Gas, SenderChainId: chainID, @@ -94,7 +223,7 @@ func TestKeeper_RefundAmountOnZetaChainGas(t *testing.T) { fungibleMock.On("DepositZRC20", mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(nil, errors.New("")) - err := k.RefundAmountOnZetaChainGas(ctx, types.CrossChainTx{ + err := k.LegacyRefundAbortedAmountOnZetaChainGas(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_Gas, SenderChainId: chainID, @@ -119,7 +248,7 @@ func TestKeeper_RefundAmountOnZetaChainGas(t *testing.T) { deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) zrc20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") - err := k.RefundAmountOnZetaChainGas(ctx, types.CrossChainTx{ + err := k.LegacyRefundAbortedAmountOnZetaChainGas(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_Gas, SenderChainId: chainID, @@ -141,7 +270,7 @@ func TestKeeper_RefundAmountOnZetaChainGas(t *testing.T) { sender := sample.EthAddress() chainID := getValidEthChainID() deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) - err := k.RefundAmountOnZetaChainGas(ctx, types.CrossChainTx{ + err := k.LegacyRefundAbortedAmountOnZetaChainGas(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_Gas, SenderChainId: chainID, @@ -166,7 +295,7 @@ func TestKeeper_RefundAmountOnZetaChainGas(t *testing.T) { deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) _ = setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") - err := k.RefundAmountOnZetaChainGas(ctx, types.CrossChainTx{ + err := k.LegacyRefundAbortedAmountOnZetaChainGas(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_Gas, SenderChainId: chainID, @@ -192,7 +321,7 @@ func TestKeeper_RefundAmountOnZetaChainZeta(t *testing.T) { sender := sample.EthAddress() chainID := getValidEthChainID() - err := k.RefundAmountOnZetaChainZeta(ctx, types.CrossChainTx{ + err := k.LegacyRefundAbortedAmountOnZetaChainZeta(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_Gas, SenderChainId: chainID, @@ -218,7 +347,7 @@ func TestKeeper_RefundAmountOnZetaChainZeta(t *testing.T) { sender := sample.EthAddress() chainID := getValidBtcChainID() - err := k.RefundAmountOnZetaChainZeta(ctx, types.CrossChainTx{ + err := k.LegacyRefundAbortedAmountOnZetaChainZeta(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_Gas, SenderChainId: chainID, @@ -245,7 +374,7 @@ func TestKeeper_RefundAmountOnZetaChainZeta(t *testing.T) { sender := sample.EthAddress() chainID := getValidEthChainID() - err := k.RefundAmountOnZetaChainZeta(ctx, types.CrossChainTx{ + err := k.LegacyRefundAbortedAmountOnZetaChainZeta(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_Gas, SenderChainId: chainID, @@ -268,7 +397,7 @@ func TestKeeper_RefundAmountOnZetaChainZeta(t *testing.T) { sender := sample.EthAddress() chainID := getValidEthChainID() - err := k.RefundAmountOnZetaChainZeta(ctx, types.CrossChainTx{ + err := k.LegacyRefundAbortedAmountOnZetaChainZeta(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_Gas, SenderChainId: chainID, @@ -289,7 +418,7 @@ func TestKeeper_RefundAmountOnZetaChainZeta(t *testing.T) { sender := sample.EthAddress() chainID := getValidEthChainID() - err := k.RefundAmountOnZetaChainZeta(ctx, types.CrossChainTx{ + err := k.LegacyRefundAbortedAmountOnZetaChainZeta(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_Gas, SenderChainId: chainID, @@ -328,7 +457,7 @@ func TestKeeper_RefundAmountOnZetaChainERC20(t *testing.T) { "bar", ) - err := k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{ + err := k.LegacyRefundAbortedAmountOnZetaChainERC20(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_ERC20, @@ -351,7 +480,7 @@ func TestKeeper_RefundAmountOnZetaChainERC20(t *testing.T) { require.Equal(t, uint64(42), balance.Uint64()) // can refund again - err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{ + err = k.LegacyRefundAbortedAmountOnZetaChainERC20(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_ERC20, @@ -382,7 +511,7 @@ func TestKeeper_RefundAmountOnZetaChainERC20(t *testing.T) { sender := sample.EthAddress() chainID := getValidEthChainID() - err := k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{ + err := k.LegacyRefundAbortedAmountOnZetaChainERC20(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_ERC20, SenderChainId: chainID, @@ -417,7 +546,7 @@ func TestKeeper_RefundAmountOnZetaChainERC20(t *testing.T) { fungibleMock.On("DepositZRC20", mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(nil, errors.New("")) - err := k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{ + err := k.LegacyRefundAbortedAmountOnZetaChainERC20(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_ERC20, SenderChainId: chainID, @@ -437,7 +566,7 @@ func TestKeeper_RefundAmountOnZetaChainERC20(t *testing.T) { t.Run("should fail with invalid cctx", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) - err := k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{ + err := k.LegacyRefundAbortedAmountOnZetaChainERC20(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_Zeta, @@ -447,7 +576,7 @@ func TestKeeper_RefundAmountOnZetaChainERC20(t *testing.T) { ) require.ErrorContains(t, err, "unsupported coin type") - err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{ + err = k.LegacyRefundAbortedAmountOnZetaChainERC20(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_Gas, }}, @@ -455,7 +584,7 @@ func TestKeeper_RefundAmountOnZetaChainERC20(t *testing.T) { ) require.ErrorContains(t, err, "unsupported coin type") - err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{ + err = k.LegacyRefundAbortedAmountOnZetaChainERC20(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_ERC20, SenderChainId: 999999, @@ -465,7 +594,7 @@ func TestKeeper_RefundAmountOnZetaChainERC20(t *testing.T) { ) require.ErrorContains(t, err, "only EVM chains are supported") - err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{ + err = k.LegacyRefundAbortedAmountOnZetaChainERC20(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_ERC20, SenderChainId: getValidEthChainID(), @@ -476,7 +605,7 @@ func TestKeeper_RefundAmountOnZetaChainERC20(t *testing.T) { ) require.ErrorContains(t, err, "no amount to refund") - err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{ + err = k.LegacyRefundAbortedAmountOnZetaChainERC20(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_ERC20, SenderChainId: getValidEthChainID(), @@ -488,7 +617,7 @@ func TestKeeper_RefundAmountOnZetaChainERC20(t *testing.T) { require.ErrorContains(t, err, "no amount to refund") // the foreign coin has not been set - err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{ + err = k.LegacyRefundAbortedAmountOnZetaChainERC20(ctx, types.CrossChainTx{ InboundParams: &types.InboundParams{ CoinType: coin.CoinType_ERC20, SenderChainId: getValidEthChainID(), @@ -507,6 +636,6 @@ func TestKeeper_RefundAbortedAmountOnZetaChain_FailsForUnsupportedCoinType(t *te cctx := sample.CrossChainTx(t, "index") cctx.InboundParams.CoinType = coin.CoinType_Cmd - err := k.RefundAbortedAmountOnZetaChain(ctx, *cctx, common.Address{}) + err := k.LegacyRefundAbortedAmountOnZetaChain(ctx, *cctx, common.Address{}) require.ErrorContains(t, err, "unsupported coin type for refund on ZetaChain") } diff --git a/x/crosschain/keeper/cctx_gateway_observers.go b/x/crosschain/keeper/cctx_gateway_observers.go index da82606ba4..3bfdb1defc 100644 --- a/x/crosschain/keeper/cctx_gateway_observers.go +++ b/x/crosschain/keeper/cctx_gateway_observers.go @@ -75,8 +75,8 @@ func (c CCTXGatewayObservers) InitiateOutbound( return c.crosschainKeeper.SetObserverOutboundInfo(tmpCtx, outboundReceiverChainID, config.CCTX) }() if err != nil { - // do not commit anything here as the CCTX should be aborted - config.CCTX.SetAbort(types.StatusMessages{ + // do not commit anything here as the CCTX should be aborted, and use ctx for processing the abort + c.crosschainKeeper.ProcessAbort(ctx, config.CCTX, types.StatusMessages{ StatusMessage: "outbound failed unable to process", ErrorMessageOutbound: cctxerror.NewCCTXErrorJSONMessage("Unable to create outbound", err), }) diff --git a/x/crosschain/keeper/cctx_gateway_zevm.go b/x/crosschain/keeper/cctx_gateway_zevm.go index 45eaafa9c8..4036c7e818 100644 --- a/x/crosschain/keeper/cctx_gateway_zevm.go +++ b/x/crosschain/keeper/cctx_gateway_zevm.go @@ -29,14 +29,12 @@ func (c CCTXGatewayZEVM) InitiateOutbound( // abort if CCTX inbound observation status indicates failure // this is specifically for Bitcoin inbound error 'INSUFFICIENT_DEPOSITOR_FEE' if config.CCTX.InboundParams.Status == types.InboundStatus_INSUFFICIENT_DEPOSITOR_FEE { - config.CCTX.SetAbort( - types.StatusMessages{ - StatusMessage: fmt.Sprintf( - "observation failed, reason %s", - types.InboundStatus_INSUFFICIENT_DEPOSITOR_FEE.String(), - ), - }, - ) + c.crosschainKeeper.ProcessAbort(ctx, config.CCTX, types.StatusMessages{ + StatusMessage: fmt.Sprintf( + "observation failed, reason %s", + types.InboundStatus_INSUFFICIENT_DEPOSITOR_FEE.String(), + ), + }) return types.CctxStatus_Aborted, nil } @@ -46,7 +44,8 @@ func (c CCTXGatewayZEVM) InitiateOutbound( if err != nil && !isContractReverted { // exceptional case; internal error; should abort CCTX - config.CCTX.SetAbort(types.StatusMessages{ + // use ctx as tmpCtx is dismissed to not save any side effects performed during the evm deposit + c.crosschainKeeper.ProcessAbort(ctx, config.CCTX, types.StatusMessages{ StatusMessage: "outbound failed but the universal contract did not revert", ErrorMessageOutbound: cctxerror.NewCCTXErrorJSONMessage("failed to deposit tokens in ZEVM", err), }) diff --git a/x/crosschain/keeper/cctx_gateways.go b/x/crosschain/keeper/cctx_gateways.go index c5372ef334..7c2d444a68 100644 --- a/x/crosschain/keeper/cctx_gateways.go +++ b/x/crosschain/keeper/cctx_gateways.go @@ -10,7 +10,7 @@ import ( // CCTXGateway is interface implemented by every gateway. It is one of interfaces used for communication // between CCTX gateways and crosschain module, and it is called by crosschain module. type CCTXGateway interface { - // Initiate a new outbound, this tells the CCTXGateway to carry out the action to execute the outbound. + // InitiateOutbound initiates a new outbound, this tells the CCTXGateway to carry out the action to execute the outbound. // It is the only entry point to initiate an outbound and it returns new CCTX status after it is completed. InitiateOutbound(ctx sdk.Context, config InitiateOutboundConfig) (newCCTXStatus types.CctxStatus, err error) } diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go index f3a2cbefdb..2ae354317b 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go @@ -22,23 +22,16 @@ import ( observertypes "github.com/zeta-chain/node/x/observer/types" ) -/* -ValidateOutboundZEVM processes the finalization of an outbound transaction if receiver is ZEVM. -It takes deposit error and information if contract revert happened during deposit, to make a decision: - -- If the deposit was successful, the CCTX status is changed to OutboundMined. - -- If the deposit returned an internal error, but isContractReverted is false, the CCTX status is changed to Aborted. - -- If the deposit is reverted, the function tries to create a revert cctx with status PendingRevert. - -- If the creation of revert tx also fails it changes the status to Aborted. - -Note : Aborted CCTXs are not refunded in this function. The refund is done using a separate refunding mechanism. -We do not return an error from this function, as all changes need to be persisted to the state. -Instead we use a temporary context to make changes and then commit the context on for the happy path, i.e cctx is set to OutboundMined. -New CCTX status after preprocessing is returned. -*/ +// ValidateOutboundZEVM processes the finalization of an outbound transaction if receiver is ZEVM. +// It takes deposit error and information if contract revert happened during deposit, to make a decision: +// - If the deposit was successful, the CCTX status is changed to OutboundMined. +// - If the deposit returned an internal error, but isContractReverted is false, the CCTX status is changed to Aborted. +// - If the deposit is reverted, the function tries to create a revert cctx with status PendingRevert. +// - If the creation of revert tx also fails it changes the status to Aborted. +// Note : Aborted CCTXs are not refunded in this function. The refund is done using a separate refunding mechanism. +// We do not return an error from this function, as all changes need to be persisted to the state. +// Instead we use a temporary context to make changes and then commit the context on for the happy path, i.e cctx is set to OutboundMined. +// New CCTX status after preprocessing is returned. func (k Keeper) ValidateOutboundZEVM( ctx sdk.Context, cctx *types.CrossChainTx, @@ -59,12 +52,11 @@ func (k Keeper) ValidateOutboundZEVM( // Error here would mean the outbound tx failed and we also failed to create a revert tx. // This is the only case where we set outbound and revert messages, // as both the outbound and the revert failed in the same block - cctx.SetAbort( - types.StatusMessages{ - StatusMessage: fmt.Sprintf("revert failed to be processed"), - ErrorMessageOutbound: ccctxerror.NewCCTXErrorJSONMessage("", depositErr), - ErrorMessageRevert: ccctxerror.NewCCTXErrorJSONMessage("", revertErr), - }) + k.ProcessAbort(ctx, cctx, types.StatusMessages{ + StatusMessage: fmt.Sprintf("revert failed to be processed"), + ErrorMessageOutbound: ccctxerror.NewCCTXErrorJSONMessage("", depositErr), + ErrorMessageRevert: ccctxerror.NewCCTXErrorJSONMessage("", revertErr), + }) return types.CctxStatus_Aborted } @@ -75,98 +67,37 @@ func (k Keeper) ValidateOutboundZEVM( return types.CctxStatus_OutboundMined } -// ValidateOutboundObservers processes the finalization of an outbound transaction based on the ballot status. -// The state is committed only if the individual steps are successful. -func (k Keeper) ValidateOutboundObservers( - ctx sdk.Context, - cctx *types.CrossChainTx, - ballotStatus observertypes.BallotStatus, - valueReceived string, -) error { - tmpCtx, commit := ctx.CacheContext() - err := func() error { - switch ballotStatus { - case observertypes.BallotStatus_BallotFinalized_SuccessObservation: - k.processSuccessfulOutbound(tmpCtx, cctx, valueReceived, true) - case observertypes.BallotStatus_BallotFinalized_FailureObservation: - return k.processFailedOutboundObservers(tmpCtx, cctx, valueReceived) - } - return nil - }() - if err != nil { - return err - } - err = cctx.Validate() - if err != nil { - return err - } - commit() - return nil -} - -// processFailedOutboundObservers processes a failed outbound transaction for observers. It does the following things in one function: -// -// 1. For Admin Tx or a withdrawal from Zeta chain, it aborts the CCTX -// -// 2. For other CCTX -// - If the CCTX is in PendingOutbound, it creates a revert tx and sets the finalization status of the current outbound tx to executed -// - If the CCTX is in PendingRevert, it sets the Status to Aborted -// -// 3. Emit an event for the failed outbound transaction +// processSuccessfulOutbound processes a successful outbound transaction. It does the following things in one function: // -// 4. Set the finalization status of the current outbound tx to executed. If a revert tx is is created, the finalization status is not set, it would get set when the revert is processed via a subsequent transaction +// 1. Change the status of the CCTX from +// - PendingRevert to Reverted +// - PendingOutbound to OutboundMined +// 2. Set the finalization status of the current outbound tx to executed +// 3. Emit an event for the successful outbound transaction if flag is provided // -// This function sets CCTX status , in cases where the outbound tx is successful, but tx itself fails +// This function sets CCTX status, in cases where the outbound tx is successful, but tx itself fails // This is done because HandleValidOutbound does not set the cctx status // For cases where the outbound tx is unsuccessful, the cctx status is automatically set to Aborted in the processFailedOutboundObservers function, so we can just return and error to trigger that -func (k Keeper) processFailedOutboundObservers(ctx sdk.Context, cctx *types.CrossChainTx, valueReceived string) error { +func (k Keeper) processSuccessfulOutbound( + ctx sdk.Context, + cctx *types.CrossChainTx, + valueReceived string, + emitEvent bool, +) { oldStatus := cctx.CctxStatus.Status - // The following logic is used to handler the mentioned conditions separately. The reason being - // All admin tx is created using a policy message, there is no associated inbound tx, therefore we do not need any revert logic - // For transactions which originated from ZEVM, we can process the outbound in the same block as there is no TSS signing required for the revert - // For all other transactions we need to create a revert tx and set the status to pending revert - - if cctx.ProtocolContractVersion == types.ProtocolContractVersion_V2 { - return k.processFailedOutboundV2(ctx, cctx) - } - - if cctx.InboundParams.CoinType == coin.CoinType_Cmd { - // if the cctx is of coin type cmd or the sender chain is zeta chain, then we do not revert, the cctx is aborted - cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed - cctx.SetAbort(types.StatusMessages{ - StatusMessage: "outbound failed for admin tx", - }) - } else if chains.IsZetaChain(cctx.InboundParams.SenderChainId, k.GetAuthorityKeeper().GetAdditionalChainList(ctx)) { - switch cctx.InboundParams.CoinType { - // Try revert if the coin-type is ZETA - case coin.CoinType_Zeta: - { - err := k.processFailedZETAOutboundOnZEVM(ctx, cctx) - if err != nil { - return cosmoserrors.Wrap(err, "validateFailedOutboundObserversForZEVMTx") - } - } - // For all other coin-types, we do not revert, the cctx is aborted - default: - { - cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed - cctx.SetAbort(types.StatusMessages{ - StatusMessage: "outbound failed", - ErrorMessageOutbound: ccctxerror.NewCCTXErrorJSONMessage("outbound failed to be executed on connected chain", nil), - ErrorMessageRevert: ccctxerror.NewCCTXErrorJSONMessage(fmt.Sprintf("revert on ZetaChain is not supported for cctx v1 with coin type %s", cctx.InboundParams.CoinType), nil), - }) - } - } - } else { - // We add a hardcoded message here as the error from the connected chain is not available, - err := k.processFailedOutboundOnExternalChain(ctx, cctx, oldStatus, errors.New("outbound failed to be executed on connected chain"), cctx.GetCurrentOutboundParam().Amount) - if err != nil { - return cosmoserrors.Wrap(err, "processFailedOutboundOnExternalChain") - } + switch oldStatus { + case types.CctxStatus_PendingRevert: + cctx.SetReverted() + case types.CctxStatus_PendingOutbound: + cctx.SetOutboundMined() + default: + return } + cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed newStatus := cctx.CctxStatus.Status.String() - EmitOutboundFailure(ctx, valueReceived, oldStatus.String(), newStatus, cctx.Index) - return nil + if emitEvent { + EmitOutboundSuccess(ctx, valueReceived, oldStatus.String(), newStatus, cctx.Index) + } } // processFailedOutboundOnExternalChain processes the failed outbound transaction where the receiver is an external chain. @@ -233,47 +164,127 @@ func (k Keeper) processFailedOutboundOnExternalChain( }) case types.CctxStatus_PendingRevert: cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed - cctx.SetAbort(types.StatusMessages{ - StatusMessage: "revert failed to be processed", - ErrorMessageRevert: ccctxerror.NewCCTXErrorJSONMessage("", depositErr), - }) + return errors.Wrap(depositErr, "revert failed to be processed on connected chain") + default: + return fmt.Errorf("unexpected cctx status %s", cctx.CctxStatus.Status) } return nil } -// processSuccessfulOutbound processes a successful outbound transaction. It does the following things in one function: +// ValidateOutboundObservers processes the finalization of an outbound transaction based on the ballot status. +// The state is committed only if the individual steps are successful. +func (k Keeper) ValidateOutboundObservers( + ctx sdk.Context, + cctx *types.CrossChainTx, + ballotStatus observertypes.BallotStatus, + valueReceived string, +) error { + // temporary context ensure we don't end up with inconsistent state + tmpCtx, commit := ctx.CacheContext() + + switch ballotStatus { + case observertypes.BallotStatus_BallotFinalized_SuccessObservation: + k.processSuccessfulOutbound(tmpCtx, cctx, valueReceived, true) + case observertypes.BallotStatus_BallotFinalized_FailureObservation: + k.processFailedOutboundObservers(tmpCtx, cctx, valueReceived) + } + + err := cctx.Validate() + if err != nil { + return err + } + commit() + return nil +} + +// processFailedOutboundObservers processes a failed outbound transaction for observers. It does the following things in one function: // -// 1. Change the status of the CCTX from -// - PendingRevert to Reverted -// - PendingOutbound to OutboundMined +// 1. For Admin Tx or a withdrawal from Zeta chain, it aborts the CCTX // -// 2. Set the finalization status of the current outbound tx to executed +// 2. For other CCTX +// - If the CCTX is in PendingOutbound, it creates a revert tx and sets the finalization status of the current outbound tx to executed +// - If the CCTX is in PendingRevert, it sets the Status to Aborted // -// 3. Emit an event for the successful outbound transaction if flag is provided +// 3. Emit an event for the failed outbound transaction // -// This function sets CCTX status, in cases where the outbound tx is successful, but tx itself fails +// 4. Set the finalization status of the current outbound tx to executed. If a revert tx is is created, the finalization status is not set, it would get set when the revert is processed via a subsequent transaction +// +// This function sets CCTX status , in cases where the outbound tx is successful, but tx itself fails // This is done because HandleValidOutbound does not set the cctx status // For cases where the outbound tx is unsuccessful, the cctx status is automatically set to Aborted in the processFailedOutboundObservers function, so we can just return and error to trigger that -func (k Keeper) processSuccessfulOutbound( - ctx sdk.Context, - cctx *types.CrossChainTx, - valueReceived string, - emitEvent bool, -) { +func (k Keeper) processFailedOutboundObservers(ctx sdk.Context, cctx *types.CrossChainTx, valueReceived string) { oldStatus := cctx.CctxStatus.Status - switch oldStatus { - case types.CctxStatus_PendingRevert: - cctx.SetReverted() - case types.CctxStatus_PendingOutbound: - cctx.SetOutboundMined() - default: + // The following logic is used to handler the mentioned conditions separately. The reason being + // All admin tx is created using a policy message, there is no associated inbound tx, therefore we do not need any revert logic + // For transactions which originated from ZEVM, we can process the outbound in the same block as there is no TSS signing required for the revert + // For all other transactions we need to create a revert tx and set the status to pending revert + + if cctx.ProtocolContractVersion == types.ProtocolContractVersion_V2 { + err := k.processFailedOutboundV2(ctx, cctx) + + // if the revert failed to be processed, we process the abort of the cctx + if err != nil { + k.ProcessAbort(ctx, cctx, types.StatusMessages{ + StatusMessage: "outbound failed and revert failed", + ErrorMessageRevert: ccctxerror.NewCCTXErrorJSONMessage( + "revert tx failed to be executed", + nil, + ), + }) + } return } - cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed - newStatus := cctx.CctxStatus.Status.String() - if emitEvent { - EmitOutboundSuccess(ctx, valueReceived, oldStatus.String(), newStatus, cctx.Index) + + if cctx.InboundParams.CoinType == coin.CoinType_Cmd { + // if the cctx is of coin type cmd or the sender chain is zeta chain, then we do not revert, the cctx is aborted + cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed + cctx.SetAbort(types.StatusMessages{ + StatusMessage: "outbound failed for admin cmd", + ErrorMessageOutbound: ccctxerror.NewCCTXErrorJSONMessage( + "admin cmd outbound failed to be executed on connected chain", + nil, + ), + ErrorMessageRevert: ccctxerror.NewCCTXErrorJSONMessage("admin cmd outbound can't be reverted", nil), + }) + } else if chains.IsZetaChain(cctx.InboundParams.SenderChainId, k.GetAuthorityKeeper().GetAdditionalChainList(ctx)) { + switch cctx.InboundParams.CoinType { + // Try revert if the coin-type is ZETA + case coin.CoinType_Zeta: + { + err := k.processFailedZETAOutboundOnZEVM(ctx, cctx) + if err != nil { + cctx.SetAbort(types.StatusMessages{ + StatusMessage: "zeta outbound failed and revert failed on ZetaChain", + ErrorMessageOutbound: ccctxerror.NewCCTXErrorJSONMessage("outbound failed to be executed on connected chain", nil), + ErrorMessageRevert: ccctxerror.NewCCTXErrorJSONMessage("revert failed", err), + }) + } + } + // For all other coin-types, we do not revert, the cctx is aborted + default: + { + cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed + cctx.SetAbort(types.StatusMessages{ + StatusMessage: "outbound failed and revert can't be processed", + ErrorMessageOutbound: ccctxerror.NewCCTXErrorJSONMessage("outbound failed to be executed on connected chain", nil), + ErrorMessageRevert: ccctxerror.NewCCTXErrorJSONMessage(fmt.Sprintf("revert on ZetaChain is not supported for cctx v1 with coin type %s", cctx.InboundParams.CoinType), nil), + }) + } + } + } else { + // We add a hardcoded message here as the error from the connected chain is not available, + err := k.processFailedOutboundOnExternalChain(ctx, cctx, oldStatus, errors.New("outbound failed to be executed on connected chain"), cctx.GetCurrentOutboundParam().Amount) + if err != nil { + cctx.SetAbort(types.StatusMessages{ + StatusMessage: "outbound failed and revert failed on connected chain", + ErrorMessageOutbound: ccctxerror.NewCCTXErrorJSONMessage("outbound failed to be executed on connected chain", nil), + ErrorMessageRevert: ccctxerror.NewCCTXErrorJSONMessage("revert failed", err), + }) + } } + newStatus := cctx.CctxStatus.Status.String() + EmitOutboundFailure(ctx, valueReceived, oldStatus.String(), newStatus, cctx.Index) + return } // processFailedZETAOutboundOnZEVM processes a failed ZETA outbound on ZEVM @@ -394,7 +405,7 @@ func (k Keeper) processFailedOutboundV2(ctx sdk.Context, cctx *types.CrossChainT // process the revert on ZEVM to := ethcommon.HexToAddress(cctx.GetCurrentOutboundParam().Receiver) - evmTxResponse, err := k.fungibleKeeper.ProcessV2RevertDeposit( + evmTxResponse, err := k.fungibleKeeper.ProcessRevert( tmpCtx, cctx.InboundParams.Sender, cctx.GetCurrentOutboundParam().Amount.BigInt(), @@ -451,13 +462,7 @@ func (k Keeper) processFailedOutboundV2(ctx sdk.Context, cctx *types.CrossChainT cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed case types.CctxStatus_PendingRevert: cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed - cctx.SetAbort(types.StatusMessages{ - StatusMessage: "revert failed to be processed", - ErrorMessageRevert: ccctxerror.NewCCTXErrorJSONMessage( - "revert tx failed to be executed on connected chain", - nil, - ), - }) + return errors.New("revert failed to be processed on connected chain") default: return fmt.Errorf("unexpected cctx status %s", cctx.CctxStatus.Status) } diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_outbound_test.go b/x/crosschain/keeper/cctx_orchestrator_validate_outbound_test.go index 5878976f20..bd4a986344 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_outbound_test.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_outbound_test.go @@ -61,7 +61,7 @@ func TestKeeper_ValidateSuccessfulOutbound(t *testing.T) { } func TestKeeper_ValidateFailedOutboundV2(t *testing.T) { - t.Run("fail if can't fetch ZetaChain chain ID", func(t *testing.T) { + t.Run("cctx aborted if can't fetch ZetaChain chain ID", func(t *testing.T) { // arrange k, ctx, _, _ := keepertest.CrosschainKeeper(t) cctx := sample.CrossChainTx(t, "test") @@ -79,11 +79,11 @@ func TestKeeper_ValidateFailedOutboundV2(t *testing.T) { ) // assert - require.Error(t, err) - require.Contains(t, err.Error(), "failed to get ZetaChain chainID") + require.NoError(t, err) + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) }) - t.Run("fail if CCTX source chain is not ZetaChain", func(t *testing.T) { + t.Run("cctx aborted if CCTX source chain is not ZetaChain", func(t *testing.T) { // arrange k, ctx, _, _ := keepertest.CrosschainKeeper(t) cctx := sample.CrossChainTx(t, "test") @@ -100,11 +100,11 @@ func TestKeeper_ValidateFailedOutboundV2(t *testing.T) { ) // assert - require.Error(t, err) - require.Contains(t, err.Error(), "sender chain for withdraw cctx is not ZetaChain") + require.NoError(t, err) + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) }) - t.Run("fail if fail to add revert outbound", func(t *testing.T) { + t.Run("cctx aborted if fail to add revert outbound", func(t *testing.T) { // arrange k, ctx, _, _ := keepertest.CrosschainKeeper(t) cctx := sample.CrossChainTxV2(t, "test") @@ -126,11 +126,11 @@ func TestKeeper_ValidateFailedOutboundV2(t *testing.T) { ) // assert - require.Error(t, err) - require.Contains(t, err.Error(), "failed AddRevertOutbound") + require.NoError(t, err) + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) }) - t.Run("fail if the revert call get reverted", func(t *testing.T) { + t.Run("cctx aborted if the revert call get reverted", func(t *testing.T) { // arrange k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseFungibleMock: true, @@ -155,11 +155,11 @@ func TestKeeper_ValidateFailedOutboundV2(t *testing.T) { ) // assert - require.Error(t, err) - require.Contains(t, err.Error(), "revert transaction reverted") + require.NoError(t, err) + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) }) - t.Run("fail if the revert call can't be processed", func(t *testing.T) { + t.Run("cctx aborted if the revert call can't be processed", func(t *testing.T) { // arrange k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseFungibleMock: true, @@ -183,8 +183,8 @@ func TestKeeper_ValidateFailedOutboundV2(t *testing.T) { ) // assert - require.Error(t, err) - require.Contains(t, err.Error(), "revert transaction couldn't be processed") + require.NoError(t, err) + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) }) t.Run("process failed outbound with a revert", func(t *testing.T) { @@ -239,7 +239,7 @@ func TestKeeper_ValidateFailedOutboundV2(t *testing.T) { require.EqualValues(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) }) - t.Run("fail if cctx status is invalid", func(t *testing.T) { + t.Run("cctx aborted if cctx status is invalid", func(t *testing.T) { // arrange k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseFungibleMock: true, @@ -257,8 +257,8 @@ func TestKeeper_ValidateFailedOutboundV2(t *testing.T) { ) // assert - require.Error(t, err) - require.Contains(t, err.Error(), "unexpected cctx status") + require.NoError(t, err) + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) }) } @@ -339,7 +339,7 @@ func TestKeeper_ValidateFailedOutbound(t *testing.T) { require.Equal(t, types.CctxStatus_Reverted, cctx.CctxStatus.Status) require.Equal(t, cctx.GetCurrentOutboundParam().TxFinalizationStatus, types.TxFinalizationStatus_Executed) }) - t.Run("unable to validate failed outbound if GetCCTXIndexBytes fails", func(t *testing.T) { + t.Run("cctx aborted if GetCCTXIndexBytes fails", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) receiver := sample.EthAddress() cctx := GetERC20Cctx(t, receiver, chains.Goerli, "", big.NewInt(42)) @@ -352,10 +352,11 @@ func TestKeeper_ValidateFailedOutbound(t *testing.T) { observertypes.BallotStatus_BallotFinalized_FailureObservation, sample.String(), ) - require.ErrorContains(t, err, "failed reverting GetCCTXIndexBytes") + require.NoError(t, err) + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) }) - t.Run("unable to validate failed outbound if Adding Revert fails", func(t *testing.T) { + t.Run("cctx aborted if Adding Revert fails", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) cctx := sample.CrossChainTx(t, "test") cctx.InboundParams.SenderChainId = chains.ZetaChainMainnet.ChainId @@ -366,10 +367,11 @@ func TestKeeper_ValidateFailedOutbound(t *testing.T) { observertypes.BallotStatus_BallotFinalized_FailureObservation, sample.String(), ) - require.ErrorContains(t, err, "failed AddRevertOutbound") + require.NoError(t, err) + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) }) - t.Run("unable to validate failed outbound if ZETARevertAndCallContract fails", func(t *testing.T) { + t.Run("cctx aborted if ZETARevertAndCallContract fails", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseFungibleMock: true, }) @@ -393,7 +395,8 @@ func TestKeeper_ValidateFailedOutbound(t *testing.T) { observertypes.BallotStatus_BallotFinalized_FailureObservation, sample.String(), ) - require.ErrorContains(t, err, "failed ZETARevertAndCallContract") + require.NoError(t, err) + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) }) t.Run("successfully revert failed outbound if original sender is a contract", func(t *testing.T) { @@ -517,7 +520,7 @@ func TestKeeper_ValidateFailedOutbound(t *testing.T) { require.Equal(t, types.TxFinalizationStatus_Executed, cctx.OutboundParams[0].TxFinalizationStatus) }) - t.Run("unable to validate revert when update nonce fails", func(t *testing.T) { + t.Run("aborted if update nonce fails", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseFungibleMock: true, UseObserverMock: true, @@ -552,11 +555,11 @@ func TestKeeper_ValidateFailedOutbound(t *testing.T) { observertypes.BallotStatus_BallotFinalized_FailureObservation, sample.String(), ) - require.ErrorIs(t, err, types.ErrCannotFindReceiverNonce) - require.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_PendingOutbound) + require.NoError(t, err) + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) }) - t.Run("unable to validate revert when PayGasAndUpdateCctx fails", func(t *testing.T) { + t.Run("aborted if PayGasAndUpdateCctx fails", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseFungibleMock: true, UseObserverMock: true, @@ -587,11 +590,11 @@ func TestKeeper_ValidateFailedOutbound(t *testing.T) { observertypes.BallotStatus_BallotFinalized_FailureObservation, sample.String(), ) - require.ErrorIs(t, err, observertypes.ErrSupportedChains) - require.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_PendingOutbound) + require.NoError(t, err) + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) }) - t.Run("unable to validate revert when GetRevertGasLimit fails", func(t *testing.T) { + t.Run("aborted if GetRevertGasLimit fails", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseFungibleMock: true, }) @@ -617,8 +620,8 @@ func TestKeeper_ValidateFailedOutbound(t *testing.T) { observertypes.BallotStatus_BallotFinalized_FailureObservation, sample.String(), ) - require.ErrorIs(t, err, types.ErrForeignCoinNotFound) - require.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_PendingOutbound) + require.NoError(t, err) + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) }) } @@ -679,7 +682,7 @@ func TestKeeper_ValidateOutboundObservers(t *testing.T) { require.Error(t, err) }) - t.Run("do not validate outbound on error, no new outbound created", func(t *testing.T) { + t.Run("no new outbound created when aborted ", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseFungibleMock: true, }) @@ -706,14 +709,15 @@ func TestKeeper_ValidateOutboundObservers(t *testing.T) { observertypes.BallotStatus_BallotFinalized_FailureObservation, sample.String(), ) - require.ErrorIs(t, err, types.ErrForeignCoinNotFound) - require.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_PendingOutbound) + require.NoError(t, err) + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) + // New outbound not added and the old outbound is not finalized require.Len(t, cctx.OutboundParams, oldOutboundParamsLen) require.Equal(t, cctx.GetCurrentOutboundParam().TxFinalizationStatus, types.TxFinalizationStatus_NotFinalized) }) - t.Run("do not validate outbound if the cctx has already been reverted once", func(t *testing.T) { + t.Run("cctx aborted if the cctx has already been reverted once", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseFungibleMock: true, }) @@ -741,7 +745,8 @@ func TestKeeper_ValidateOutboundObservers(t *testing.T) { observertypes.BallotStatus_BallotFinalized_FailureObservation, sample.String(), ) - require.Error(t, err) + require.NoError(t, err) + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) }) t.Run("successfully revert a outbound and create a new revert tx", func(t *testing.T) { diff --git a/x/crosschain/keeper/evm_deposit.go b/x/crosschain/keeper/evm_deposit.go index 037462e653..630abaac91 100644 --- a/x/crosschain/keeper/evm_deposit.go +++ b/x/crosschain/keeper/evm_deposit.go @@ -148,7 +148,7 @@ func (k Keeper) HandleEVMDeposit(ctx sdk.Context, cctx *types.CrossChainTx) (boo tmpCtx.EventManager().EmitEvent( sdk.NewEvent(sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), - sdk.NewAttribute("action", "DepositZRC20AndCallContract"), + sdk.NewAttribute("action", "CallDepositAndCall"), sdk.NewAttribute("contract", to.String()), sdk.NewAttribute("data", hex.EncodeToString(message)), sdk.NewAttribute("cctxIndex", cctx.Index), diff --git a/x/crosschain/keeper/msg_server_abort_stuck_cctx.go b/x/crosschain/keeper/msg_server_abort_stuck_cctx.go index 6983dcdc21..836116b86a 100644 --- a/x/crosschain/keeper/msg_server_abort_stuck_cctx.go +++ b/x/crosschain/keeper/msg_server_abort_stuck_cctx.go @@ -41,8 +41,7 @@ func (k msgServer) AbortStuckCCTX( } // update the status - - cctx.SetAbort(types.StatusMessages{ + k.ProcessAbort(ctx, &cctx, types.StatusMessages{ StatusMessage: AbortMessage, }) diff --git a/x/crosschain/keeper/msg_server_refund_aborted_tx.go b/x/crosschain/keeper/msg_server_refund_aborted_tx.go index a4f899b9e2..224cc47230 100644 --- a/x/crosschain/keeper/msg_server_refund_aborted_tx.go +++ b/x/crosschain/keeper/msg_server_refund_aborted_tx.go @@ -65,14 +65,14 @@ func (k msgServer) RefundAbortedCCTX( // refund the amount // use temporary context to avoid gas refunding issues and side effects tmpCtx, commit := ctx.CacheContext() - err = k.RefundAbortedAmountOnZetaChain(tmpCtx, cctx, refundAddress) + err = k.LegacyRefundAbortedAmountOnZetaChain(tmpCtx, cctx, refundAddress) if err != nil { return nil, errorsmod.Wrap(types.ErrUnableProcessRefund, err.Error()) } commit() // set the cctx as refunded - cctx.CctxStatus.AbortRefunded() + cctx.CctxStatus.SetAbortRefunded() k.SetCrossChainTx(ctx, cctx) return &types.MsgRefundAbortedCCTXResponse{}, nil diff --git a/x/crosschain/keeper/msg_server_vote_outbound_tx.go b/x/crosschain/keeper/msg_server_vote_outbound_tx.go index 9535a11131..166b2bb383 100644 --- a/x/crosschain/keeper/msg_server_vote_outbound_tx.go +++ b/x/crosschain/keeper/msg_server_vote_outbound_tx.go @@ -121,16 +121,18 @@ func (k msgServer) VoteOutbound( // Fund the gas stability pool with the remaining funds. k.FundStabilityPool(ctx, &cctx) - // We use the current TSS pubkey to finalize the outbound. + // Validate and process the observed outbound err = k.ValidateOutboundObservers(ctx, &cctx, ballot.BallotStatus, msg.ValueReceived.String()) if err != nil { - // The validate function for the outbound returns an error, which means that the outbound is invalid and should instead be aborted directly - // Irrespective of what the Ballot status is - k.HandleInvalidOutbound(ctx, &cctx, err, tss.TssPubkey) - return &types.MsgVoteOutboundResponse{}, nil + // Should not happen + cctx.SetAbort(types.StatusMessages{ + StatusMessage: "outbound failed unable to process", + ErrorMessageOutbound: cctxerror.NewCCTXErrorJSONMessage("", err), + }) + ctx.Logger().Error(err.Error()) } - // The outbound is valid, the HandleValidOutbound function would save the required status changes - k.HandleValidOutbound(ctx, &cctx, tss.TssPubkey) + k.SaveOutbound(ctx, &cctx, tss.TssPubkey) + return &types.MsgVoteOutboundResponse{}, nil } @@ -188,41 +190,11 @@ func percentOf(n *big.Int, percent int64) *big.Int { return n } -/* -HandleInvalidOutbound saves an invalid outbound transaction. It does the following things in one function: - - 1. Change the status of the CCTX to Aborted - - 2. Save the outbound -*/ - -func (k Keeper) HandleInvalidOutbound(ctx sdk.Context, cctx *types.CrossChainTx, err error, tssPubkey string) { - cctx.SetAbort(types.StatusMessages{ - StatusMessage: "outbound failed unable to process", - ErrorMessageOutbound: cctxerror.NewCCTXErrorJSONMessage("", err), - }) - ctx.Logger().Error(err.Error()) - k.SaveOutbound(ctx, cctx, tssPubkey) -} - -// HandleValidOutbound saves a successful outbound transaction. -// This function does not set the CCTX status, therefore all successful outbound transactions need -// to have their status set during processing -func (k Keeper) HandleValidOutbound(ctx sdk.Context, cctx *types.CrossChainTx, tssPubkey string) { - k.SaveOutbound(ctx, cctx, tssPubkey) -} - -/* -SaveOutbound saves the outbound transaction.It does the following things in one function: - - 1. Set the ballot index for the outbound vote to the cctx - - 2. Remove the nonce from the pending nonces - - 3. Remove the outbound tx tracker - - 4. Set the cctx and nonce to cctx and inboundHash to cctx -*/ +// SaveOutbound saves the outbound transaction.It does the following things in one function: +// 1. Set the ballot index for the outbound vote to the cctx +// 2. Remove the nonce from the pending nonces +// 3. Remove the outbound tx tracker +// 4. Set the cctx and nonce to cctx and inboundHash to cctx func (k Keeper) SaveOutbound(ctx sdk.Context, cctx *types.CrossChainTx, tssPubkey string) { // #nosec G115 always in range for _, outboundParams := range cctx.OutboundParams { diff --git a/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go b/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go index 4789fada73..f3551f3524 100644 --- a/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go +++ b/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go @@ -579,116 +579,6 @@ func TestKeeper_VoteOutbound(t *testing.T) { }) } -func TestKeeper_SaveFailedOutbound(t *testing.T) { - t.Run("successfully save failed outbound", func(t *testing.T) { - //ARRANGE - k, ctx, _, _ := keepertest.CrosschainKeeper(t) - cctx := sample.CrossChainTx(t, "test") - k.SetOutboundTracker(ctx, types.OutboundTracker{ - Index: "", - ChainId: cctx.GetCurrentOutboundParam().ReceiverChainId, - Nonce: cctx.GetCurrentOutboundParam().TssNonce, - HashList: nil, - }) - cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - - //ACT - k.HandleInvalidOutbound(ctx, cctx, errors.New(sample.String()), sample.Tss().TssPubkey) - - //ASSERT - require.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_Aborted) - _, found := k.GetOutboundTracker( - ctx, - cctx.GetCurrentOutboundParam().ReceiverChainId, - cctx.GetCurrentOutboundParam().TssNonce, - ) - require.False(t, found) - }) - - t.Run("successfully save failed outbound with multiple trackers", func(t *testing.T) { - //ARRANGE - k, ctx, _, _ := keepertest.CrosschainKeeper(t) - cctx := sample.CrossChainTx(t, "test") - for _, outboundParams := range cctx.OutboundParams { - k.SetOutboundTracker(ctx, types.OutboundTracker{ - Index: "", - ChainId: outboundParams.ReceiverChainId, - Nonce: outboundParams.TssNonce, - HashList: nil, - }) - } - cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - - //ACT - k.HandleInvalidOutbound(ctx, cctx, errors.New(sample.String()), sample.Tss().TssPubkey) - - //ASSERT - require.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_Aborted) - for _, outboundParams := range cctx.OutboundParams { - _, found := k.GetOutboundTracker( - ctx, - outboundParams.ReceiverChainId, - outboundParams.TssNonce, - ) - require.False(t, found) - } - }) -} - -func TestKeeper_SaveSuccessfulOutbound(t *testing.T) { - t.Run("successfully save successful outbound", func(t *testing.T) { - //ARRANGE - k, ctx, _, _ := keepertest.CrosschainKeeper(t) - cctx := sample.CrossChainTx(t, "test") - k.SetOutboundTracker(ctx, types.OutboundTracker{ - Index: "", - ChainId: cctx.GetCurrentOutboundParam().ReceiverChainId, - Nonce: cctx.GetCurrentOutboundParam().TssNonce, - HashList: nil, - }) - cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - - //ACT - k.HandleValidOutbound(ctx, cctx, sample.Tss().TssPubkey) - - //ASSERT - _, found := k.GetOutboundTracker( - ctx, - cctx.GetCurrentOutboundParam().ReceiverChainId, - cctx.GetCurrentOutboundParam().TssNonce, - ) - require.False(t, found) - }) - - t.Run("successfully save successful outbound with multiple trackers", func(t *testing.T) { - //ARRANGE - k, ctx, _, _ := keepertest.CrosschainKeeper(t) - cctx := sample.CrossChainTx(t, "test") - for _, outboundParams := range cctx.OutboundParams { - k.SetOutboundTracker(ctx, types.OutboundTracker{ - Index: "", - ChainId: outboundParams.ReceiverChainId, - Nonce: outboundParams.TssNonce, - HashList: nil, - }) - } - cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - - //ACT - k.HandleValidOutbound(ctx, cctx, sample.Tss().TssPubkey) - - //ASSERT - for _, outboundParams := range cctx.OutboundParams { - _, found := k.GetOutboundTracker( - ctx, - outboundParams.ReceiverChainId, - outboundParams.TssNonce, - ) - require.False(t, found) - } - }) -} - func TestKeeper_SaveOutbound(t *testing.T) { t.Run("successfully save outbound", func(t *testing.T) { //ARRANGE diff --git a/x/crosschain/keeper/refund.go b/x/crosschain/keeper/refund.go deleted file mode 100644 index 8d1e2da230..0000000000 --- a/x/crosschain/keeper/refund.go +++ /dev/null @@ -1,127 +0,0 @@ -package keeper - -import ( - "errors" - "fmt" - - errorsmod "cosmossdk.io/errors" - sdk "github.com/cosmos/cosmos-sdk/types" - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/zeta-chain/node/pkg/chains" - "github.com/zeta-chain/node/pkg/coin" - "github.com/zeta-chain/node/x/crosschain/types" -) - -func (k Keeper) RefundAbortedAmountOnZetaChain( - ctx sdk.Context, - cctx types.CrossChainTx, - refundAddress ethcommon.Address, -) error { - coinType := cctx.InboundParams.CoinType - switch coinType { - case coin.CoinType_Gas: - return k.RefundAmountOnZetaChainGas(ctx, cctx, refundAddress) - case coin.CoinType_Zeta: - return k.RefundAmountOnZetaChainZeta(ctx, cctx, refundAddress) - case coin.CoinType_ERC20: - return k.RefundAmountOnZetaChainERC20(ctx, cctx, refundAddress) - default: - return fmt.Errorf("unsupported coin type for refund on ZetaChain : %s", coinType) - } -} - -// RefundAmountOnZetaChainGas refunds the amount of the cctx on ZetaChain in case of aborted cctx with cointype gas -func (k Keeper) RefundAmountOnZetaChainGas( - ctx sdk.Context, - cctx types.CrossChainTx, - refundAddress ethcommon.Address, -) error { - // refund in gas token to refund address - // Refund the the amount was previously - refundAmount := GetAbortedAmount(cctx) - if refundAmount.IsNil() || refundAmount.IsZero() { - return errors.New("no amount to refund") - } - chainID := cctx.InboundParams.SenderChainId - // get the zrc20 contract address - fcSenderChain, found := k.fungibleKeeper.GetGasCoinForForeignCoin(ctx, chainID) - if !found { - return types.ErrForeignCoinNotFound - } - zrc20 := ethcommon.HexToAddress(fcSenderChain.Zrc20ContractAddress) - if zrc20 == (ethcommon.Address{}) { - return errorsmod.Wrapf(types.ErrForeignCoinNotFound, "zrc20 contract address not found for chain %d", chainID) - } - // deposit the amount to the tx origin instead of receiver as this is a refund - if _, err := k.fungibleKeeper.DepositZRC20(ctx, zrc20, refundAddress, refundAmount.BigInt()); err != nil { - return errors.New("failed to refund zeta on ZetaChain" + err.Error()) - } - return nil -} - -// RefundAmountOnZetaChainZeta refunds the amount of the cctx on ZetaChain in case of aborted cctx with cointype zeta -func (k Keeper) RefundAmountOnZetaChainZeta( - ctx sdk.Context, - cctx types.CrossChainTx, - refundAddress ethcommon.Address, -) error { - // if coin type is Zeta, handle this as a deposit ZETA to zEVM. - refundAmount := GetAbortedAmount(cctx) - chainID := cctx.InboundParams.SenderChainId - // check if chain is an EVM chain - if !chains.IsEVMChain(chainID, k.GetAuthorityKeeper().GetAdditionalChainList(ctx)) { - return errors.New("only EVM chains are supported for refund when coin type is Zeta") - } - if cctx.InboundParams.Amount.IsNil() || cctx.InboundParams.Amount.IsZero() { - return errors.New("no amount to refund") - } - // deposit the amount to refund address - if err := k.fungibleKeeper.DepositCoinZeta(ctx, refundAddress, refundAmount.BigInt()); err != nil { - return errors.New("failed to refund zeta on ZetaChain" + err.Error()) - } - return nil -} - -// RefundAmountOnZetaChainERC20 refunds the amount of the cctx on ZetaChain in case of aborted cctx -// NOTE: GetCurrentOutboundParam should contain the last up to date cctx amount -// Refund address should already be validated before calling this function -func (k Keeper) RefundAmountOnZetaChainERC20( - ctx sdk.Context, - cctx types.CrossChainTx, - refundAddress ethcommon.Address, -) error { - refundAmount := GetAbortedAmount(cctx) - // preliminary checks - if cctx.InboundParams.CoinType != coin.CoinType_ERC20 { - return errors.New("unsupported coin type for refund on ZetaChain") - } - if !chains.IsEVMChain(cctx.InboundParams.SenderChainId, k.GetAuthorityKeeper().GetAdditionalChainList(ctx)) { - return errors.New("only EVM chains are supported for refund on ZetaChain") - } - - if refundAmount.IsNil() || refundAmount.IsZero() { - return errors.New("no amount to refund") - } - - // get address of the zrc20 - fc, found := k.fungibleKeeper.GetForeignCoinFromAsset( - ctx, - cctx.InboundParams.Asset, - cctx.InboundParams.SenderChainId, - ) - if !found { - return fmt.Errorf("asset %s zrc not found", cctx.InboundParams.Asset) - } - zrc20 := ethcommon.HexToAddress(fc.Zrc20ContractAddress) - if zrc20 == (ethcommon.Address{}) { - return fmt.Errorf("asset %s invalid zrc address", cctx.InboundParams.Asset) - } - - // deposit the amount to the sender - if _, err := k.fungibleKeeper.DepositZRC20(ctx, zrc20, refundAddress, refundAmount.BigInt()); err != nil { - return errors.New("failed to deposit zrc20 on ZetaChain" + err.Error()) - } - - return nil -} diff --git a/x/crosschain/types/cctx.go b/x/crosschain/types/cctx.go index 306d0c053e..86f371e594 100644 --- a/x/crosschain/types/cctx.go +++ b/x/crosschain/types/cctx.go @@ -14,6 +14,26 @@ import ( observertypes "github.com/zeta-chain/node/x/observer/types" ) +// GetConnectedChainID returns the connected chain ID for the CCTX. +// If the CCTX is outgoing, this is the receiver chain ID. +// If the CCTX is incoming, this is the sender chain ID. +// Second argument is boolean, true if the CCTX is outgoing, false if incoming. +func (m CrossChainTx) GetConnectedChainID() (int64, bool, error) { + if m.InboundParams == nil { + return 0, false, fmt.Errorf("inbound params cannot be nil") + } + + // If the sender chain ID is ZetaChain, this is an outgoing CCTX. + // Note: additional chains argument is empty, all ZetaChain IDs are hardcoded in the codebase. + if chains.IsZetaChain(m.InboundParams.SenderChainId, []chains.Chain{}) { + if len(m.OutboundParams) < 1 || m.OutboundParams[0] == nil { + return 0, false, fmt.Errorf("outbound params cannot be nil") + } + return m.OutboundParams[0].ReceiverChainId, true, nil + } + return m.InboundParams.SenderChainId, false, nil +} + // GetEVMRevertAddress returns the EVM revert address // If a revert address is specified in the revert options, it returns the address // Otherwise returns sender address diff --git a/x/crosschain/types/cctx_test.go b/x/crosschain/types/cctx_test.go index d2bc120a8a..30068c9633 100644 --- a/x/crosschain/types/cctx_test.go +++ b/x/crosschain/types/cctx_test.go @@ -12,6 +12,70 @@ import ( "github.com/zeta-chain/node/x/crosschain/types" ) +func TestCrossChainTx_GetConnectedChainID(t *testing.T) { + t.Run("no inbound params", func(t *testing.T) { + cctx := sample.CrossChainTx(t, "sample") + cctx.InboundParams = nil + _, _, err := cctx.GetConnectedChainID() + require.Error(t, err) + require.ErrorContains(t, err, "inbound params cannot be nil") + }) + + t.Run("no outbound params", func(t *testing.T) { + cctx := sample.CrossChainTx(t, "sample") + cctx.InboundParams = &types.InboundParams{ + SenderChainId: chains.ZetaChainPrivnet.GetChainId(), + } + cctx.OutboundParams = []*types.OutboundParams{} + _, _, err := cctx.GetConnectedChainID() + require.Error(t, err) + require.ErrorContains(t, err, "outbound params cannot be nil") + }) + + t.Run("no outbound params with nil", func(t *testing.T) { + cctx := sample.CrossChainTx(t, "sample") + cctx.InboundParams = &types.InboundParams{ + SenderChainId: chains.ZetaChainPrivnet.GetChainId(), + } + cctx.OutboundParams = []*types.OutboundParams{nil} + _, _, err := cctx.GetConnectedChainID() + require.Error(t, err) + require.ErrorContains(t, err, "outbound params cannot be nil") + }) + + t.Run("outgoing cctx", func(t *testing.T) { + cctx := sample.CrossChainTx(t, "sample") + cctx.InboundParams = &types.InboundParams{ + SenderChainId: chains.ZetaChainPrivnet.GetChainId(), + } + cctx.OutboundParams = []*types.OutboundParams{ + { + ReceiverChainId: chains.BitcoinTestnet.GetChainId(), + }, + } + chainID, outgoing, err := cctx.GetConnectedChainID() + require.NoError(t, err) + require.True(t, outgoing) + require.EqualValues(t, chains.BitcoinTestnet.GetChainId(), chainID) + }) + + t.Run("incoming cctx", func(t *testing.T) { + cctx := sample.CrossChainTx(t, "sample") + cctx.InboundParams = &types.InboundParams{ + SenderChainId: chains.BitcoinTestnet.GetChainId(), + } + cctx.OutboundParams = []*types.OutboundParams{ + { + ReceiverChainId: chains.ZetaChainPrivnet.GetChainId(), + }, + } + chainID, outgoing, err := cctx.GetConnectedChainID() + require.NoError(t, err) + require.False(t, outgoing) + require.EqualValues(t, chains.BitcoinTestnet.GetChainId(), chainID) + }) +} + func TestCrossChainTx_GetEVMRevertAddress(t *testing.T) { t.Run("use revert address if revert options", func(t *testing.T) { cctx := sample.CrossChainTx(t, "sample") diff --git a/x/crosschain/types/cross_chain_tx.pb.go b/x/crosschain/types/cross_chain_tx.pb.go index 9de2c170cc..9064f10f12 100644 --- a/x/crosschain/types/cross_chain_tx.pb.go +++ b/x/crosschain/types/cross_chain_tx.pb.go @@ -596,6 +596,8 @@ type Status struct { // error_message_revert carries information about the revert outbound tx , // which is created if the first outbound tx fails ErrorMessageRevert string `protobuf:"bytes,7,opt,name=error_message_revert,json=errorMessageRevert,proto3" json:"error_message_revert,omitempty"` + // error_message_abort carries information when aborting the CCTX fails + ErrorMessageAbort string `protobuf:"bytes,8,opt,name=error_message_abort,json=errorMessageAbort,proto3" json:"error_message_abort,omitempty"` } func (m *Status) Reset() { *m = Status{} } @@ -680,6 +682,13 @@ func (m *Status) GetErrorMessageRevert() string { return "" } +func (m *Status) GetErrorMessageAbort() string { + if m != nil { + return m.ErrorMessageAbort + } + return "" +} + // RevertOptions represents the options for reverting a cctx type RevertOptions struct { RevertAddress string `protobuf:"bytes,1,opt,name=revert_address,json=revertAddress,proto3" json:"revert_address,omitempty"` @@ -871,104 +880,105 @@ func init() { } var fileDescriptor_d4c1966807fb5cb2 = []byte{ - // 1540 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4b, 0x6f, 0x23, 0xc7, - 0x11, 0xe6, 0x48, 0x14, 0x45, 0x16, 0x1f, 0x1a, 0xb5, 0xb8, 0xda, 0x59, 0x25, 0xcb, 0x55, 0x98, - 0xac, 0x43, 0x6f, 0xbc, 0x64, 0x2c, 0x03, 0x46, 0x90, 0x1b, 0x97, 0x22, 0xbd, 0x4c, 0xac, 0x07, - 0x86, 0x92, 0x80, 0x18, 0x01, 0xc6, 0xcd, 0x99, 0x16, 0xd9, 0x10, 0x39, 0x4d, 0x4c, 0x37, 0x05, - 0xca, 0xc8, 0x8f, 0xc8, 0x0f, 0xc8, 0x31, 0x87, 0xfc, 0x14, 0x1f, 0x0d, 0xe4, 0x12, 0xe4, 0xb0, - 0x08, 0x76, 0xff, 0x81, 0x4f, 0x39, 0xe4, 0x10, 0xf4, 0x8b, 0x0f, 0x45, 0x91, 0x94, 0xc0, 0x27, - 0x56, 0x57, 0x75, 0x3d, 0x58, 0x5d, 0xdf, 0xd7, 0x3d, 0x70, 0xf0, 0x0d, 0x11, 0x38, 0x1c, 0x62, - 0x1a, 0x37, 0x94, 0xc4, 0x12, 0xd2, 0x08, 0x13, 0xc6, 0xb9, 0xd6, 0x29, 0x31, 0x50, 0x72, 0x20, - 0x66, 0xf5, 0x49, 0xc2, 0x04, 0x43, 0xcf, 0xe7, 0x3e, 0x75, 0xeb, 0x53, 0x5f, 0xf8, 0xec, 0x95, - 0x07, 0x6c, 0xc0, 0xd4, 0xce, 0x86, 0x94, 0xb4, 0xd3, 0xde, 0x47, 0x77, 0x24, 0x9a, 0x5c, 0x0d, - 0x1a, 0x21, 0x93, 0x69, 0x18, 0x8d, 0xf5, 0xbe, 0xea, 0x3f, 0x37, 0xa0, 0xd8, 0x8d, 0xfb, 0x6c, - 0x1a, 0x47, 0xa7, 0x38, 0xc1, 0x63, 0x8e, 0x76, 0x21, 0xc3, 0x49, 0x1c, 0x91, 0xc4, 0x73, 0xf6, - 0x9d, 0x5a, 0xce, 0x37, 0x2b, 0xf4, 0x11, 0x6c, 0x69, 0xc9, 0xd4, 0x47, 0x23, 0x6f, 0x6d, 0xdf, - 0xa9, 0xad, 0xfb, 0x45, 0xad, 0x6e, 0x49, 0x6d, 0x37, 0x42, 0x3f, 0x82, 0x9c, 0x98, 0x05, 0x2c, - 0xa1, 0x03, 0x1a, 0x7b, 0xeb, 0x2a, 0x44, 0x56, 0xcc, 0x4e, 0xd4, 0x1a, 0xbd, 0x81, 0x9c, 0x4c, - 0x1e, 0x88, 0x9b, 0x09, 0xf1, 0xd2, 0xfb, 0x4e, 0xad, 0x74, 0xf0, 0xb2, 0x7e, 0xc7, 0xff, 0x9b, - 0x5c, 0x0d, 0xea, 0xaa, 0xca, 0x16, 0xa3, 0xf1, 0xd9, 0xcd, 0x84, 0xf8, 0xd9, 0xd0, 0x48, 0xa8, - 0x0c, 0x1b, 0x98, 0x73, 0x22, 0xbc, 0x0d, 0x15, 0x5c, 0x2f, 0xd0, 0xe7, 0x90, 0xc1, 0x63, 0x36, - 0x8d, 0x85, 0x97, 0x91, 0xea, 0x37, 0x95, 0x6f, 0xdf, 0xbd, 0x48, 0xfd, 0xfd, 0xdd, 0x8b, 0xdd, - 0x90, 0xf1, 0x31, 0xe3, 0x3c, 0xba, 0xaa, 0x53, 0xd6, 0x18, 0x63, 0x31, 0xac, 0x9f, 0xd3, 0x58, - 0xf8, 0x66, 0x37, 0xfa, 0x29, 0x14, 0x59, 0x9f, 0x93, 0xe4, 0x9a, 0x44, 0xc1, 0x10, 0xf3, 0xa1, - 0xb7, 0xa9, 0xa2, 0x16, 0xac, 0xf2, 0x2d, 0xe6, 0x43, 0xf4, 0x2b, 0xf0, 0xe6, 0x9b, 0xc8, 0x4c, - 0x90, 0x24, 0xc6, 0xa3, 0x60, 0x48, 0xe8, 0x60, 0x28, 0xbc, 0xec, 0xbe, 0x53, 0x4b, 0xfb, 0xbb, - 0xd6, 0xde, 0x36, 0xe6, 0xb7, 0xca, 0x8a, 0x7e, 0x02, 0x85, 0x3e, 0x1e, 0x8d, 0x98, 0x08, 0x68, - 0x1c, 0x91, 0x99, 0x97, 0x53, 0xd1, 0xf3, 0x5a, 0xd7, 0x95, 0x2a, 0x74, 0x00, 0x4f, 0x2e, 0x69, - 0x8c, 0x47, 0xf4, 0x1b, 0x12, 0x05, 0xb2, 0x03, 0x36, 0x32, 0xa8, 0xc8, 0x3b, 0x73, 0xe3, 0x57, - 0x44, 0x60, 0x13, 0x96, 0xc2, 0xae, 0x98, 0x05, 0xc6, 0x82, 0x05, 0x65, 0x71, 0xc0, 0x05, 0x16, - 0x53, 0xee, 0xe5, 0x55, 0x53, 0x3f, 0xab, 0xdf, 0x3b, 0x34, 0xf5, 0xb3, 0x59, 0x67, 0xc9, 0xb7, - 0xa7, 0x5c, 0xfd, 0xb2, 0xb8, 0x43, 0x8b, 0x5e, 0xc3, 0x0e, 0xe5, 0xc1, 0xf2, 0x64, 0x86, 0x78, - 0x34, 0xf2, 0x0a, 0xfb, 0x4e, 0x2d, 0xeb, 0xbb, 0x94, 0xb7, 0xa4, 0x45, 0x1d, 0x7e, 0x0b, 0x8f, - 0x46, 0xe8, 0x10, 0x32, 0xa6, 0x92, 0xb2, 0xaa, 0xe4, 0x93, 0x07, 0x2a, 0x31, 0xc3, 0x67, 0x4a, - 0x30, 0xbe, 0xe8, 0xf7, 0xb0, 0x1d, 0xb2, 0xf8, 0x92, 0x26, 0x63, 0xfd, 0xe7, 0xc6, 0x2c, 0x22, - 0xde, 0x13, 0x15, 0xb0, 0xf1, 0x40, 0xc0, 0xd6, 0x92, 0xdf, 0x11, 0x8b, 0x88, 0xef, 0x86, 0xb7, - 0x34, 0xbf, 0x49, 0x67, 0x8b, 0x6e, 0xb9, 0xfa, 0x35, 0x94, 0x64, 0x47, 0x9b, 0x61, 0x28, 0x07, - 0x81, 0xc6, 0x03, 0x74, 0x0c, 0x3b, 0xb8, 0xcf, 0x12, 0x61, 0xcf, 0xc1, 0x0c, 0x94, 0xf3, 0xa8, - 0x81, 0xda, 0x36, 0xae, 0x2a, 0xa6, 0x72, 0xac, 0x5e, 0x40, 0x5e, 0xf6, 0xe4, 0x64, 0x22, 0x33, - 0x73, 0x89, 0x8c, 0x01, 0xe6, 0xc1, 0x88, 0x8e, 0xa9, 0x0e, 0x9a, 0xf6, 0xb3, 0x03, 0xcc, 0xbf, - 0x94, 0x6b, 0xf4, 0x0a, 0xb6, 0x29, 0x0f, 0x70, 0xd2, 0xa7, 0x22, 0xc1, 0xc9, 0x8d, 0x6e, 0xf2, - 0x9a, 0x6a, 0xf2, 0x16, 0xe5, 0x4d, 0xab, 0x97, 0xf1, 0xaa, 0x7f, 0xda, 0x84, 0xd2, 0xc9, 0x54, - 0x2c, 0xa3, 0x76, 0x0f, 0xb2, 0x09, 0x09, 0x09, 0xbd, 0x9e, 0xe3, 0x76, 0xbe, 0x46, 0x1f, 0x83, - 0x6b, 0x65, 0x7d, 0x82, 0x5d, 0x0b, 0xdd, 0x2d, 0xab, 0xb7, 0xe0, 0x5d, 0xc1, 0xe7, 0xfa, 0xff, - 0x87, 0xcf, 0x05, 0x12, 0xd3, 0xff, 0x13, 0x12, 0x25, 0x71, 0x70, 0x1e, 0xc4, 0x2c, 0x0e, 0x89, - 0xc2, 0x76, 0xda, 0xcf, 0x0a, 0xce, 0x8f, 0xe5, 0x7a, 0xb5, 0x77, 0x99, 0x5b, 0xbd, 0x33, 0xc6, - 0x49, 0x42, 0x43, 0x62, 0xf0, 0x2b, 0x8d, 0xa7, 0x72, 0x8d, 0x6a, 0xe0, 0x1a, 0x23, 0x4b, 0xa8, - 0xb8, 0x09, 0x2e, 0x09, 0xf1, 0x9e, 0xaa, 0x3d, 0x25, 0xbd, 0x47, 0xa9, 0x3b, 0x84, 0x20, 0x04, - 0x69, 0xc5, 0x00, 0x59, 0x65, 0x55, 0xf2, 0x63, 0xf0, 0x7b, 0x1f, 0x39, 0xc0, 0xbd, 0xe4, 0xf0, - 0x0c, 0x64, 0x99, 0xc1, 0x94, 0x93, 0x48, 0xa1, 0x25, 0xed, 0x6f, 0x0e, 0x30, 0x3f, 0xe7, 0x24, - 0x42, 0x47, 0xb0, 0x43, 0x2e, 0x2f, 0x49, 0x28, 0xe8, 0x35, 0x09, 0x16, 0x7f, 0xee, 0x89, 0xea, - 0xe8, 0x73, 0xd3, 0xd1, 0x27, 0xff, 0xd9, 0xd1, 0xae, 0x9c, 0xc4, 0xb9, 0xe7, 0x17, 0xb6, 0x09, - 0xf5, 0xdb, 0xe1, 0x74, 0x23, 0x77, 0x55, 0xd2, 0x95, 0xfd, 0xba, 0xa3, 0xcf, 0x01, 0xe4, 0x59, - 0x4c, 0xa6, 0xfd, 0x2b, 0x72, 0xa3, 0x38, 0x25, 0xe7, 0xcb, 0xd3, 0x39, 0x55, 0x8a, 0x7b, 0xe8, - 0xa7, 0xf0, 0x43, 0xd3, 0xcf, 0x11, 0x14, 0x24, 0x14, 0x02, 0xa6, 0x41, 0xe4, 0x79, 0xfb, 0x4e, - 0x2d, 0x7f, 0xf0, 0xea, 0x21, 0x12, 0x58, 0xc0, 0xce, 0xcf, 0x87, 0x4b, 0x18, 0xbc, 0x93, 0x58, - 0x9e, 0xfd, 0xb0, 0xc4, 0xf2, 0xd7, 0x35, 0xc8, 0x98, 0xea, 0x9b, 0x73, 0x36, 0x74, 0x54, 0x8e, - 0x8f, 0x1f, 0xca, 0x11, 0x8a, 0xd9, 0x2d, 0x2a, 0x7c, 0x09, 0x25, 0x2d, 0x05, 0x63, 0xc2, 0x39, - 0x1e, 0x10, 0x85, 0xdd, 0x9c, 0x5f, 0xd4, 0xda, 0x23, 0xad, 0x94, 0xf7, 0x18, 0x49, 0x12, 0x96, - 0xcc, 0x77, 0x65, 0xf4, 0x3d, 0xa6, 0x94, 0x76, 0xd3, 0xa7, 0x50, 0x1e, 0x61, 0x2e, 0xce, 0x27, - 0x11, 0x16, 0x24, 0x10, 0x74, 0x4c, 0xb8, 0xc0, 0xe3, 0x89, 0x42, 0xfa, 0xba, 0xbf, 0xb3, 0xb0, - 0x9d, 0x59, 0x13, 0xaa, 0x81, 0xa4, 0x1f, 0x49, 0x6d, 0x3e, 0xb9, 0x9c, 0xc6, 0x11, 0x89, 0x14, - 0xac, 0x35, 0x2b, 0x2d, 0xab, 0xd1, 0x2f, 0x60, 0x3b, 0x4c, 0x08, 0x96, 0xec, 0xb9, 0x88, 0xbc, - 0xa1, 0x22, 0xbb, 0xc6, 0xb0, 0x08, 0xfb, 0x4b, 0x28, 0xaf, 0x94, 0x1b, 0x24, 0xe4, 0x9a, 0x24, - 0xc2, 0xa0, 0x17, 0x2d, 0x57, 0xed, 0x2b, 0x4b, 0xf5, 0x7b, 0x07, 0x8a, 0x5a, 0xb4, 0x67, 0xf9, - 0x12, 0x4a, 0xda, 0x2b, 0xc0, 0x51, 0x94, 0x10, 0xce, 0x0d, 0xf3, 0x15, 0xb5, 0xb6, 0xa9, 0x95, - 0xe8, 0x67, 0x50, 0xd2, 0x13, 0x14, 0xdb, 0x24, 0x9a, 0x56, 0xd5, 0x5c, 0x9d, 0xc4, 0x3a, 0xa6, - 0xec, 0x9f, 0x22, 0xf0, 0x79, 0x2c, 0xfd, 0x74, 0x29, 0x28, 0xa5, 0x0d, 0xb5, 0xc8, 0x68, 0xbb, - 0x2c, 0x7b, 0x51, 0xb0, 0x19, 0x6d, 0x9b, 0xdf, 0x4a, 0xc2, 0x55, 0xdb, 0x16, 0x50, 0xdb, 0x78, - 0x14, 0x17, 0x9a, 0xf0, 0x16, 0x87, 0xd5, 0x7f, 0xa5, 0xa1, 0xb0, 0xb8, 0x60, 0xcf, 0x66, 0xc8, - 0x83, 0x4d, 0xd5, 0x4b, 0x66, 0x69, 0xde, 0x2e, 0xe5, 0xb3, 0x48, 0x53, 0x94, 0x1e, 0x0f, 0xbd, - 0x40, 0x27, 0x90, 0x53, 0x57, 0xd9, 0x25, 0x21, 0xdc, 0xd4, 0x70, 0x70, 0x7f, 0x0d, 0xdf, 0xbf, - 0x7b, 0xe1, 0xde, 0xe0, 0xf1, 0xe8, 0xd7, 0xd5, 0xb9, 0x63, 0xd5, 0xcf, 0x4a, 0xb9, 0x43, 0x08, - 0x47, 0x3f, 0x87, 0xad, 0x84, 0x8c, 0xf0, 0x0d, 0x89, 0x6e, 0x4d, 0x5a, 0xc9, 0xa8, 0x6d, 0x13, - 0x3a, 0x90, 0x0f, 0x43, 0x31, 0xb3, 0xc4, 0x90, 0x55, 0xb8, 0x7d, 0xf9, 0xc0, 0xfc, 0x9b, 0xd9, - 0x87, 0x70, 0x8e, 0x03, 0xd4, 0x83, 0x12, 0xd5, 0x6f, 0x84, 0x60, 0xa2, 0xee, 0x3a, 0xc5, 0xc1, - 0xf9, 0xc7, 0x3e, 0x2c, 0xf4, 0xfd, 0xe8, 0x17, 0xe9, 0xca, 0x23, 0xf7, 0x02, 0xb6, 0x98, 0xb9, - 0x40, 0x6d, 0x54, 0xd8, 0x5f, 0xaf, 0xe5, 0x0f, 0x5e, 0x3f, 0x10, 0x75, 0xf5, 0xda, 0xf5, 0x4b, - 0x6c, 0xf5, 0x1a, 0x4e, 0xe0, 0x99, 0x7a, 0x57, 0x87, 0x6c, 0x14, 0x84, 0x2c, 0x16, 0x09, 0x0e, - 0x45, 0x70, 0x4d, 0x12, 0x4e, 0x59, 0x6c, 0x9e, 0x66, 0x9f, 0x3f, 0x90, 0xe1, 0xd4, 0xf8, 0xb7, - 0x8c, 0xfb, 0x85, 0xf6, 0xf6, 0x9f, 0x4e, 0xee, 0x36, 0xa0, 0xdf, 0xcd, 0x87, 0xd2, 0x72, 0x64, - 0xe1, 0x51, 0x0d, 0x5a, 0x01, 0xd3, 0x9b, 0xb4, 0x9c, 0x0a, 0x3b, 0xc8, 0x46, 0xf9, 0xea, 0x0f, - 0x00, 0x0b, 0x46, 0x42, 0x08, 0x4a, 0xa7, 0x24, 0x8e, 0x68, 0x3c, 0x30, 0xbd, 0x75, 0x53, 0x68, - 0x07, 0xb6, 0x8c, 0xce, 0x76, 0xc6, 0x75, 0xd0, 0x36, 0x14, 0xed, 0xea, 0x88, 0xc6, 0x24, 0x72, - 0xd7, 0xa5, 0xca, 0xec, 0xd3, 0x69, 0xdd, 0x34, 0x2a, 0x40, 0x56, 0xcb, 0x24, 0x72, 0x37, 0x50, - 0x1e, 0x36, 0x9b, 0xfa, 0x01, 0xe5, 0x66, 0xf6, 0xd2, 0x7f, 0xf9, 0x73, 0xc5, 0x79, 0xf5, 0x5b, - 0x28, 0xdf, 0x75, 0x51, 0x20, 0x17, 0x0a, 0xc7, 0x4c, 0x74, 0xec, 0xb3, 0xd8, 0x4d, 0xa1, 0x22, - 0xe4, 0x16, 0x4b, 0x47, 0x46, 0x6e, 0xcf, 0x48, 0x38, 0x95, 0xc1, 0xd6, 0x4c, 0xb0, 0x4f, 0xc0, - 0xbd, 0x4d, 0xe0, 0x28, 0x0b, 0xe9, 0x5e, 0xb3, 0xd3, 0x76, 0x53, 0x52, 0xea, 0x34, 0x7b, 0x67, - 0xae, 0x63, 0x76, 0x7f, 0x3d, 0xff, 0x2a, 0x32, 0x39, 0xf3, 0xb0, 0xd9, 0x3b, 0x6f, 0xb5, 0xda, - 0xbd, 0x9e, 0x9b, 0x42, 0x15, 0xd8, 0xeb, 0x1e, 0xf7, 0xce, 0x3b, 0x9d, 0x6e, 0xab, 0xdb, 0x3e, - 0x3e, 0x0b, 0x0e, 0xdb, 0xa7, 0x27, 0xbd, 0xee, 0xd9, 0x89, 0x1f, 0x74, 0xda, 0x6d, 0xd7, 0x41, - 0x3f, 0x06, 0xaf, 0x7b, 0x7c, 0xd1, 0xfc, 0xb2, 0x7b, 0x18, 0xf8, 0xed, 0x56, 0xbb, 0x7b, 0xd1, - 0xf6, 0x83, 0xe6, 0xe1, 0xa1, 0x2f, 0xbd, 0x6d, 0x3d, 0x0d, 0x78, 0xfa, 0x5f, 0x4e, 0x1a, 0x65, - 0x60, 0xed, 0xe2, 0x53, 0x37, 0xa5, 0x7e, 0x0f, 0x6c, 0x49, 0x6f, 0xbe, 0xf8, 0xf6, 0x7d, 0xc5, - 0xf9, 0xee, 0x7d, 0xc5, 0xf9, 0xc7, 0xfb, 0x8a, 0xf3, 0xc7, 0x0f, 0x95, 0xd4, 0x77, 0x1f, 0x2a, - 0xa9, 0xbf, 0x7d, 0xa8, 0xa4, 0xbe, 0x7a, 0x3d, 0xa0, 0x62, 0x38, 0xed, 0xd7, 0x43, 0x36, 0x56, - 0x1f, 0x7b, 0xaf, 0xf5, 0x77, 0x5f, 0xcc, 0x22, 0xd2, 0x98, 0x2d, 0x7f, 0x5e, 0xca, 0x57, 0x1d, - 0xef, 0x67, 0xd4, 0x20, 0x7d, 0xf6, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x07, 0xe1, 0x03, 0xdd, - 0x8c, 0x0e, 0x00, 0x00, + // 1553 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4d, 0x6f, 0x1b, 0xc7, + 0x19, 0xe6, 0x5a, 0x14, 0x45, 0xbe, 0xfc, 0xd0, 0x6a, 0x44, 0xcb, 0x6b, 0xb5, 0xa6, 0x55, 0xa6, + 0x4e, 0x19, 0x37, 0x26, 0x1b, 0x05, 0x08, 0x8a, 0xde, 0x68, 0x8a, 0x8c, 0xd9, 0x46, 0x1f, 0x58, + 0x4a, 0x02, 0x1a, 0x14, 0xd8, 0x0c, 0x77, 0x47, 0xe4, 0x40, 0xe4, 0x0e, 0xb1, 0x33, 0x14, 0xa8, + 0xa0, 0xb7, 0xfe, 0x81, 0xfe, 0x80, 0x1e, 0x7b, 0xe8, 0x4f, 0xc9, 0x31, 0xc7, 0xa2, 0x07, 0xa3, + 0xb0, 0xff, 0x41, 0x4e, 0x3d, 0xf4, 0x50, 0xcc, 0x17, 0x3f, 0x54, 0x55, 0x52, 0x03, 0x9f, 0x38, + 0xf3, 0x7e, 0xf3, 0x9d, 0xf7, 0x79, 0x66, 0x16, 0xf6, 0xbf, 0x25, 0x02, 0x87, 0x43, 0x4c, 0xe3, + 0x86, 0x5a, 0xb1, 0x84, 0x34, 0xc2, 0x84, 0x71, 0xae, 0x65, 0x6a, 0x19, 0xa8, 0x75, 0x20, 0x66, + 0xf5, 0x49, 0xc2, 0x04, 0x43, 0xcf, 0xe6, 0x3e, 0x75, 0xeb, 0x53, 0x5f, 0xf8, 0xec, 0x96, 0x07, + 0x6c, 0xc0, 0x94, 0x65, 0x43, 0xae, 0xb4, 0xd3, 0xee, 0xc7, 0xb7, 0x24, 0x9a, 0x5c, 0x0e, 0x1a, + 0x21, 0x93, 0x69, 0x18, 0x8d, 0xb5, 0x5d, 0xf5, 0x5f, 0xeb, 0x50, 0xec, 0xc6, 0x7d, 0x36, 0x8d, + 0xa3, 0x13, 0x9c, 0xe0, 0x31, 0x47, 0x3b, 0x90, 0xe1, 0x24, 0x8e, 0x48, 0xe2, 0x39, 0x7b, 0x4e, + 0x2d, 0xe7, 0x9b, 0x1d, 0xfa, 0x18, 0x36, 0xf5, 0xca, 0xd4, 0x47, 0x23, 0xef, 0xd1, 0x9e, 0x53, + 0x5b, 0xf3, 0x8b, 0x5a, 0xdc, 0x92, 0xd2, 0x6e, 0x84, 0x7e, 0x02, 0x39, 0x31, 0x0b, 0x58, 0x42, + 0x07, 0x34, 0xf6, 0xd6, 0x54, 0x88, 0xac, 0x98, 0x1d, 0xab, 0x3d, 0x7a, 0x0d, 0x39, 0x99, 0x3c, + 0x10, 0xd7, 0x13, 0xe2, 0xa5, 0xf7, 0x9c, 0x5a, 0x69, 0xff, 0x45, 0xfd, 0x96, 0xff, 0x37, 0xb9, + 0x1c, 0xd4, 0x55, 0x95, 0x2d, 0x46, 0xe3, 0xd3, 0xeb, 0x09, 0xf1, 0xb3, 0xa1, 0x59, 0xa1, 0x32, + 0xac, 0x63, 0xce, 0x89, 0xf0, 0xd6, 0x55, 0x70, 0xbd, 0x41, 0x5f, 0x40, 0x06, 0x8f, 0xd9, 0x34, + 0x16, 0x5e, 0x46, 0x8a, 0x5f, 0x57, 0xbe, 0x7b, 0xfb, 0x3c, 0xf5, 0x8f, 0xb7, 0xcf, 0x77, 0x42, + 0xc6, 0xc7, 0x8c, 0xf3, 0xe8, 0xb2, 0x4e, 0x59, 0x63, 0x8c, 0xc5, 0xb0, 0x7e, 0x46, 0x63, 0xe1, + 0x1b, 0x6b, 0xf4, 0x11, 0x14, 0x59, 0x9f, 0x93, 0xe4, 0x8a, 0x44, 0xc1, 0x10, 0xf3, 0xa1, 0xb7, + 0xa1, 0xa2, 0x16, 0xac, 0xf0, 0x0d, 0xe6, 0x43, 0xf4, 0x6b, 0xf0, 0xe6, 0x46, 0x64, 0x26, 0x48, + 0x12, 0xe3, 0x51, 0x30, 0x24, 0x74, 0x30, 0x14, 0x5e, 0x76, 0xcf, 0xa9, 0xa5, 0xfd, 0x1d, 0xab, + 0x6f, 0x1b, 0xf5, 0x1b, 0xa5, 0x45, 0x3f, 0x83, 0x42, 0x1f, 0x8f, 0x46, 0x4c, 0x04, 0x34, 0x8e, + 0xc8, 0xcc, 0xcb, 0xa9, 0xe8, 0x79, 0x2d, 0xeb, 0x4a, 0x11, 0xda, 0x87, 0xc7, 0x17, 0x34, 0xc6, + 0x23, 0xfa, 0x2d, 0x89, 0x02, 0xd9, 0x01, 0x1b, 0x19, 0x54, 0xe4, 0xed, 0xb9, 0xf2, 0x6b, 0x22, + 0xb0, 0x09, 0x4b, 0x61, 0x47, 0xcc, 0x02, 0xa3, 0xc1, 0x82, 0xb2, 0x38, 0xe0, 0x02, 0x8b, 0x29, + 0xf7, 0xf2, 0xaa, 0xa9, 0x9f, 0xd7, 0xef, 0x1c, 0x9a, 0xfa, 0xe9, 0xac, 0xb3, 0xe4, 0xdb, 0x53, + 0xae, 0x7e, 0x59, 0xdc, 0x22, 0x45, 0xaf, 0x60, 0x9b, 0xf2, 0x60, 0x79, 0x32, 0x43, 0x3c, 0x1a, + 0x79, 0x85, 0x3d, 0xa7, 0x96, 0xf5, 0x5d, 0xca, 0x5b, 0x52, 0xa3, 0x0e, 0xbf, 0x85, 0x47, 0x23, + 0x74, 0x00, 0x19, 0x53, 0x49, 0x59, 0x55, 0xf2, 0xe9, 0x3d, 0x95, 0x98, 0xe1, 0x33, 0x25, 0x18, + 0x5f, 0xf4, 0x07, 0xd8, 0x0a, 0x59, 0x7c, 0x41, 0x93, 0xb1, 0xfe, 0x73, 0x63, 0x16, 0x11, 0xef, + 0xb1, 0x0a, 0xd8, 0xb8, 0x27, 0x60, 0x6b, 0xc9, 0xef, 0x90, 0x45, 0xc4, 0x77, 0xc3, 0x1b, 0x92, + 0xdf, 0xa6, 0xb3, 0x45, 0xb7, 0x5c, 0xfd, 0x06, 0x4a, 0xb2, 0xa3, 0xcd, 0x30, 0x94, 0x83, 0x40, + 0xe3, 0x01, 0x3a, 0x82, 0x6d, 0xdc, 0x67, 0x89, 0xb0, 0xe7, 0x60, 0x06, 0xca, 0x79, 0xd0, 0x40, + 0x6d, 0x19, 0x57, 0x15, 0x53, 0x39, 0x56, 0xcf, 0x21, 0x2f, 0x7b, 0x72, 0x3c, 0x91, 0x99, 0xb9, + 0x44, 0xc6, 0x00, 0xf3, 0x60, 0x44, 0xc7, 0x54, 0x07, 0x4d, 0xfb, 0xd9, 0x01, 0xe6, 0x5f, 0xc9, + 0x3d, 0x7a, 0x09, 0x5b, 0x94, 0x07, 0x38, 0xe9, 0x53, 0x91, 0xe0, 0xe4, 0x5a, 0x37, 0xf9, 0x91, + 0x6a, 0xf2, 0x26, 0xe5, 0x4d, 0x2b, 0x97, 0xf1, 0xaa, 0x7f, 0xd9, 0x80, 0xd2, 0xf1, 0x54, 0x2c, + 0xa3, 0x76, 0x17, 0xb2, 0x09, 0x09, 0x09, 0xbd, 0x9a, 0xe3, 0x76, 0xbe, 0x47, 0x9f, 0x80, 0x6b, + 0xd7, 0xfa, 0x04, 0xbb, 0x16, 0xba, 0x9b, 0x56, 0x6e, 0xc1, 0xbb, 0x82, 0xcf, 0xb5, 0x1f, 0x87, + 0xcf, 0x05, 0x12, 0xd3, 0xff, 0x17, 0x12, 0x25, 0x71, 0x70, 0x1e, 0xc4, 0x2c, 0x0e, 0x89, 0xc2, + 0x76, 0xda, 0xcf, 0x0a, 0xce, 0x8f, 0xe4, 0x7e, 0xb5, 0x77, 0x99, 0x1b, 0xbd, 0x33, 0xca, 0x49, + 0x42, 0x43, 0x62, 0xf0, 0x2b, 0x95, 0x27, 0x72, 0x8f, 0x6a, 0xe0, 0x1a, 0x25, 0x4b, 0xa8, 0xb8, + 0x0e, 0x2e, 0x08, 0xf1, 0x9e, 0x28, 0x9b, 0x92, 0xb6, 0x51, 0xe2, 0x0e, 0x21, 0x08, 0x41, 0x5a, + 0x31, 0x40, 0x56, 0x69, 0xd5, 0xfa, 0x21, 0xf8, 0xbd, 0x8b, 0x1c, 0xe0, 0x4e, 0x72, 0x78, 0x0a, + 0xb2, 0xcc, 0x60, 0xca, 0x49, 0xa4, 0xd0, 0x92, 0xf6, 0x37, 0x06, 0x98, 0x9f, 0x71, 0x12, 0xa1, + 0x43, 0xd8, 0x26, 0x17, 0x17, 0x24, 0x14, 0xf4, 0x8a, 0x04, 0x8b, 0x3f, 0xf7, 0x58, 0x75, 0xf4, + 0x99, 0xe9, 0xe8, 0xe3, 0xff, 0xee, 0x68, 0x57, 0x4e, 0xe2, 0xdc, 0xf3, 0x4b, 0xdb, 0x84, 0xfa, + 0xcd, 0x70, 0xba, 0x91, 0x3b, 0x2a, 0xe9, 0x8a, 0xbd, 0xee, 0xe8, 0x33, 0x00, 0x79, 0x16, 0x93, + 0x69, 0xff, 0x92, 0x5c, 0x2b, 0x4e, 0xc9, 0xf9, 0xf2, 0x74, 0x4e, 0x94, 0xe0, 0x0e, 0xfa, 0x29, + 0x7c, 0x68, 0xfa, 0x39, 0x84, 0x82, 0x84, 0x42, 0xc0, 0x34, 0x88, 0x3c, 0x6f, 0xcf, 0xa9, 0xe5, + 0xf7, 0x5f, 0xde, 0x47, 0x02, 0x0b, 0xd8, 0xf9, 0xf9, 0x70, 0x09, 0x83, 0xb7, 0x12, 0xcb, 0xd3, + 0x0f, 0x4b, 0x2c, 0x7f, 0x5a, 0x83, 0x8c, 0xa9, 0xbe, 0x39, 0x67, 0x43, 0x47, 0xe5, 0xf8, 0xe4, + 0xbe, 0x1c, 0xa1, 0x98, 0xdd, 0xa0, 0xc2, 0x17, 0x50, 0xd2, 0xab, 0x60, 0x4c, 0x38, 0xc7, 0x03, + 0xa2, 0xb0, 0x9b, 0xf3, 0x8b, 0x5a, 0x7a, 0xa8, 0x85, 0xf2, 0x1e, 0x23, 0x49, 0xc2, 0x92, 0xb9, + 0x55, 0x46, 0xdf, 0x63, 0x4a, 0x68, 0x8d, 0x3e, 0x83, 0xf2, 0x08, 0x73, 0x71, 0x36, 0x89, 0xb0, + 0x20, 0x81, 0xa0, 0x63, 0xc2, 0x05, 0x1e, 0x4f, 0x14, 0xd2, 0xd7, 0xfc, 0xed, 0x85, 0xee, 0xd4, + 0xaa, 0x50, 0x0d, 0x24, 0xfd, 0x48, 0x6a, 0xf3, 0xc9, 0xc5, 0x34, 0x8e, 0x48, 0xa4, 0x60, 0xad, + 0x59, 0x69, 0x59, 0x8c, 0x7e, 0x09, 0x5b, 0x61, 0x42, 0xb0, 0x64, 0xcf, 0x45, 0xe4, 0x75, 0x15, + 0xd9, 0x35, 0x8a, 0x45, 0xd8, 0x5f, 0x41, 0x79, 0xa5, 0xdc, 0x20, 0x21, 0x57, 0x24, 0x11, 0x06, + 0xbd, 0x68, 0xb9, 0x6a, 0x5f, 0x69, 0xd4, 0x08, 0xaf, 0x78, 0x28, 0xbe, 0x35, 0x60, 0xdd, 0x5a, + 0x76, 0x50, 0x65, 0x55, 0x7f, 0x70, 0xa0, 0xa8, 0x5d, 0xed, 0xd9, 0xbf, 0x80, 0x92, 0xce, 0x12, + 0xe0, 0x28, 0x4a, 0x08, 0xe7, 0x86, 0x29, 0x8b, 0x5a, 0xda, 0xd4, 0x42, 0xf4, 0x73, 0x28, 0xe9, + 0x89, 0x8b, 0x6d, 0x51, 0x9a, 0x86, 0xd5, 0x1c, 0x1e, 0xc7, 0xa6, 0x9c, 0x8f, 0xa0, 0xa8, 0x0a, + 0x98, 0xc7, 0xd2, 0x4f, 0x9d, 0x82, 0x12, 0xda, 0x50, 0x8b, 0x8c, 0xf6, 0x54, 0x64, 0xef, 0x0a, + 0x36, 0xa3, 0x3d, 0x96, 0x37, 0x92, 0xa0, 0x95, 0xd9, 0x02, 0x9a, 0xeb, 0x0f, 0xe2, 0x4e, 0x13, + 0xde, 0xe2, 0xb6, 0xfa, 0xef, 0x34, 0x14, 0x16, 0x17, 0xf2, 0xe9, 0x0c, 0x79, 0xb0, 0xa1, 0x7a, + 0xcf, 0xec, 0xb5, 0x60, 0xb7, 0xf2, 0x19, 0xa5, 0x29, 0x4d, 0x8f, 0x93, 0xde, 0xa0, 0x63, 0xc8, + 0xa9, 0xab, 0xef, 0x82, 0x10, 0x6e, 0x6a, 0xd8, 0xbf, 0xbb, 0x86, 0x1f, 0xde, 0x3e, 0x77, 0xaf, + 0xf1, 0x78, 0xf4, 0x9b, 0xea, 0xdc, 0xb1, 0xea, 0x67, 0xe5, 0xba, 0x43, 0x08, 0x47, 0xbf, 0x80, + 0xcd, 0x84, 0x8c, 0xf0, 0x35, 0x89, 0x6e, 0x4c, 0x66, 0xc9, 0x88, 0x6d, 0x13, 0x3a, 0x90, 0x0f, + 0x43, 0x31, 0xb3, 0x44, 0x92, 0x55, 0x38, 0x7f, 0x71, 0x0f, 0x5e, 0x0c, 0x56, 0x20, 0x9c, 0xe3, + 0x06, 0xf5, 0xa0, 0x44, 0xf5, 0x9b, 0x22, 0x98, 0xa8, 0xbb, 0x51, 0x71, 0x76, 0xfe, 0xa1, 0x0f, + 0x11, 0x7d, 0x9f, 0xfa, 0x45, 0xba, 0xf2, 0x28, 0x3e, 0x87, 0x4d, 0x66, 0x2e, 0x5c, 0x1b, 0x15, + 0xf6, 0xd6, 0x6a, 0xf9, 0xfd, 0x57, 0xf7, 0x44, 0x5d, 0xbd, 0xa6, 0xfd, 0x12, 0x5b, 0xbd, 0xb6, + 0x13, 0x78, 0xaa, 0xde, 0xe1, 0x21, 0x1b, 0x05, 0x21, 0x8b, 0x45, 0x82, 0x43, 0x11, 0x5c, 0x91, + 0x84, 0x53, 0x16, 0x9b, 0xa7, 0xdc, 0x17, 0xf7, 0x64, 0x38, 0x31, 0xfe, 0x2d, 0xe3, 0x7e, 0xae, + 0xbd, 0xfd, 0x27, 0x93, 0xdb, 0x15, 0xe8, 0xf7, 0xf3, 0xa1, 0xb4, 0x9c, 0x5a, 0x78, 0x50, 0x83, + 0x56, 0xc0, 0xf4, 0x3a, 0x2d, 0xa7, 0xc2, 0x0e, 0xb2, 0x11, 0xbe, 0xfc, 0x23, 0xc0, 0x82, 0xc1, + 0x10, 0x82, 0xd2, 0x09, 0x89, 0x23, 0x1a, 0x0f, 0x4c, 0x6f, 0xdd, 0x14, 0xda, 0x86, 0x4d, 0x23, + 0xb3, 0x9d, 0x71, 0x1d, 0xb4, 0x05, 0x45, 0xbb, 0x3b, 0xa4, 0x31, 0x89, 0xdc, 0x35, 0x29, 0x32, + 0x76, 0x3a, 0xad, 0x9b, 0x46, 0x05, 0xc8, 0xea, 0x35, 0x89, 0xdc, 0x75, 0x94, 0x87, 0x8d, 0xa6, + 0x7e, 0x70, 0xb9, 0x99, 0xdd, 0xf4, 0xdf, 0xfe, 0x5a, 0x71, 0x5e, 0xfe, 0x0e, 0xca, 0xb7, 0x5d, + 0x2c, 0xc8, 0x85, 0xc2, 0x11, 0x13, 0x1d, 0xfb, 0x8c, 0x76, 0x53, 0xa8, 0x08, 0xb9, 0xc5, 0xd6, + 0x91, 0x91, 0xdb, 0x33, 0x12, 0x4e, 0x65, 0xb0, 0x47, 0x26, 0xd8, 0xa7, 0xe0, 0xde, 0x24, 0x7c, + 0x94, 0x85, 0x74, 0xaf, 0xd9, 0x69, 0xbb, 0x29, 0xb9, 0xea, 0x34, 0x7b, 0xa7, 0xae, 0x63, 0xac, + 0xbf, 0x99, 0x7f, 0x45, 0x99, 0x9c, 0x79, 0xd8, 0xe8, 0x9d, 0xb5, 0x5a, 0xed, 0x5e, 0xcf, 0x4d, + 0xa1, 0x0a, 0xec, 0x76, 0x8f, 0x7a, 0x67, 0x9d, 0x4e, 0xb7, 0xd5, 0x6d, 0x1f, 0x9d, 0x06, 0x07, + 0xed, 0x93, 0xe3, 0x5e, 0xf7, 0xf4, 0xd8, 0x0f, 0x3a, 0xed, 0xb6, 0xeb, 0xa0, 0x9f, 0x82, 0xd7, + 0x3d, 0x3a, 0x6f, 0x7e, 0xd5, 0x3d, 0x08, 0xfc, 0x76, 0xab, 0xdd, 0x3d, 0x6f, 0xfb, 0x41, 0xf3, + 0xe0, 0xc0, 0x97, 0xde, 0xb6, 0x9e, 0x06, 0x3c, 0xf9, 0x1f, 0x27, 0x8d, 0x32, 0xf0, 0xe8, 0xfc, + 0x33, 0x37, 0xa5, 0x7e, 0xf7, 0x6d, 0x49, 0xaf, 0xbf, 0xfc, 0xee, 0x5d, 0xc5, 0xf9, 0xfe, 0x5d, + 0xc5, 0xf9, 0xe7, 0xbb, 0x8a, 0xf3, 0xe7, 0xf7, 0x95, 0xd4, 0xf7, 0xef, 0x2b, 0xa9, 0xbf, 0xbf, + 0xaf, 0xa4, 0xbe, 0x7e, 0x35, 0xa0, 0x62, 0x38, 0xed, 0xd7, 0x43, 0x36, 0x56, 0x1f, 0x87, 0xaf, + 0xf4, 0x77, 0x62, 0xcc, 0x22, 0xd2, 0x98, 0x2d, 0x7f, 0x8e, 0xca, 0x57, 0x20, 0xef, 0x67, 0xd4, + 0x20, 0x7d, 0xfe, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x10, 0xf5, 0x9b, 0x4a, 0xbc, 0x0e, 0x00, + 0x00, } func (m *InboundParams) Marshal() (dAtA []byte, err error) { @@ -1333,6 +1343,13 @@ func (m *Status) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.ErrorMessageAbort) > 0 { + i -= len(m.ErrorMessageAbort) + copy(dAtA[i:], m.ErrorMessageAbort) + i = encodeVarintCrossChainTx(dAtA, i, uint64(len(m.ErrorMessageAbort))) + i-- + dAtA[i] = 0x42 + } if len(m.ErrorMessageRevert) > 0 { i -= len(m.ErrorMessageRevert) copy(dAtA[i:], m.ErrorMessageRevert) @@ -1743,6 +1760,10 @@ func (m *Status) Size() (n int) { if l > 0 { n += 1 + l + sovCrossChainTx(uint64(l)) } + l = len(m.ErrorMessageAbort) + if l > 0 { + n += 1 + l + sovCrossChainTx(uint64(l)) + } return n } @@ -3109,6 +3130,38 @@ func (m *Status) Unmarshal(dAtA []byte) error { } m.ErrorMessageRevert = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ErrorMessageAbort", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrossChainTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCrossChainTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCrossChainTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ErrorMessageAbort = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCrossChainTx(dAtA[iNdEx:]) diff --git a/x/crosschain/types/expected_keepers.go b/x/crosschain/types/expected_keepers.go index 8b8dd40dee..10edb622ab 100644 --- a/x/crosschain/types/expected_keepers.go +++ b/x/crosschain/types/expected_keepers.go @@ -151,7 +151,7 @@ type FungibleKeeper interface { protocolContractVersion ProtocolContractVersion, isCrossChainCall bool, ) (*evmtypes.MsgEthereumTxResponse, bool, error) - ProcessV2RevertDeposit( + ProcessRevert( ctx sdk.Context, inboundSender string, amount *big.Int, @@ -162,6 +162,17 @@ type FungibleKeeper interface { callOnRevert bool, revertMessage []byte, ) (*evmtypes.MsgEthereumTxResponse, error) + ProcessAbort( + ctx sdk.Context, + inboundSender string, + amount *big.Int, + outgoing bool, + chainID int64, + coinType coin.CoinType, + asset string, + abortAddress ethcommon.Address, + revertMessage []byte, + ) (*evmtypes.MsgEthereumTxResponse, error) CallUniswapV2RouterSwapExactTokensForTokens( ctx sdk.Context, sender ethcommon.Address, diff --git a/x/crosschain/types/status.go b/x/crosschain/types/status.go index 6e9ba4891a..8af48e702b 100644 --- a/x/crosschain/types/status.go +++ b/x/crosschain/types/status.go @@ -9,9 +9,10 @@ type StatusMessages struct { StatusMessage string `json:"status_message"` ErrorMessageOutbound string `json:"error_message_outbound"` ErrorMessageRevert string `json:"error_message_revert"` + ErrorMessageAbort string `json:"error_message_abort"` } -func (m *Status) AbortRefunded() { +func (m *Status) SetAbortRefunded() { m.IsAbortRefunded = true m.StatusMessage = "CCTX aborted and Refunded" } @@ -46,6 +47,9 @@ func (m *Status) UpdateErrorMessages(messages StatusMessages) { if messages.ErrorMessageRevert != "" { m.ErrorMessageRevert = messages.ErrorMessageRevert } + if messages.ErrorMessageAbort != "" { + m.ErrorMessageAbort = messages.ErrorMessageAbort + } } func (m *Status) ValidateTransition(newStatus CctxStatus) bool { diff --git a/x/crosschain/types/status_test.go b/x/crosschain/types/status_test.go index a73a1b5cb7..786f32a40c 100644 --- a/x/crosschain/types/status_test.go +++ b/x/crosschain/types/status_test.go @@ -17,7 +17,7 @@ func TestStatus_AbortRefunded(t *testing.T) { LastUpdateTimestamp: 0, IsAbortRefunded: false, } - status.AbortRefunded() + status.SetAbortRefunded() require.Equal(t, status.IsAbortRefunded, true) require.Equal(t, status.StatusMessage, "CCTX aborted and Refunded") }) diff --git a/x/fungible/keeper/deposits.go b/x/fungible/keeper/deposits.go index 07a0649bec..64d050bd79 100644 --- a/x/fungible/keeper/deposits.go +++ b/x/fungible/keeper/deposits.go @@ -1,10 +1,12 @@ package keeper import ( + "fmt" "math/big" sdk "github.com/cosmos/cosmos-sdk/types" - eth "github.com/ethereum/go-ethereum/common" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/protocol-contracts/pkg/systemcontract.sol" @@ -14,7 +16,7 @@ import ( ) // DepositCoinZeta immediately mints ZETA to the EVM account -func (k Keeper) DepositCoinZeta(ctx sdk.Context, to eth.Address, amount *big.Int) error { +func (k Keeper) DepositCoinZeta(ctx sdk.Context, to ethcommon.Address, amount *big.Int) error { zetaToAddress := sdk.AccAddress(to.Bytes()) return k.MintZetaToEVMAccount(ctx, zetaToAddress, amount) } @@ -28,7 +30,7 @@ func (k Keeper) DepositCoinsToFungibleModule(ctx sdk.Context, amount *big.Int) e func (k Keeper) ZRC20DepositAndCallContract( ctx sdk.Context, from []byte, - to eth.Address, + to ethcommon.Address, amount *big.Int, senderChainID int64, message []byte, @@ -45,7 +47,7 @@ func (k Keeper) ZRC20DepositAndCallContract( // handle the deposit for protocol contract version 2 if protocolContractVersion == crosschaintypes.ProtocolContractVersion_V2 { - return k.ProcessV2Deposit( + return k.ProcessDeposit( ctx, from, senderChainID, @@ -65,10 +67,10 @@ func (k Keeper) ZRC20DepositAndCallContract( if acc != nil && acc.IsContract() { context := systemcontract.ZContext{ Origin: from, - Sender: eth.Address{}, + Sender: ethcommon.Address{}, ChainID: big.NewInt(senderChainID), } - res, err := k.DepositZRC20AndCallContract(ctx, context, zrc20Contract, to, amount, message) + res, err := k.CallDepositAndCall(ctx, context, zrc20Contract, to, amount, message) return res, true, err } @@ -81,6 +83,156 @@ func (k Keeper) ZRC20DepositAndCallContract( return res, false, err } +// ProcessDeposit handles a deposit from an inbound tx with protocol version 2 +// returns [txResponse, isContractCall, error] +// isContractCall is true if the message is non empty +func (k Keeper) ProcessDeposit( + ctx sdk.Context, + from []byte, + senderChainID int64, + zrc20Addr ethcommon.Address, + to ethcommon.Address, + amount *big.Int, + message []byte, + coinType coin.CoinType, + isCrossChainCall bool, +) (*evmtypes.MsgEthereumTxResponse, bool, error) { + if coinType == coin.CoinType_Zeta { + return nil, false, errors.New("ZETA asset is currently unsupported for deposit with V2 protocol contracts") + } + + context := systemcontract.ZContext{ + Origin: []byte{}, + Sender: ethcommon.BytesToAddress(from), + ChainID: big.NewInt(senderChainID), + } + + if coinType == coin.CoinType_NoAssetCall { + // simple call + res, err := k.CallExecute(ctx, context, zrc20Addr, amount, to, message) + return res, true, err + } else if isCrossChainCall { + // call with asset + res, err := k.CallDepositAndCallZRC20(ctx, context, zrc20Addr, amount, to, message) + return res, true, err + } + + // simple deposit + res, err := k.DepositZRC20(ctx, zrc20Addr, to, amount) + return res, false, err +} + +// ProcessRevert handles a revert deposit from an inbound tx with protocol version 2 +func (k Keeper) ProcessRevert( + ctx sdk.Context, + inboundSender string, + amount *big.Int, + chainID int64, + coinType coin.CoinType, + asset string, + revertAddress ethcommon.Address, + callOnRevert bool, + revertMessage []byte, +) (*evmtypes.MsgEthereumTxResponse, error) { + if coinType == coin.CoinType_Zeta { + return nil, errors.New("ZETA asset is currently unsupported for revert with V2 protocol contracts") + } + + // get the zrc20 contract + zrc20Addr, _, err := k.getAndCheckZRC20( + ctx, + amount, + chainID, + coinType, + asset, + ) + if err != nil { + return nil, err + } + + switch coinType { + case coin.CoinType_NoAssetCall: + if callOnRevert { + // no asset, call simple revert + res, err := k.CallExecuteRevert(ctx, inboundSender, zrc20Addr, amount, revertAddress, revertMessage) + return res, err + } else { + // no asset, no call, do nothing + return nil, nil + } + case coin.CoinType_ERC20, coin.CoinType_Gas: + if callOnRevert { + // revert with a ZRC20 asset + res, err := k.CallDepositAndRevert( + ctx, + inboundSender, + zrc20Addr, + amount, + revertAddress, + revertMessage, + ) + return res, err + } else { + // simply deposit back to the revert address + res, err := k.DepositZRC20(ctx, zrc20Addr, revertAddress, amount) + return res, err + } + } + + return nil, fmt.Errorf("unsupported coin type for revert %s", coinType) +} + +// ProcessAbort handles an abort deposit from an inbound tx with protocol version 2 +func (k Keeper) ProcessAbort( + ctx sdk.Context, + inboundSender string, + amount *big.Int, + outgoing bool, + chainID int64, + coinType coin.CoinType, + asset string, + abortAddress ethcommon.Address, + revertMessage []byte, +) (*evmtypes.MsgEthereumTxResponse, error) { + if coinType == coin.CoinType_Zeta { + return nil, errors.New("ZETA asset is currently unsupported for abort with V2 protocol contracts") + } + + // get the zrc20 contract + zrc20Addr, _, err := k.getAndCheckZRC20( + ctx, + amount, + chainID, + coinType, + asset, + ) + if err != nil { + return nil, err + } + + // if the cctx contains asset, the asset is first deposited to the abort address, separately from onAbort call + if coinType == coin.CoinType_ERC20 || coinType == coin.CoinType_Gas { + // simply deposit back to the revert address + // if the deposit fails, processing the abort entirely fails + // MsgRefundAbort can still be used to retry the operation later on + if _, err := k.DepositZRC20(ctx, zrc20Addr, abortAddress, amount); err != nil { + return nil, err + } + } + + // call onAbort + return k.CallExecuteAbort( + ctx, + inboundSender, + zrc20Addr, + amount, + outgoing, + big.NewInt(chainID), + abortAddress, + revertMessage, + ) +} + // getAndCheckZRC20 returns the ZRC20 contract address and foreign coin for the given chainID and asset // it also checks if the foreign coin is paused and if the cap is reached func (k Keeper) getAndCheckZRC20( @@ -89,8 +241,8 @@ func (k Keeper) getAndCheckZRC20( chainID int64, coinType coin.CoinType, asset string, -) (eth.Address, types.ForeignCoins, error) { - var zrc20Contract eth.Address +) (ethcommon.Address, types.ForeignCoins, error) { + var zrc20Contract ethcommon.Address var foreignCoin types.ForeignCoins var found bool @@ -103,19 +255,19 @@ func (k Keeper) getAndCheckZRC20( if coinType == coin.CoinType_Gas || coinType == coin.CoinType_NoAssetCall { foreignCoin, found = k.GetGasCoinForForeignCoin(ctx, chainID) if !found { - return eth.Address{}, types.ForeignCoins{}, crosschaintypes.ErrGasCoinNotFound + return ethcommon.Address{}, types.ForeignCoins{}, crosschaintypes.ErrGasCoinNotFound } } else { foreignCoin, found = k.GetForeignCoinFromAsset(ctx, asset, chainID) if !found { - return eth.Address{}, types.ForeignCoins{}, crosschaintypes.ErrForeignCoinNotFound + return ethcommon.Address{}, types.ForeignCoins{}, crosschaintypes.ErrForeignCoinNotFound } } - zrc20Contract = eth.HexToAddress(foreignCoin.Zrc20ContractAddress) + zrc20Contract = ethcommon.HexToAddress(foreignCoin.Zrc20ContractAddress) // check if foreign coin is paused if foreignCoin.Paused { - return eth.Address{}, types.ForeignCoins{}, types.ErrPausedZRC20 + return ethcommon.Address{}, types.ForeignCoins{}, types.ErrPausedZRC20 } // check foreign coins cap if it has a cap @@ -123,11 +275,11 @@ func (k Keeper) getAndCheckZRC20( liquidityCap := foreignCoin.LiquidityCap.BigInt() totalSupply, err := k.TotalSupplyZRC4(ctx, zrc20Contract) if err != nil { - return eth.Address{}, types.ForeignCoins{}, err + return ethcommon.Address{}, types.ForeignCoins{}, err } newSupply := new(big.Int).Add(totalSupply, amount) if newSupply.Cmp(liquidityCap) > 0 { - return eth.Address{}, types.ForeignCoins{}, types.ErrForeignCoinCapReached + return ethcommon.Address{}, types.ForeignCoins{}, types.ErrForeignCoinCapReached } } diff --git a/x/fungible/keeper/deposits_test.go b/x/fungible/keeper/deposits_test.go index 27b1af4837..e75bc5aa20 100644 --- a/x/fungible/keeper/deposits_test.go +++ b/x/fungible/keeper/deposits_test.go @@ -1,26 +1,128 @@ package keeper_test import ( + "cosmossdk.io/math" + "github.com/pkg/errors" + "github.com/stretchr/testify/mock" + "github.com/zeta-chain/node/cmd/zetacored/config" + "github.com/zeta-chain/node/testutil/contracts" + crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" "math/big" "testing" - "cosmossdk.io/errors" - "cosmossdk.io/math" - sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/mock" + "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" - - "github.com/zeta-chain/node/cmd/zetacored/config" "github.com/zeta-chain/node/pkg/chains" "github.com/zeta-chain/node/pkg/coin" - "github.com/zeta-chain/node/testutil/contracts" + "github.com/zeta-chain/node/pkg/contracts/testdappv2" keepertest "github.com/zeta-chain/node/testutil/keeper" "github.com/zeta-chain/node/testutil/sample" - crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" + fungiblekeeper "github.com/zeta-chain/node/x/fungible/keeper" "github.com/zeta-chain/node/x/fungible/types" ) +// getTestDAppNoMessageIndex queries the no message index of the test dapp v2 contract +func getTestDAppNoMessageIndex( + t *testing.T, + ctx sdk.Context, + k fungiblekeeper.Keeper, + contract, + account common.Address, +) string { + testDAppABI, err := testdappv2.TestDAppV2MetaData.GetAbi() + require.NoError(t, err) + res, err := k.CallEVM( + ctx, + *testDAppABI, + types.ModuleAddressEVM, + contract, + fungiblekeeper.BigIntZero, + nil, + false, + false, + "getNoMessageIndex", + account, + ) + require.NoError(t, err) + + unpacked, err := testDAppABI.Unpack("getNoMessageIndex", res.Ret) + require.NoError(t, err) + require.Len(t, unpacked, 1) + + index, ok := unpacked[0].(string) + require.True(t, ok) + + return index +} + +// deployTestDAppV2 deploys the test dapp v2 contract and returns its address +func deployTestDAppV2(t *testing.T, ctx sdk.Context, k *fungiblekeeper.Keeper, evmk types.EVMKeeper) common.Address { + testDAppV2, err := k.DeployContract(ctx, testdappv2.TestDAppV2MetaData, true, sample.EthAddress()) + require.NoError(t, err) + require.NotEmpty(t, testDAppV2) + assertContractDeployment(t, evmk, ctx, testDAppV2) + + return testDAppV2 +} + +// assertTestDAppV2MessageAndAmount asserts the message and amount of the test dapp v2 contract +func assertTestDAppV2MessageAndAmount( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + contract common.Address, + expectedMessage string, + expectedAmount int64, +) { + testDAppABI, err := testdappv2.TestDAppV2MetaData.GetAbi() + require.NoError(t, err) + + // message + res, err := k.CallEVM( + ctx, + *testDAppABI, + types.ModuleAddressEVM, + contract, + fungiblekeeper.BigIntZero, + nil, + false, + false, + "getCalledWithMessage", + expectedMessage, + ) + require.NoError(t, err) + + unpacked, err := testDAppABI.Unpack("getCalledWithMessage", res.Ret) + require.NoError(t, err) + require.Len(t, unpacked, 1) + found, ok := unpacked[0].(bool) + require.True(t, ok) + require.True(t, found) + + // amount + res, err = k.CallEVM( + ctx, + *testDAppABI, + types.ModuleAddressEVM, + contract, + fungiblekeeper.BigIntZero, + nil, + false, + false, + "getAmountWithMessage", + expectedMessage, + ) + require.NoError(t, err) + + unpacked, err = testDAppABI.Unpack("getAmountWithMessage", res.Ret) + require.NoError(t, err) + require.Len(t, unpacked, 1) + amount, ok := unpacked[0].(*big.Int) + require.True(t, ok) + require.Equal(t, expectedAmount, amount.Int64()) +} + func TestKeeper_ZRC20DepositAndCallContract(t *testing.T) { t.Run("can deposit gas coin for transfers", func(t *testing.T) { // setup gas coin @@ -437,10 +539,10 @@ func TestKeeper_DepositCoinZeta(t *testing.T) { b := sdkk.BankKeeper.GetBalance(ctx, zetaToAddress, config.BaseDenom) require.Equal(t, int64(0), b.Amount.Int64()) - errorMint := errors.New("", 1, "error minting coins") + errorMint := errors.New("error minting coins") bankMock.On("GetSupply", ctx, mock.Anything, mock.Anything). - Return(sdk.NewCoin(config.BaseDenom, sdkmath.NewInt(0))). + Return(sdk.NewCoin(config.BaseDenom, math.NewInt(0))). Once() bankMock.On("MintCoins", ctx, types.ModuleName, mock.Anything).Return(errorMint).Once() err := k.DepositCoinZeta(ctx, to, amount) @@ -448,3 +550,157 @@ func TestKeeper_DepositCoinZeta(t *testing.T) { }) } + +func TestKeeper_ProcessDeposit(t *testing.T) { + t.Run("should process no-call deposit", func(t *testing.T) { + // ARRANGE + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + _ = k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + chainID := chains.DefaultChainsList()[0].ChainId + receiver := sample.EthAddress() + + // deploy the system contracts + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + // ACT + _, contractCall, err := k.ProcessDeposit( + ctx, + sample.EthAddress().Bytes(), + chainID, + zrc20, + receiver, + big.NewInt(42), + []byte{}, + coin.CoinType_Gas, + false, + ) + + // ASSERT + require.NoError(t, err) + require.False(t, contractCall) + + balance, err := k.BalanceOfZRC4(ctx, zrc20, receiver) + require.NoError(t, err) + require.Equal(t, big.NewInt(42), balance) + }) + + t.Run("should process no-call deposit, message should be ignored", func(t *testing.T) { + // ARRANGE + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + _ = k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + chainID := chains.DefaultChainsList()[0].ChainId + receiver := sample.EthAddress() + + // deploy the system contracts + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + // ACT + _, contractCall, err := k.ProcessDeposit( + ctx, + sample.EthAddress().Bytes(), + chainID, + zrc20, + receiver, + big.NewInt(42), + []byte("foo"), + coin.CoinType_Gas, + false, + ) + + // ASSERT + require.NoError(t, err) + require.False(t, contractCall) + + balance, err := k.BalanceOfZRC4(ctx, zrc20, receiver) + require.NoError(t, err) + require.Equal(t, big.NewInt(42), balance) + }) + + t.Run("should process deposit and call", func(t *testing.T) { + // ARRANGE + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + _ = k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + chainID := chains.DefaultChainsList()[0].ChainId + + // deploy test dapp + testDapp := deployTestDAppV2(t, ctx, k, sdkk.EvmKeeper) + + // deploy the system contracts + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + // ACT + _, contractCall, err := k.ProcessDeposit( + ctx, + sample.EthAddress().Bytes(), + chainID, + zrc20, + testDapp, + big.NewInt(82), + []byte("foo"), + coin.CoinType_Gas, + true, + ) + + // ASSERT + require.NoError(t, err) + require.True(t, contractCall) + balance, err := k.BalanceOfZRC4(ctx, zrc20, testDapp) + require.NoError(t, err) + require.Equal(t, big.NewInt(82), balance) + assertTestDAppV2MessageAndAmount(t, ctx, k, testDapp, "foo", 82) + }) + + t.Run("should process deposit and call with no message", func(t *testing.T) { + // ARRANGE + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + _ = k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + chainID := chains.DefaultChainsList()[0].ChainId + + // deploy test dapp + testDapp := deployTestDAppV2(t, ctx, k, sdkk.EvmKeeper) + + // deploy the system contracts + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + sender := sample.EthAddress() + + // ACT + _, contractCall, err := k.ProcessDeposit( + ctx, + sender.Bytes(), + chainID, + zrc20, + testDapp, + big.NewInt(82), + []byte{}, + coin.CoinType_Gas, + true, + ) + + // ASSERT + require.NoError(t, err) + require.True(t, contractCall) + balance, err := k.BalanceOfZRC4(ctx, zrc20, testDapp) + require.NoError(t, err) + require.Equal(t, big.NewInt(82), balance) + + messageIndex := getTestDAppNoMessageIndex(t, ctx, *k, testDapp, sender) + + assertTestDAppV2MessageAndAmount( + t, + ctx, + k, + testDapp, + messageIndex, + 82, + ) + }) +} diff --git a/x/fungible/keeper/evm.go b/x/fungible/keeper/evm.go index 5f1d7892c3..d920f336e5 100644 --- a/x/fungible/keeper/evm.go +++ b/x/fungible/keeper/evm.go @@ -315,10 +315,9 @@ func (k Keeper) UpdateZRC20GasLimit( ) } -// DepositZRC20AndCallContract deposits into ZRC4 and call contract function in a single tx -// callable from fungible module +// CallDepositAndCall calls the depositAndCall function of the system contract // Returns directly results from CallEVM -func (k Keeper) DepositZRC20AndCallContract(ctx sdk.Context, +func (k Keeper) CallDepositAndCall(ctx sdk.Context, context systemcontract.ZContext, zrc20Addr common.Address, targetContract common.Address, diff --git a/x/fungible/keeper/v2_evm.go b/x/fungible/keeper/evm_gateway.go similarity index 81% rename from x/fungible/keeper/v2_evm.go rename to x/fungible/keeper/evm_gateway.go index 4b5b233e6d..e7e21901a2 100644 --- a/x/fungible/keeper/v2_evm.go +++ b/x/fungible/keeper/evm_gateway.go @@ -249,3 +249,57 @@ func (k Keeper) CallDepositAndRevert( }, ) } + +// CallExecuteAbort calls the executeAbort function on the gateway contract +// +// function executeAbort( +// address target, +// AbortContext abortContext, +// ) +func (k Keeper) CallExecuteAbort( + ctx sdk.Context, + inboundSender string, + zrc20 common.Address, + amount *big.Int, + outgoing bool, + chainID *big.Int, + target common.Address, + message []byte, +) (*evmtypes.MsgEthereumTxResponse, error) { + gatewayABI, err := gatewayzevm.GatewayZEVMMetaData.GetAbi() + if err != nil { + return nil, err + } + + systemContract, found := k.GetSystemContract(ctx) + if !found { + return nil, types.ErrSystemContractNotFound + } + gatewayAddr := common.HexToAddress(systemContract.Gateway) + if crypto.IsEmptyAddress(gatewayAddr) { + return nil, types.ErrGatewayContractNotSet + } + + // TODO: set correct sender for non EVM chains + // https://github.com/zeta-chain/node/issues/3532 + return k.CallEVM( + ctx, + *gatewayABI, + types.ModuleAddressEVM, + gatewayAddr, + BigIntZero, + gatewayGasLimit, + true, + false, + "executeAbort", + target, + revert.AbortContext{ + Sender: common.HexToAddress(inboundSender).Bytes(), + Asset: zrc20, + Amount: amount, + Outgoing: outgoing, + ChainID: chainID, + RevertMessage: message, + }, + ) +} diff --git a/x/fungible/keeper/evm_test.go b/x/fungible/keeper/evm_test.go index 64dd506a83..c9d3d98674 100644 --- a/x/fungible/keeper/evm_test.go +++ b/x/fungible/keeper/evm_test.go @@ -567,7 +567,7 @@ func TestKeeper_DepositZRC20AndCallContract(t *testing.T) { require.NoError(t, err) assertContractDeployment(t, sdkk.EvmKeeper, ctx, example) - res, err := k.DepositZRC20AndCallContract( + res, err := k.CallDepositAndCall( ctx, systemcontract.ZContext{ Origin: sample.EthAddress().Bytes(), @@ -595,7 +595,7 @@ func TestKeeper_DepositZRC20AndCallContract(t *testing.T) { require.NoError(t, err) assertContractDeployment(t, sdkk.EvmKeeper, ctx, example) - res, err := k.DepositZRC20AndCallContract( + res, err := k.CallDepositAndCall( ctx, systemcontract.ZContext{ Origin: sample.EthAddress().Bytes(), @@ -649,7 +649,7 @@ func TestKeeper_DepositZRC20AndCallContract(t *testing.T) { require.NoError(t, err) assertContractDeployment(t, sdkk.EvmKeeper, ctx, reverter) - res, err := k.DepositZRC20AndCallContract( + res, err := k.CallDepositAndCall( ctx, systemcontract.ZContext{ Origin: sample.EthAddress().Bytes(), @@ -675,7 +675,7 @@ func TestKeeper_DepositZRC20AndCallContract(t *testing.T) { deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "FOOBAR") - res, err := k.DepositZRC20AndCallContract( + res, err := k.CallDepositAndCall( ctx, systemcontract.ZContext{ Origin: sample.EthAddress().Bytes(), diff --git a/x/fungible/keeper/v2_deposits.go b/x/fungible/keeper/v2_deposits.go deleted file mode 100644 index a71174fa52..0000000000 --- a/x/fungible/keeper/v2_deposits.go +++ /dev/null @@ -1,108 +0,0 @@ -package keeper - -import ( - "fmt" - "math/big" - - sdk "github.com/cosmos/cosmos-sdk/types" - ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/pkg/errors" - evmtypes "github.com/zeta-chain/ethermint/x/evm/types" - "github.com/zeta-chain/protocol-contracts/pkg/systemcontract.sol" - - "github.com/zeta-chain/node/pkg/coin" -) - -// ProcessV2Deposit handles a deposit from an inbound tx with protocol version 2 -// returns [txResponse, isContractCall, error] -// isContractCall is true if the message is non empty -func (k Keeper) ProcessV2Deposit( - ctx sdk.Context, - from []byte, - senderChainID int64, - zrc20Addr ethcommon.Address, - to ethcommon.Address, - amount *big.Int, - message []byte, - coinType coin.CoinType, - isCrossChainCall bool, -) (*evmtypes.MsgEthereumTxResponse, bool, error) { - context := systemcontract.ZContext{ - Origin: []byte{}, - Sender: ethcommon.BytesToAddress(from), - ChainID: big.NewInt(senderChainID), - } - - if coinType == coin.CoinType_NoAssetCall { - // simple call - res, err := k.CallExecute(ctx, context, zrc20Addr, amount, to, message) - return res, true, err - } else if isCrossChainCall { - // call with asset - res, err := k.CallDepositAndCallZRC20(ctx, context, zrc20Addr, amount, to, message) - return res, true, err - } - - // simple deposit - res, err := k.DepositZRC20(ctx, zrc20Addr, to, amount) - return res, false, err -} - -// 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, - asset string, - revertAddress ethcommon.Address, - callOnRevert bool, - revertMessage []byte, -) (*evmtypes.MsgEthereumTxResponse, error) { - // get the zrc20 contract - zrc20Addr, _, err := k.getAndCheckZRC20( - ctx, - amount, - chainID, - coinType, - asset, - ) - if err != nil { - return nil, err - } - - switch coinType { - case coin.CoinType_NoAssetCall: - - if callOnRevert { - // no asset, call simple revert - res, err := k.CallExecuteRevert(ctx, inboundSender, zrc20Addr, amount, revertAddress, revertMessage) - return res, err - } else { - // no asset, no call, do nothing - return nil, nil - } - case coin.CoinType_Zeta: - return nil, errors.New("ZETA asset is currently unsupported for revert with V2 protocol contracts") - case coin.CoinType_ERC20, coin.CoinType_Gas: - if callOnRevert { - // revert with a ZRC20 asset - res, err := k.CallDepositAndRevert( - ctx, - inboundSender, - zrc20Addr, - amount, - revertAddress, - revertMessage, - ) - return res, err - } else { - // simply deposit back to the revert address - res, err := k.DepositZRC20(ctx, zrc20Addr, revertAddress, amount) - return res, err - } - } - - return nil, fmt.Errorf("unsupported coin type for revert %s", coinType) -} diff --git a/x/fungible/keeper/v2_deposits_test.go b/x/fungible/keeper/v2_deposits_test.go deleted file mode 100644 index 3f138ada9d..0000000000 --- a/x/fungible/keeper/v2_deposits_test.go +++ /dev/null @@ -1,272 +0,0 @@ -package keeper_test - -import ( - "math/big" - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" - "github.com/zeta-chain/node/pkg/chains" - "github.com/zeta-chain/node/pkg/coin" - "github.com/zeta-chain/node/pkg/contracts/testdappv2" - keepertest "github.com/zeta-chain/node/testutil/keeper" - "github.com/zeta-chain/node/testutil/sample" - fungiblekeeper "github.com/zeta-chain/node/x/fungible/keeper" - "github.com/zeta-chain/node/x/fungible/types" -) - -// getTestDAppNoMessageIndex queries the no message index of the test dapp v2 contract -func getTestDAppNoMessageIndex( - t *testing.T, - ctx sdk.Context, - k fungiblekeeper.Keeper, - contract, - account common.Address, -) string { - testDAppABI, err := testdappv2.TestDAppV2MetaData.GetAbi() - require.NoError(t, err) - res, err := k.CallEVM( - ctx, - *testDAppABI, - types.ModuleAddressEVM, - contract, - fungiblekeeper.BigIntZero, - nil, - false, - false, - "getNoMessageIndex", - account, - ) - require.NoError(t, err) - - unpacked, err := testDAppABI.Unpack("getNoMessageIndex", res.Ret) - require.NoError(t, err) - require.Len(t, unpacked, 1) - - index, ok := unpacked[0].(string) - require.True(t, ok) - - return index -} - -// deployTestDAppV2 deploys the test dapp v2 contract and returns its address -func deployTestDAppV2(t *testing.T, ctx sdk.Context, k *fungiblekeeper.Keeper, evmk types.EVMKeeper) common.Address { - testDAppV2, err := k.DeployContract(ctx, testdappv2.TestDAppV2MetaData, true, sample.EthAddress()) - require.NoError(t, err) - require.NotEmpty(t, testDAppV2) - assertContractDeployment(t, evmk, ctx, testDAppV2) - - return testDAppV2 -} - -// assertTestDAppV2MessageAndAmount asserts the message and amount of the test dapp v2 contract -func assertTestDAppV2MessageAndAmount( - t *testing.T, - ctx sdk.Context, - k *fungiblekeeper.Keeper, - contract common.Address, - expectedMessage string, - expectedAmount int64, -) { - testDAppABI, err := testdappv2.TestDAppV2MetaData.GetAbi() - require.NoError(t, err) - - // message - res, err := k.CallEVM( - ctx, - *testDAppABI, - types.ModuleAddressEVM, - contract, - fungiblekeeper.BigIntZero, - nil, - false, - false, - "getCalledWithMessage", - expectedMessage, - ) - require.NoError(t, err) - - unpacked, err := testDAppABI.Unpack("getCalledWithMessage", res.Ret) - require.NoError(t, err) - require.Len(t, unpacked, 1) - found, ok := unpacked[0].(bool) - require.True(t, ok) - require.True(t, found) - - // amount - res, err = k.CallEVM( - ctx, - *testDAppABI, - types.ModuleAddressEVM, - contract, - fungiblekeeper.BigIntZero, - nil, - false, - false, - "getAmountWithMessage", - expectedMessage, - ) - require.NoError(t, err) - - unpacked, err = testDAppABI.Unpack("getAmountWithMessage", res.Ret) - require.NoError(t, err) - require.Len(t, unpacked, 1) - amount, ok := unpacked[0].(*big.Int) - require.True(t, ok) - require.Equal(t, expectedAmount, amount.Int64()) -} - -func TestKeeper_ProcessV2Deposit(t *testing.T) { - t.Run("should process no-call deposit", func(t *testing.T) { - // ARRANGE - k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) - _ = k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - - chainID := chains.DefaultChainsList()[0].ChainId - receiver := sample.EthAddress() - - // deploy the system contracts - deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) - zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") - - // ACT - _, contractCall, err := k.ProcessV2Deposit( - ctx, - sample.EthAddress().Bytes(), - chainID, - zrc20, - receiver, - big.NewInt(42), - []byte{}, - coin.CoinType_Gas, - false, - ) - - // ASSERT - require.NoError(t, err) - require.False(t, contractCall) - - balance, err := k.BalanceOfZRC4(ctx, zrc20, receiver) - require.NoError(t, err) - require.Equal(t, big.NewInt(42), balance) - }) - - t.Run("should process no-call deposit, message should be ignored", func(t *testing.T) { - // ARRANGE - k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) - _ = k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - - chainID := chains.DefaultChainsList()[0].ChainId - receiver := sample.EthAddress() - - // deploy the system contracts - deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) - zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") - - // ACT - _, contractCall, err := k.ProcessV2Deposit( - ctx, - sample.EthAddress().Bytes(), - chainID, - zrc20, - receiver, - big.NewInt(42), - []byte("foo"), - coin.CoinType_Gas, - false, - ) - - // ASSERT - require.NoError(t, err) - require.False(t, contractCall) - - balance, err := k.BalanceOfZRC4(ctx, zrc20, receiver) - require.NoError(t, err) - require.Equal(t, big.NewInt(42), balance) - }) - - t.Run("should process deposit and call", func(t *testing.T) { - // ARRANGE - k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) - _ = k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - - chainID := chains.DefaultChainsList()[0].ChainId - - // deploy test dapp - testDapp := deployTestDAppV2(t, ctx, k, sdkk.EvmKeeper) - - // deploy the system contracts - deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) - zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") - - // ACT - _, contractCall, err := k.ProcessV2Deposit( - ctx, - sample.EthAddress().Bytes(), - chainID, - zrc20, - testDapp, - big.NewInt(82), - []byte("foo"), - coin.CoinType_Gas, - true, - ) - - // ASSERT - require.NoError(t, err) - require.True(t, contractCall) - balance, err := k.BalanceOfZRC4(ctx, zrc20, testDapp) - require.NoError(t, err) - require.Equal(t, big.NewInt(82), balance) - assertTestDAppV2MessageAndAmount(t, ctx, k, testDapp, "foo", 82) - }) - - t.Run("should process deposit and call with no message", func(t *testing.T) { - // ARRANGE - k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) - _ = k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - - chainID := chains.DefaultChainsList()[0].ChainId - - // deploy test dapp - testDapp := deployTestDAppV2(t, ctx, k, sdkk.EvmKeeper) - - // deploy the system contracts - deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) - zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") - - sender := sample.EthAddress() - - // ACT - _, contractCall, err := k.ProcessV2Deposit( - ctx, - sender.Bytes(), - chainID, - zrc20, - testDapp, - big.NewInt(82), - []byte{}, - coin.CoinType_Gas, - true, - ) - - // ASSERT - require.NoError(t, err) - require.True(t, contractCall) - balance, err := k.BalanceOfZRC4(ctx, zrc20, testDapp) - require.NoError(t, err) - require.Equal(t, big.NewInt(82), balance) - - messageIndex := getTestDAppNoMessageIndex(t, ctx, *k, testDapp, sender) - - assertTestDAppV2MessageAndAmount( - t, - ctx, - k, - testDapp, - messageIndex, - 82, - ) - }) -}