From f2bd85f7dd2a24ab1971bc208b74e81c812aad94 Mon Sep 17 00:00:00 2001 From: suha jin <89185836+djm07073@users.noreply.github.com> Date: Fri, 18 Oct 2024 13:30:20 +0900 Subject: [PATCH 1/6] feat: erc20 wrapper contract fix: add comment to understand feat: wrapper erc20 factory fix: unwrap and wrap the tokens feat: add erc20 wrapper when initialize keeper fix: async callback to handle failure of ibc transfer feat: add query for erc20 wrapper fix query path --- app/ibc-hooks/README.md | 50 +- proto/minievm/evm/v1/genesis.proto | 3 + proto/minievm/evm/v1/query.proto | 17 + x/evm/contracts/erc20_wrapper/ERC20Wrapper.go | 759 ++++++++++++++++++ .../contracts/erc20_wrapper/ERC20Wrapper.sol | 201 +++++ x/evm/contracts/util/Strings.go | 203 +++++ x/evm/contracts/util/Strings.sol | 88 ++ x/evm/keeper/erc721_test.go | 2 +- x/evm/keeper/genesis.go | 31 +- x/evm/keeper/genesis_test.go | 1 + x/evm/keeper/keeper.go | 11 + x/evm/keeper/query_server.go | 12 + x/evm/keeper/query_server_test.go | 14 + x/evm/types/address.go | 1 + x/evm/types/errors.go | 1 + x/evm/types/genesis.pb.go | 56 +- x/evm/types/keys.go | 1 + x/evm/types/query.pb.go | 491 +++++++++-- x/evm/types/query.pb.gw.go | 65 ++ 19 files changed, 1924 insertions(+), 83 deletions(-) create mode 100644 x/evm/contracts/erc20_wrapper/ERC20Wrapper.go create mode 100644 x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol create mode 100644 x/evm/contracts/util/Strings.go create mode 100644 x/evm/contracts/util/Strings.sol diff --git a/app/ibc-hooks/README.md b/app/ibc-hooks/README.md index daffc3e7..72cf50b6 100644 --- a/app/ibc-hooks/README.md +++ b/app/ibc-hooks/README.md @@ -2,7 +2,7 @@ This module is copied from [osmosis](https://github.com/osmosis-labs/osmosis) and changed to execute evm contract with ICS-20 token transfer calls. -## Move Hooks +## EVM Hooks The evm hook is an IBC middleware which is used to allow ICS-20 token transfers to initiate contract calls. This allows cross-chain contract calls, that involve token movement. @@ -12,7 +12,7 @@ One of primary importance is cross-chain swaps, which is an extremely powerful p The mechanism enabling this is a `memo` field on every ICS20 and ICS721 transfer packet as of [IBC v3.4.0](https://medium.com/the-interchain-foundation/moving-beyond-simple-token-transfers-d42b2b1dc29b). Move hooks is an IBC middleware that parses an ICS20 transfer, and if the `memo` field is of a particular form, executes a evm contract call. We now detail the `memo` format for `evm` contract calls, and the execution guarantees provided. -### Move Contract Execution Format +### EVM Contract Execution Format Before we dive into the IBC metadata format, we show the hook data format, so the reader has a sense of what are the fields we need to be setting in. The evm `MsgCall` is defined [here](../../x/evm/types/tx.pb.go) and other types are defined [here](./message.go) as the following type: @@ -48,6 +48,9 @@ type MsgCall struct { ContractAddr string `protobuf:"bytes,2,opt,name=contract_addr,json=contractAddr,proto3" json:"contract_addr,omitempty"` // Hex encoded execution input bytes. Input string `protobuf:"bytes,3,opt,name=input,proto3" json:"input,omitempty"` + // Value is the amount of fee denom token to transfer to the contract. +Value string `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` + } ``` @@ -71,6 +74,8 @@ msg := MsgCall{ ContractAddr: packet.data.memo["evm"]["message"]["contract_addr"], // Hex encoded execution input bytes. Input: packet.data.memo["evm"]["message"]["input"], + + Value: packet.data.memo["evm"]["message"]["value"] } ``` @@ -93,6 +98,7 @@ ICS20 is JSON native, so we use JSON for the memo format. "message": { "contract_addr": "0x1", "input": "hex encoded byte string", + "value": "0" }, // optional field to get async callback (ack and timeout) "async_callback": { @@ -103,7 +109,6 @@ ICS20 is JSON native, so we use JSON for the memo format. } } } - ``` An ICS20 packet is formatted correctly for evmhooks iff the following all hold: @@ -111,7 +116,7 @@ An ICS20 packet is formatted correctly for evmhooks iff the following all hold: - `memo` is not blank - `memo` is valid JSON - `memo` has at least one key, with value `"evm"` -- `memo["evm"]["message"]` has exactly five entries, `"contract_addr"` and `"input"` +- `memo["evm"]["message"]` has exactly 3 entries, `"contract_addr"`, `"input"`, `"value"` - `receiver` == "" || `receiver` == "module_address::module_name::function_name" We consider an ICS20 packet as directed towards evmhooks iff all of the following hold: @@ -160,5 +165,38 @@ interface IIBCAsyncCallback { Also when a contract make IBC transfer request, it should provide async callback data through memo field. -- `memo['evm']['async_callback']['id']`: the async callback id is assigned from the contract. so later it will be passed as argument of `ibc_ack` and `ibc_timeout`. -- `memo['evm']['async_callback']['contract_addr']`: The address of module which defines the callback function. +- `memo['evm']['async_callback']['id']`: the async callback id is assigned from the contract. so later it will be passed as argument of `ibc_ack` and `ibc_timeout`. +- `memo['evm']['async_callback']['contract_addr']`: The address of contract which defines the callback function. + +### IBC Transfer using ERC20Wrapper + +`src -> dst`: use the ERC20Wrapper contract to wrap and do ibc-transfer + +`dst -> src`: unwrapped the wrapped token by execute hook +- data example +```json +{ + //... other ibc fields that we don't care about + "data": { + "denom": "wrapped token denom", // will be transformed to the local denom (ibc/...) + "amount": "1000", + "sender": "addr on counterparty chain", // will be transformed + "receiver": "ModuleAddr::ModuleName::FunctionName", + "memo": { + "evm": { + // execute message on receive packet + "message": { + "contract_addr": "...", // should query erc20 wrapper contract addr + "input": "...", // function selector(fc078758) + abiCoder.encode([string,address,address],denom,amount) ref)https://docs.ethers.org/v6/api/abi/abi-coder/#AbiCoder-encode + "value": "0" + }, + // optional field to get async callback (ack and timeout) + "async_callback": { + "id": 1, + "contract_addr": "0x1" + } + } + } + } +} +``` diff --git a/proto/minievm/evm/v1/genesis.proto b/proto/minievm/evm/v1/genesis.proto index e70eff65..f9718bfc 100644 --- a/proto/minievm/evm/v1/genesis.proto +++ b/proto/minievm/evm/v1/genesis.proto @@ -47,6 +47,9 @@ message GenesisState { // erc20 factory contract address bytes erc20_factory = 8; + + // erc20 wrapper contract address + bytes erc20_wrapper = 9; } // GenesisKeyValue defines store KV values. diff --git a/proto/minievm/evm/v1/query.proto b/proto/minievm/evm/v1/query.proto index 3899c918..f1995091 100644 --- a/proto/minievm/evm/v1/query.proto +++ b/proto/minievm/evm/v1/query.proto @@ -27,6 +27,11 @@ service Query { option (google.api.http).get = "/minievm/evm/v1/contracts/erc20_factory"; } + // ERC20Wrapper gets the ERC20Wrapper contract address. + rpc ERC20Wrapper(QueryERC20WrapperRequest) returns (QueryERC20WrapperResponse) { + option (google.api.http).get = "/minievm/evm/v1/contracts/erc20_wrapper"; + } + // ContractAddrByDenom gets the contract address by denom. rpc ContractAddrByDenom(QueryContractAddrByDenomRequest) returns (QueryContractAddrByDenomResponse) { option (google.api.http).get = "/minievm/evm/v1/contracts/by_denom"; @@ -94,6 +99,18 @@ message QueryERC20FactoryResponse { string address = 1; } +// QueryERC20WrapperRequest is the request type for the Query/ERC20Wrapper RPC +// method +message QueryERC20WrapperRequest {} + +// QueryERC20WrapperResponse is the response type for the Query/ERC20Wrapper RPC +// method +message QueryERC20WrapperResponse { + option (gogoproto.equal) = true; + // 0x prefixed hex address + string address = 1; +} + // QueryContractAddrByDenomRequest is the request type for the Query/ContractAddrByDenom RPC // method message QueryContractAddrByDenomRequest { diff --git a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go new file mode 100644 index 00000000..8d78de01 --- /dev/null +++ b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go @@ -0,0 +1,759 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package erc20_wrapper + +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 +) + +// Erc20WrapperMetaData contains all meta data concerning the Erc20Wrapper contract. +var Erc20WrapperMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"StringsInsufficientHexLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"erc20\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"ERC20Created\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"name\":\"createERC20\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"ibc_ack\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"}],\"name\":\"ibc_timeout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"originTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"wrappedTokenDenom\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wrappedAmt\",\"type\":\"uint256\"}],\"name\":\"unwrap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"channel\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"receiver\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"wrap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"wrappedTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60806040525f8060146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055503480156036575f80fd5b50335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550614a7f806100835f395ff3fe608060405234801561000f575f80fd5b506004361061009c575f3560e01c80639a111432116100645780639a11143214610156578063b5ad1fb614610172578063d5c6b504146101a2578063f2fde38b146101d2578063fc078758146101ee5761009c565b806301ffc9a7146100a057806306ef1a86146100d05780630d4f1f9d1461010057806331a503f01461011c5780638da5cb5b14610138575b5f80fd5b6100ba60048036038101906100b59190611ba1565b61020a565b6040516100c79190611be6565b60405180910390f35b6100ea60048036038101906100e59190611d71565b610273565b6040516100f79190611e38565b60405180910390f35b61011a60048036038101906101159190611eb8565b6103f2565b005b61013660048036038101906101319190611ef6565b610405565b005b610140610411565b60405161014d9190611e38565b60405180910390f35b610170600480360381019061016b9190611f7e565b610434565b005b61018c6004803603810190610187919061202d565b610730565b6040516101999190611e38565b60405180910390f35b6101bc60048036038101906101b7919061202d565b610760565b6040516101c99190611e38565b60405180910390f35b6101ec60048036038101906101e7919061202d565b610790565b005b61020860048036038101906102039190612058565b6108d8565b005b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f8084848460405161028490611b2e565b61029093929190612133565b604051809103905ff0801580156102a9573d5f803e3d5ffd5b50905060f273ffffffffffffffffffffffffffffffffffffffff1663d126274a826040518263ffffffff1660e01b81526004016102e69190611e38565b6020604051808303815f875af1158015610302573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610326919061218a565b508073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b336040518263ffffffff1660e01b81526004016103609190611e38565b5f604051808303815f87803b158015610377575f80fd5b505af1158015610389573d5f803e3d5ffd5b505050503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d160405160405180910390a3809150509392505050565b806104015761040082610c51565b5b5050565b61040e81610c51565b50565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61043d84610d8c565b8373ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161047a939291906121c4565b6020604051808303815f875af1158015610496573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104ba919061218a565b505f610534838673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610509573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061052d919061220d565b60066110af565b905060015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1930836040518363ffffffff1660e01b81526004016105cd929190612238565b5f604051808303815f87803b1580156105e4575f80fd5b505af11580156105f6573d5f803e3d5ffd5b5050505060015f60148282829054906101000a900467ffffffffffffffff1661061f919061228c565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e66106cb8860015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685878a61117e565b6040518263ffffffff1660e01b81526004016106e791906122c7565b6020604051808303815f875af1158015610703573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610727919061218a565b50505050505050565b6002602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6001602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107e6575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361081d575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60f173ffffffffffffffffffffffffffffffffffffffff16632b3324ce856040518263ffffffff1660e01b815260040161091391906122c7565b6020604051808303815f875af115801561092f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061095391906122fb565b90505f73ffffffffffffffffffffffffffffffffffffffff1660025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610a1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1690612370565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166379cc679033846040518363ffffffff1660e01b8152600401610a5a929190612238565b6020604051808303815f875af1158015610a76573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a9a919061218a565b505f610b7083600660025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b6b919061220d565b6110af565b905060025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85836040518363ffffffff1660e01b8152600401610c09929190612238565b6020604051808303815f875af1158015610c25573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c49919061218a565b505050505050565b5f60035f8367ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f206040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182018054610ce6906123bb565b80601f0160208091040260200160405190810160405280929190818152602001828054610d12906123bb565b8015610d5d5780601f10610d3457610100808354040283529160200191610d5d565b820191905f5260205f20905b815481529060010190602001808311610d4057829003601f168201915b505050505081526020016002820154815250509050610d888160200151825f015183604001516108d8565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff1660015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036110ac575f610fb26040518060400160405280600781526020017f57726170706564000000000000000000000000000000000000000000000000008152508373ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa158015610e9d573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610ec59190612459565b604051602001610ed69291906124da565b6040516020818303038152906040526040518060400160405280600181526020017f57000000000000000000000000000000000000000000000000000000000000008152508473ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015610f63573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610f8b9190612459565b604051602001610f9c9291906124da565b604051602081830303815290604052600661158f565b90508060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505b50565b5f8160ff168360ff1611156110f0575f82846110cb91906124fd565b60ff16600a6110da9190612660565b905080856110e891906126d7565b915050611135565b8160ff168360ff161015611130575f838361110b91906124fd565b60ff16600a61111a9190612660565b905080856111289190612707565b915050611134565b8390505b5b5f8103611177576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116e90612792565b60405180910390fd5b9392505050565b6060806060805f6040518060a00160405280606381526020016149e76063913990505f6040518060400160405280601781526020017f222c22746f6b656e223a207b202264656e6f6d223a202200000000000000000081525090505f6040518060400160405280600d81526020017f222c22616d6f756e74223a2022000000000000000000000000000000000000008152509050828c8360f173ffffffffffffffffffffffffffffffffffffffff166381cf0f6a8f6040518263ffffffff1660e01b815260040161124f9190611e38565b5f604051808303815f875af115801561126a573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906112929190612459565b846040516020016112a79594939291906127b0565b60405160208183030381529060405295505050505f6040518060400160405280600d81526020017f222c2273656e646572223a20220000000000000000000000000000000000000081525090505f6040518060400160405280600f81526020017f222c227265636569766572223a2022000000000000000000000000000000000081525090505f6040518060800160405280605a815260200161498d605a913990505f6040518060400160405280600c81526020017f222c226d656d6f223a202222000000000000000000000000000000000000000081525090505f61138c8c6116a8565b90505f6113988c6116a8565b9050818660f173ffffffffffffffffffffffffffffffffffffffff16636af32a55306040518263ffffffff1660e01b81526004016113d69190611e38565b5f604051808303815f875af11580156113f1573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906114199190612459565b878e8886896040516020016114359897969594939291906127fa565b60405160208183030381529060405297505050505050505f6040518060400160405280601b81526020017f2c226173796e635f63616c6c6261636b223a207b226964223a2022000000000081525090505f6040518060400160405280601781526020017f222c22636f6e74726163745f61646472657373223a202200000000000000000081525090505f6040518060400160405280600381526020017f227d7d000000000000000000000000000000000000000000000000000000000081525090505f6115205f60149054906101000a900467ffffffffffffffff1667ffffffffffffffff166116a8565b90505f61152c30611772565b905084828583866040516020016115479594939291906127b0565b604051602081830303815290604052955050505050508282826040516020016115729392919061286b565b604051602081830303815290604052935050505095945050505050565b5f808484846040516115a090611b2e565b6115ac93929190612133565b604051809103905ff0801580156115c5573d5f803e3d5ffd5b50905060f273ffffffffffffffffffffffffffffffffffffffff1663d126274a826040518263ffffffff1660e01b81526004016116029190611e38565b6020604051808303815f875af115801561161e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611642919061218a565b503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d160405160405180910390a3809150509392505050565b60605f60016116b68461179f565b0190505f8167ffffffffffffffff8111156116d4576116d3611c17565b5b6040519080825280601f01601f1916602001820160405280156117065781602001600182028036833780820191505090505b5090505f82602001820190505b600115611767578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161175c5761175b6126aa565b5b0494505f8503611713575b819350505050919050565b60606117988273ffffffffffffffffffffffffffffffffffffffff16601460ff166118f0565b9050919050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106117fb577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816117f1576117f06126aa565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611838576d04ee2d6d415b85acef8100000000838161182e5761182d6126aa565b5b0492506020810190505b662386f26fc10000831061186757662386f26fc10000838161185d5761185c6126aa565b5b0492506010810190505b6305f5e1008310611890576305f5e1008381611886576118856126aa565b5b0492506008810190505b61271083106118b55761271083816118ab576118aa6126aa565b5b0492506004810190505b606483106118d857606483816118ce576118cd6126aa565b5b0492506002810190505b600a83106118e7576001810190505b80915050919050565b60605f8390505f60028460026119069190612707565b611910919061289b565b67ffffffffffffffff81111561192957611928611c17565b5b6040519080825280601f01601f19166020018201604052801561195b5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f81518110611992576119916128ce565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106119f5576119f46128ce565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f6001856002611a339190612707565b611a3d919061289b565b90505b6001811115611adc577f3031323334353637383961626364656600000000000000000000000000000000600f841660108110611a7f57611a7e6128ce565b5b1a60f81b828281518110611a9657611a956128ce565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600483901c925080611ad5906128fb565b9050611a40565b505f8214611b235784846040517fe22e27eb000000000000000000000000000000000000000000000000000000008152600401611b1a929190612922565b60405180910390fd5b809250505092915050565b6120438061294a83390190565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611b8081611b4c565b8114611b8a575f80fd5b50565b5f81359050611b9b81611b77565b92915050565b5f60208284031215611bb657611bb5611b44565b5b5f611bc384828501611b8d565b91505092915050565b5f8115159050919050565b611be081611bcc565b82525050565b5f602082019050611bf95f830184611bd7565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611c4d82611c07565b810181811067ffffffffffffffff82111715611c6c57611c6b611c17565b5b80604052505050565b5f611c7e611b3b565b9050611c8a8282611c44565b919050565b5f67ffffffffffffffff821115611ca957611ca8611c17565b5b611cb282611c07565b9050602081019050919050565b828183375f83830152505050565b5f611cdf611cda84611c8f565b611c75565b905082815260208101848484011115611cfb57611cfa611c03565b5b611d06848285611cbf565b509392505050565b5f82601f830112611d2257611d21611bff565b5b8135611d32848260208601611ccd565b91505092915050565b5f60ff82169050919050565b611d5081611d3b565b8114611d5a575f80fd5b50565b5f81359050611d6b81611d47565b92915050565b5f805f60608486031215611d8857611d87611b44565b5b5f84013567ffffffffffffffff811115611da557611da4611b48565b5b611db186828701611d0e565b935050602084013567ffffffffffffffff811115611dd257611dd1611b48565b5b611dde86828701611d0e565b9250506040611def86828701611d5d565b9150509250925092565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611e2282611df9565b9050919050565b611e3281611e18565b82525050565b5f602082019050611e4b5f830184611e29565b92915050565b5f67ffffffffffffffff82169050919050565b611e6d81611e51565b8114611e77575f80fd5b50565b5f81359050611e8881611e64565b92915050565b611e9781611bcc565b8114611ea1575f80fd5b50565b5f81359050611eb281611e8e565b92915050565b5f8060408385031215611ece57611ecd611b44565b5b5f611edb85828601611e7a565b9250506020611eec85828601611ea4565b9150509250929050565b5f60208284031215611f0b57611f0a611b44565b5b5f611f1884828501611e7a565b91505092915050565b611f2a81611e18565b8114611f34575f80fd5b50565b5f81359050611f4581611f21565b92915050565b5f819050919050565b611f5d81611f4b565b8114611f67575f80fd5b50565b5f81359050611f7881611f54565b92915050565b5f805f805f60a08688031215611f9757611f96611b44565b5b5f86013567ffffffffffffffff811115611fb457611fb3611b48565b5b611fc088828901611d0e565b9550506020611fd188828901611f37565b945050604086013567ffffffffffffffff811115611ff257611ff1611b48565b5b611ffe88828901611d0e565b935050606061200f88828901611f6a565b925050608061202088828901611f6a565b9150509295509295909350565b5f6020828403121561204257612041611b44565b5b5f61204f84828501611f37565b91505092915050565b5f805f6060848603121561206f5761206e611b44565b5b5f84013567ffffffffffffffff81111561208c5761208b611b48565b5b61209886828701611d0e565b93505060206120a986828701611f37565b92505060406120ba86828701611f6a565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f6120f6826120c4565b61210081856120ce565b93506121108185602086016120de565b61211981611c07565b840191505092915050565b61212d81611d3b565b82525050565b5f6060820190508181035f83015261214b81866120ec565b9050818103602083015261215f81856120ec565b905061216e6040830184612124565b949350505050565b5f8151905061218481611e8e565b92915050565b5f6020828403121561219f5761219e611b44565b5b5f6121ac84828501612176565b91505092915050565b6121be81611f4b565b82525050565b5f6060820190506121d75f830186611e29565b6121e46020830185611e29565b6121f160408301846121b5565b949350505050565b5f8151905061220781611d47565b92915050565b5f6020828403121561222257612221611b44565b5b5f61222f848285016121f9565b91505092915050565b5f60408201905061224b5f830185611e29565b61225860208301846121b5565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61229682611e51565b91506122a183611e51565b9250828201905067ffffffffffffffff8111156122c1576122c061225f565b5b92915050565b5f6020820190508181035f8301526122df81846120ec565b905092915050565b5f815190506122f581611f21565b92915050565b5f602082840312156123105761230f611b44565b5b5f61231d848285016122e7565b91505092915050565b7f6f726967696e20746f6b656e20646f65736e27742065786973740000000000005f82015250565b5f61235a601a836120ce565b915061236582612326565b602082019050919050565b5f6020820190508181035f8301526123878161234e565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806123d257607f821691505b6020821081036123e5576123e461238e565b5b50919050565b5f6123fd6123f884611c8f565b611c75565b90508281526020810184848401111561241957612418611c03565b5b6124248482856120de565b509392505050565b5f82601f8301126124405761243f611bff565b5b81516124508482602086016123eb565b91505092915050565b5f6020828403121561246e5761246d611b44565b5b5f82015167ffffffffffffffff81111561248b5761248a611b48565b5b6124978482850161242c565b91505092915050565b5f81905092915050565b5f6124b4826120c4565b6124be81856124a0565b93506124ce8185602086016120de565b80840191505092915050565b5f6124e582856124aa565b91506124f182846124aa565b91508190509392505050565b5f61250782611d3b565b915061251283611d3b565b9250828203905060ff81111561252b5761252a61225f565b5b92915050565b5f8160011c9050919050565b5f808291508390505b6001851115612586578086048111156125625761256161225f565b5b60018516156125715780820291505b808102905061257f85612531565b9450612546565b94509492505050565b5f8261259e5760019050612659565b816125ab575f9050612659565b81600181146125c157600281146125cb576125fa565b6001915050612659565b60ff8411156125dd576125dc61225f565b5b8360020a9150848211156125f4576125f361225f565b5b50612659565b5060208310610133831016604e8410600b841016171561262f5782820a90508381111561262a5761262961225f565b5b612659565b61263c848484600161253d565b925090508184048111156126535761265261225f565b5b81810290505b9392505050565b5f61266a82611f4b565b915061267583611f4b565b92506126a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461258f565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6126e182611f4b565b91506126ec83611f4b565b9250826126fc576126fb6126aa565b5b828204905092915050565b5f61271182611f4b565b915061271c83611f4b565b925082820261272a81611f4b565b915082820484148315176127415761274061225f565b5b5092915050565b7f636f6e76657274656420616d6f756e74206973207a65726f00000000000000005f82015250565b5f61277c6018836120ce565b915061278782612748565b602082019050919050565b5f6020820190508181035f8301526127a981612770565b9050919050565b5f6127bb82886124aa565b91506127c782876124aa565b91506127d382866124aa565b91506127df82856124aa565b91506127eb82846124aa565b91508190509695505050505050565b5f612805828b6124aa565b9150612811828a6124aa565b915061281d82896124aa565b915061282982886124aa565b915061283582876124aa565b915061284182866124aa565b915061284d82856124aa565b915061285982846124aa565b91508190509998505050505050505050565b5f61287682866124aa565b915061288282856124aa565b915061288e82846124aa565b9150819050949350505050565b5f6128a582611f4b565b91506128b083611f4b565b92508282019050808211156128c8576128c761225f565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f61290582611f4b565b91505f82036129175761291661225f565b5b600182039050919050565b5f6040820190506129355f8301856121b5565b61294260208301846121b5565b939250505056fe608060405234801561000f575f80fd5b5060405161204338038061204383398181016040528101906100319190610235565b335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826003908161007f91906104ca565b50816004908161008f91906104ca565b508060055f6101000a81548160ff021916908360ff160217905550505050610599565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610111826100cb565b810181811067ffffffffffffffff821117156101305761012f6100db565b5b80604052505050565b5f6101426100b2565b905061014e8282610108565b919050565b5f67ffffffffffffffff82111561016d5761016c6100db565b5b610176826100cb565b9050602081019050919050565b8281835e5f83830152505050565b5f6101a361019e84610153565b610139565b9050828152602081018484840111156101bf576101be6100c7565b5b6101ca848285610183565b509392505050565b5f82601f8301126101e6576101e56100c3565b5b81516101f6848260208601610191565b91505092915050565b5f60ff82169050919050565b610214816101ff565b811461021e575f80fd5b50565b5f8151905061022f8161020b565b92915050565b5f805f6060848603121561024c5761024b6100bb565b5b5f84015167ffffffffffffffff811115610269576102686100bf565b5b610275868287016101d2565b935050602084015167ffffffffffffffff811115610296576102956100bf565b5b6102a2868287016101d2565b92505060406102b386828701610221565b9150509250925092565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061030b57607f821691505b60208210810361031e5761031d6102c7565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026103807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610345565b61038a8683610345565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6103ce6103c96103c4846103a2565b6103ab565b6103a2565b9050919050565b5f819050919050565b6103e7836103b4565b6103fb6103f3826103d5565b848454610351565b825550505050565b5f90565b61040f610403565b61041a8184846103de565b505050565b5b8181101561043d576104325f82610407565b600181019050610420565b5050565b601f8211156104825761045381610324565b61045c84610336565b8101602085101561046b578190505b61047f61047785610336565b83018261041f565b50505b505050565b5f82821c905092915050565b5f6104a25f1984600802610487565b1980831691505092915050565b5f6104ba8383610493565b9150826002028217905092915050565b6104d3826102bd565b67ffffffffffffffff8111156104ec576104eb6100db565b5b6104f682546102f4565b610501828285610441565b5f60209050601f831160018114610532575f8415610520578287015190505b61052a85826104af565b865550610591565b601f19841661054086610324565b5f5b8281101561056757848901518255600182019150602085019450602081019050610542565b868310156105845784890151610580601f891682610493565b8355505b6001600288020188555050505b505050505050565b611a9d806105a65f395ff3fe608060405234801561000f575f80fd5b5060043610610114575f3560e01c806342966c68116100a057806395d89b411161006f57806395d89b41146102f0578063a9059cbb1461030e578063dd62ed3e1461033e578063f2fde38b1461036e578063fe1195ec1461038a57610114565b806342966c681461025657806370a082311461027257806379cc6790146102a25780638da5cb5b146102d257610114565b80631988513b116100e75780631988513b146101b457806323b872dd146101d05780632d688ca814610200578063313ce5671461021c57806340c10f191461023a57610114565b806301ffc9a71461011857806306fdde0314610148578063095ea7b31461016657806318160ddd14610196575b5f80fd5b610132600480360381019061012d919061143b565b6103a6565b60405161013f9190611480565b60405180910390f35b61015061041f565b60405161015d9190611509565b60405180910390f35b610180600480360381019061017b91906115b6565b6104ab565b60405161018d9190611480565b60405180910390f35b61019e610598565b6040516101ab9190611603565b60405180910390f35b6101ce60048036038101906101c9919061161c565b61059e565b005b6101ea60048036038101906101e5919061161c565b61061d565b6040516101f79190611480565b60405180910390f35b61021a600480360381019061021591906115b6565b61077d565b005b6102246107fa565b6040516102319190611687565b60405180910390f35b610254600480360381019061024f91906115b6565b61080c565b005b610270600480360381019061026b91906116a0565b61092b565b005b61028c600480360381019061028791906116cb565b6109f3565b6040516102999190611603565b60405180910390f35b6102bc60048036038101906102b791906115b6565b610a08565b6040516102c99190611480565b60405180910390f35b6102da610b66565b6040516102e79190611705565b60405180910390f35b6102f8610b89565b6040516103059190611509565b60405180910390f35b610328600480360381019061032391906115b6565b610c15565b6040516103359190611480565b60405180910390f35b6103586004803603810190610353919061171e565b610ce6565b6040516103659190611603565b60405180910390f35b610388600480360381019061038391906116cb565b610d06565b005b6103a4600480360381019061039f91906115b6565b610e4e565b005b5f7f8da6da19000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610418575061041782610ecb565b5b9050919050565b6003805461042c90611789565b80601f016020809104026020016040519081016040528092919081815260200182805461045890611789565b80156104a35780601f1061047a576101008083540402835291602001916104a3565b820191905f5260205f20905b81548152906001019060200180831161048657829003601f168201915b505050505081565b5f8160025f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516105869190611603565b60405180910390a36001905092915050565b60065481565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461060d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060490611803565b60405180910390fd5b610618838383610f34565b505050565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016106599190611705565b602060405180830381865afa158015610674573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610698919061184b565b156106d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106cf906118e6565b60405180910390fd5b8260025f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461075f9190611931565b92505081905550610771858585610f34565b60019150509392505050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e390611803565b60405180910390fd5b6107f6828261113f565b5050565b60055f9054906101000a900460ff1681565b8160f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016108479190611705565b602060405180830381865afa158015610862573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610886919061184b565b156108c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108bd906119ae565b60405180910390fd5b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461091c575f80fd5b610926838361113f565b505050565b3360f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b81526004016109669190611705565b602060405180830381865afa158015610981573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109a5919061184b565b156109e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109dc90611a16565b60405180910390fd5b6109ef338361130e565b5050565b6001602052805f5260405f205f915090505481565b5f8260f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b8152600401610a449190611705565b602060405180830381865afa158015610a5f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a83919061184b565b15610ac3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aba90611a16565b60405180910390fd5b8260025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610b4a9190611931565b92505081905550610b5b848461130e565b600191505092915050565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60048054610b9690611789565b80601f0160208091040260200160405190810160405280929190818152602001828054610bc290611789565b8015610c0d5780601f10610be457610100808354040283529160200191610c0d565b820191905f5260205f20905b815481529060010190602001808311610bf057829003601f168201915b505050505081565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b8152600401610c519190611705565b602060405180830381865afa158015610c6c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c90919061184b565b15610cd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc7906118e6565b60405180910390fd5b610cdb338585610f34565b600191505092915050565b6002602052815f5260405f20602052805f5260405f205f91509150505481565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d5c575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d93575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ebd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb490611803565b60405180910390fd5b610ec7828261130e565b5050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b8152600401610f6f9190611705565b602060405180830381865afa158015610f8a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fae919061184b565b61102e5760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b8152600401610fec9190611705565b6020604051808303815f875af1158015611008573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061102c919061184b565b505b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461107a9190611931565b925050819055508160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546110cd9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516111319190611603565b60405180910390a350505050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b815260040161117a9190611705565b602060405180830381865afa158015611195573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b9919061184b565b6112395760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b81526004016111f79190611705565b6020604051808303815f875af1158015611213573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611237919061184b565b505b8160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546112859190611a34565b925050819055508160065f82825461129d9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516113019190611603565b60405180910390a3505050565b8060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461135a9190611931565b925050819055508060065f8282546113729190611931565b925050819055505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516113d69190611603565b60405180910390a35050565b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61141a816113e6565b8114611424575f80fd5b50565b5f8135905061143581611411565b92915050565b5f602082840312156114505761144f6113e2565b5b5f61145d84828501611427565b91505092915050565b5f8115159050919050565b61147a81611466565b82525050565b5f6020820190506114935f830184611471565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6114db82611499565b6114e581856114a3565b93506114f58185602086016114b3565b6114fe816114c1565b840191505092915050565b5f6020820190508181035f83015261152181846114d1565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61155282611529565b9050919050565b61156281611548565b811461156c575f80fd5b50565b5f8135905061157d81611559565b92915050565b5f819050919050565b61159581611583565b811461159f575f80fd5b50565b5f813590506115b08161158c565b92915050565b5f80604083850312156115cc576115cb6113e2565b5b5f6115d98582860161156f565b92505060206115ea858286016115a2565b9150509250929050565b6115fd81611583565b82525050565b5f6020820190506116165f8301846115f4565b92915050565b5f805f60608486031215611633576116326113e2565b5b5f6116408682870161156f565b93505060206116518682870161156f565b9250506040611662868287016115a2565b9150509250925092565b5f60ff82169050919050565b6116818161166c565b82525050565b5f60208201905061169a5f830184611678565b92915050565b5f602082840312156116b5576116b46113e2565b5b5f6116c2848285016115a2565b91505092915050565b5f602082840312156116e0576116df6113e2565b5b5f6116ed8482850161156f565b91505092915050565b6116ff81611548565b82525050565b5f6020820190506117185f8301846116f6565b92915050565b5f8060408385031215611734576117336113e2565b5b5f6117418582860161156f565b92505060206117528582860161156f565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806117a057607f821691505b6020821081036117b3576117b261175c565b5b50919050565b7f45524332303a2063616c6c6572206973206e6f742074686520636861696e00005f82015250565b5f6117ed601e836114a3565b91506117f8826117b9565b602082019050919050565b5f6020820190508181035f83015261181a816117e1565b9050919050565b61182a81611466565b8114611834575f80fd5b50565b5f8151905061184581611821565b92915050565b5f602082840312156118605761185f6113e2565b5b5f61186d84828501611837565b91505092915050565b7f45524332303a207472616e7366657220746f20626c6f636b65642061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f6118d06022836114a3565b91506118db82611876565b604082019050919050565b5f6020820190508181035f8301526118fd816118c4565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61193b82611583565b915061194683611583565b925082820390508181111561195e5761195d611904565b5b92915050565b7f45524332303a206d696e7420746f20626c6f636b6564206164647265737300005f82015250565b5f611998601e836114a3565b91506119a382611964565b602082019050919050565b5f6020820190508181035f8301526119c58161198c565b9050919050565b7f45524332303a206275726e2066726f6d206d6f64756c652061646472657373005f82015250565b5f611a00601f836114a3565b9150611a0b826119cc565b602082019050919050565b5f6020820190508181035f830152611a2d816119f4565b9050919050565b5f611a3e82611583565b9150611a4983611583565b9250828201905080821115611a6157611a60611904565b5b9291505056fea2646970667358221220de4043b1adb87162ffc06c0127fc335d705e04b467c9acd7522c8721ebd4c4bb64736f6c63430008190033222c2274696d656f75745f686569676874223a207b227265766973696f6e5f6e756d626572223a202230222c227265766973696f6e5f686569676874223a202230227d2c2274696d656f75745f74696d657374616d70223a20227b224074797065223a20222f6962632e6170706c69636174696f6e732e7472616e736665722e76312e4d73675472616e73666572222c22736f757263655f706f7274223a20227472616e73666572222c22736f757263655f6368616e6e656c223a2022a264697066735822122062e597885825f4a25ddd1c6cc3cb268b1ba175f3515b7a740be36eb6e19e38ed64736f6c63430008190033", +} + +// Erc20WrapperABI is the input ABI used to generate the binding from. +// Deprecated: Use Erc20WrapperMetaData.ABI instead. +var Erc20WrapperABI = Erc20WrapperMetaData.ABI + +// Erc20WrapperBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use Erc20WrapperMetaData.Bin instead. +var Erc20WrapperBin = Erc20WrapperMetaData.Bin + +// DeployErc20Wrapper deploys a new Ethereum contract, binding an instance of Erc20Wrapper to it. +func DeployErc20Wrapper(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Erc20Wrapper, error) { + parsed, err := Erc20WrapperMetaData.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(Erc20WrapperBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Erc20Wrapper{Erc20WrapperCaller: Erc20WrapperCaller{contract: contract}, Erc20WrapperTransactor: Erc20WrapperTransactor{contract: contract}, Erc20WrapperFilterer: Erc20WrapperFilterer{contract: contract}}, nil +} + +// Erc20Wrapper is an auto generated Go binding around an Ethereum contract. +type Erc20Wrapper struct { + Erc20WrapperCaller // Read-only binding to the contract + Erc20WrapperTransactor // Write-only binding to the contract + Erc20WrapperFilterer // Log filterer for contract events +} + +// Erc20WrapperCaller is an auto generated read-only Go binding around an Ethereum contract. +type Erc20WrapperCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Erc20WrapperTransactor is an auto generated write-only Go binding around an Ethereum contract. +type Erc20WrapperTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Erc20WrapperFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type Erc20WrapperFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Erc20WrapperSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type Erc20WrapperSession struct { + Contract *Erc20Wrapper // 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 +} + +// Erc20WrapperCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type Erc20WrapperCallerSession struct { + Contract *Erc20WrapperCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// Erc20WrapperTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type Erc20WrapperTransactorSession struct { + Contract *Erc20WrapperTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// Erc20WrapperRaw is an auto generated low-level Go binding around an Ethereum contract. +type Erc20WrapperRaw struct { + Contract *Erc20Wrapper // Generic contract binding to access the raw methods on +} + +// Erc20WrapperCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type Erc20WrapperCallerRaw struct { + Contract *Erc20WrapperCaller // Generic read-only contract binding to access the raw methods on +} + +// Erc20WrapperTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type Erc20WrapperTransactorRaw struct { + Contract *Erc20WrapperTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewErc20Wrapper creates a new instance of Erc20Wrapper, bound to a specific deployed contract. +func NewErc20Wrapper(address common.Address, backend bind.ContractBackend) (*Erc20Wrapper, error) { + contract, err := bindErc20Wrapper(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Erc20Wrapper{Erc20WrapperCaller: Erc20WrapperCaller{contract: contract}, Erc20WrapperTransactor: Erc20WrapperTransactor{contract: contract}, Erc20WrapperFilterer: Erc20WrapperFilterer{contract: contract}}, nil +} + +// NewErc20WrapperCaller creates a new read-only instance of Erc20Wrapper, bound to a specific deployed contract. +func NewErc20WrapperCaller(address common.Address, caller bind.ContractCaller) (*Erc20WrapperCaller, error) { + contract, err := bindErc20Wrapper(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &Erc20WrapperCaller{contract: contract}, nil +} + +// NewErc20WrapperTransactor creates a new write-only instance of Erc20Wrapper, bound to a specific deployed contract. +func NewErc20WrapperTransactor(address common.Address, transactor bind.ContractTransactor) (*Erc20WrapperTransactor, error) { + contract, err := bindErc20Wrapper(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &Erc20WrapperTransactor{contract: contract}, nil +} + +// NewErc20WrapperFilterer creates a new log filterer instance of Erc20Wrapper, bound to a specific deployed contract. +func NewErc20WrapperFilterer(address common.Address, filterer bind.ContractFilterer) (*Erc20WrapperFilterer, error) { + contract, err := bindErc20Wrapper(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &Erc20WrapperFilterer{contract: contract}, nil +} + +// bindErc20Wrapper binds a generic wrapper to an already deployed contract. +func bindErc20Wrapper(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := Erc20WrapperMetaData.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 (_Erc20Wrapper *Erc20WrapperRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Erc20Wrapper.Contract.Erc20WrapperCaller.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 (_Erc20Wrapper *Erc20WrapperRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.Erc20WrapperTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Erc20Wrapper *Erc20WrapperRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.Erc20WrapperTransactor.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 (_Erc20Wrapper *Erc20WrapperCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Erc20Wrapper.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 (_Erc20Wrapper *Erc20WrapperTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Erc20Wrapper *Erc20WrapperTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.contract.Transact(opts, method, params...) +} + +// OriginTokens is a free data retrieval call binding the contract method 0xb5ad1fb6. +// +// Solidity: function originTokens(address ) view returns(address) +func (_Erc20Wrapper *Erc20WrapperCaller) OriginTokens(opts *bind.CallOpts, arg0 common.Address) (common.Address, error) { + var out []interface{} + err := _Erc20Wrapper.contract.Call(opts, &out, "originTokens", arg0) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// OriginTokens is a free data retrieval call binding the contract method 0xb5ad1fb6. +// +// Solidity: function originTokens(address ) view returns(address) +func (_Erc20Wrapper *Erc20WrapperSession) OriginTokens(arg0 common.Address) (common.Address, error) { + return _Erc20Wrapper.Contract.OriginTokens(&_Erc20Wrapper.CallOpts, arg0) +} + +// OriginTokens is a free data retrieval call binding the contract method 0xb5ad1fb6. +// +// Solidity: function originTokens(address ) view returns(address) +func (_Erc20Wrapper *Erc20WrapperCallerSession) OriginTokens(arg0 common.Address) (common.Address, error) { + return _Erc20Wrapper.Contract.OriginTokens(&_Erc20Wrapper.CallOpts, arg0) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Erc20Wrapper *Erc20WrapperCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Erc20Wrapper.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Erc20Wrapper *Erc20WrapperSession) Owner() (common.Address, error) { + return _Erc20Wrapper.Contract.Owner(&_Erc20Wrapper.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Erc20Wrapper *Erc20WrapperCallerSession) Owner() (common.Address, error) { + return _Erc20Wrapper.Contract.Owner(&_Erc20Wrapper.CallOpts) +} + +// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (_Erc20Wrapper *Erc20WrapperCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _Erc20Wrapper.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (_Erc20Wrapper *Erc20WrapperSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _Erc20Wrapper.Contract.SupportsInterface(&_Erc20Wrapper.CallOpts, interfaceId) +} + +// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (_Erc20Wrapper *Erc20WrapperCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _Erc20Wrapper.Contract.SupportsInterface(&_Erc20Wrapper.CallOpts, interfaceId) +} + +// WrappedTokens is a free data retrieval call binding the contract method 0xd5c6b504. +// +// Solidity: function wrappedTokens(address ) view returns(address) +func (_Erc20Wrapper *Erc20WrapperCaller) WrappedTokens(opts *bind.CallOpts, arg0 common.Address) (common.Address, error) { + var out []interface{} + err := _Erc20Wrapper.contract.Call(opts, &out, "wrappedTokens", arg0) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// WrappedTokens is a free data retrieval call binding the contract method 0xd5c6b504. +// +// Solidity: function wrappedTokens(address ) view returns(address) +func (_Erc20Wrapper *Erc20WrapperSession) WrappedTokens(arg0 common.Address) (common.Address, error) { + return _Erc20Wrapper.Contract.WrappedTokens(&_Erc20Wrapper.CallOpts, arg0) +} + +// WrappedTokens is a free data retrieval call binding the contract method 0xd5c6b504. +// +// Solidity: function wrappedTokens(address ) view returns(address) +func (_Erc20Wrapper *Erc20WrapperCallerSession) WrappedTokens(arg0 common.Address) (common.Address, error) { + return _Erc20Wrapper.Contract.WrappedTokens(&_Erc20Wrapper.CallOpts, arg0) +} + +// CreateERC20 is a paid mutator transaction binding the contract method 0x06ef1a86. +// +// Solidity: function createERC20(string name, string symbol, uint8 decimals) returns(address) +func (_Erc20Wrapper *Erc20WrapperTransactor) CreateERC20(opts *bind.TransactOpts, name string, symbol string, decimals uint8) (*types.Transaction, error) { + return _Erc20Wrapper.contract.Transact(opts, "createERC20", name, symbol, decimals) +} + +// CreateERC20 is a paid mutator transaction binding the contract method 0x06ef1a86. +// +// Solidity: function createERC20(string name, string symbol, uint8 decimals) returns(address) +func (_Erc20Wrapper *Erc20WrapperSession) CreateERC20(name string, symbol string, decimals uint8) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.CreateERC20(&_Erc20Wrapper.TransactOpts, name, symbol, decimals) +} + +// CreateERC20 is a paid mutator transaction binding the contract method 0x06ef1a86. +// +// Solidity: function createERC20(string name, string symbol, uint8 decimals) returns(address) +func (_Erc20Wrapper *Erc20WrapperTransactorSession) CreateERC20(name string, symbol string, decimals uint8) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.CreateERC20(&_Erc20Wrapper.TransactOpts, name, symbol, decimals) +} + +// IbcAck is a paid mutator transaction binding the contract method 0x0d4f1f9d. +// +// Solidity: function ibc_ack(uint64 callback_id, bool success) returns() +func (_Erc20Wrapper *Erc20WrapperTransactor) IbcAck(opts *bind.TransactOpts, callback_id uint64, success bool) (*types.Transaction, error) { + return _Erc20Wrapper.contract.Transact(opts, "ibc_ack", callback_id, success) +} + +// IbcAck is a paid mutator transaction binding the contract method 0x0d4f1f9d. +// +// Solidity: function ibc_ack(uint64 callback_id, bool success) returns() +func (_Erc20Wrapper *Erc20WrapperSession) IbcAck(callback_id uint64, success bool) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.IbcAck(&_Erc20Wrapper.TransactOpts, callback_id, success) +} + +// IbcAck is a paid mutator transaction binding the contract method 0x0d4f1f9d. +// +// Solidity: function ibc_ack(uint64 callback_id, bool success) returns() +func (_Erc20Wrapper *Erc20WrapperTransactorSession) IbcAck(callback_id uint64, success bool) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.IbcAck(&_Erc20Wrapper.TransactOpts, callback_id, success) +} + +// IbcTimeout is a paid mutator transaction binding the contract method 0x31a503f0. +// +// Solidity: function ibc_timeout(uint64 callback_id) returns() +func (_Erc20Wrapper *Erc20WrapperTransactor) IbcTimeout(opts *bind.TransactOpts, callback_id uint64) (*types.Transaction, error) { + return _Erc20Wrapper.contract.Transact(opts, "ibc_timeout", callback_id) +} + +// IbcTimeout is a paid mutator transaction binding the contract method 0x31a503f0. +// +// Solidity: function ibc_timeout(uint64 callback_id) returns() +func (_Erc20Wrapper *Erc20WrapperSession) IbcTimeout(callback_id uint64) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.IbcTimeout(&_Erc20Wrapper.TransactOpts, callback_id) +} + +// IbcTimeout is a paid mutator transaction binding the contract method 0x31a503f0. +// +// Solidity: function ibc_timeout(uint64 callback_id) returns() +func (_Erc20Wrapper *Erc20WrapperTransactorSession) IbcTimeout(callback_id uint64) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.IbcTimeout(&_Erc20Wrapper.TransactOpts, callback_id) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Erc20Wrapper *Erc20WrapperTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _Erc20Wrapper.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Erc20Wrapper *Erc20WrapperSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.TransferOwnership(&_Erc20Wrapper.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Erc20Wrapper *Erc20WrapperTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.TransferOwnership(&_Erc20Wrapper.TransactOpts, newOwner) +} + +// Unwrap is a paid mutator transaction binding the contract method 0xfc078758. +// +// Solidity: function unwrap(string wrappedTokenDenom, address receiver, uint256 wrappedAmt) returns() +func (_Erc20Wrapper *Erc20WrapperTransactor) Unwrap(opts *bind.TransactOpts, wrappedTokenDenom string, receiver common.Address, wrappedAmt *big.Int) (*types.Transaction, error) { + return _Erc20Wrapper.contract.Transact(opts, "unwrap", wrappedTokenDenom, receiver, wrappedAmt) +} + +// Unwrap is a paid mutator transaction binding the contract method 0xfc078758. +// +// Solidity: function unwrap(string wrappedTokenDenom, address receiver, uint256 wrappedAmt) returns() +func (_Erc20Wrapper *Erc20WrapperSession) Unwrap(wrappedTokenDenom string, receiver common.Address, wrappedAmt *big.Int) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.Unwrap(&_Erc20Wrapper.TransactOpts, wrappedTokenDenom, receiver, wrappedAmt) +} + +// Unwrap is a paid mutator transaction binding the contract method 0xfc078758. +// +// Solidity: function unwrap(string wrappedTokenDenom, address receiver, uint256 wrappedAmt) returns() +func (_Erc20Wrapper *Erc20WrapperTransactorSession) Unwrap(wrappedTokenDenom string, receiver common.Address, wrappedAmt *big.Int) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.Unwrap(&_Erc20Wrapper.TransactOpts, wrappedTokenDenom, receiver, wrappedAmt) +} + +// Wrap is a paid mutator transaction binding the contract method 0x9a111432. +// +// Solidity: function wrap(string channel, address token, string receiver, uint256 amount, uint256 timeout) returns() +func (_Erc20Wrapper *Erc20WrapperTransactor) Wrap(opts *bind.TransactOpts, channel string, token common.Address, receiver string, amount *big.Int, timeout *big.Int) (*types.Transaction, error) { + return _Erc20Wrapper.contract.Transact(opts, "wrap", channel, token, receiver, amount, timeout) +} + +// Wrap is a paid mutator transaction binding the contract method 0x9a111432. +// +// Solidity: function wrap(string channel, address token, string receiver, uint256 amount, uint256 timeout) returns() +func (_Erc20Wrapper *Erc20WrapperSession) Wrap(channel string, token common.Address, receiver string, amount *big.Int, timeout *big.Int) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.Wrap(&_Erc20Wrapper.TransactOpts, channel, token, receiver, amount, timeout) +} + +// Wrap is a paid mutator transaction binding the contract method 0x9a111432. +// +// Solidity: function wrap(string channel, address token, string receiver, uint256 amount, uint256 timeout) returns() +func (_Erc20Wrapper *Erc20WrapperTransactorSession) Wrap(channel string, token common.Address, receiver string, amount *big.Int, timeout *big.Int) (*types.Transaction, error) { + return _Erc20Wrapper.Contract.Wrap(&_Erc20Wrapper.TransactOpts, channel, token, receiver, amount, timeout) +} + +// Erc20WrapperERC20CreatedIterator is returned from FilterERC20Created and is used to iterate over the raw logs and unpacked data for ERC20Created events raised by the Erc20Wrapper contract. +type Erc20WrapperERC20CreatedIterator struct { + Event *Erc20WrapperERC20Created // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *Erc20WrapperERC20CreatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(Erc20WrapperERC20Created) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(Erc20WrapperERC20Created) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *Erc20WrapperERC20CreatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *Erc20WrapperERC20CreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// Erc20WrapperERC20Created represents a ERC20Created event raised by the Erc20Wrapper contract. +type Erc20WrapperERC20Created struct { + Erc20 common.Address + Owner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterERC20Created is a free log retrieval operation binding the contract event 0x85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d1. +// +// Solidity: event ERC20Created(address indexed erc20, address indexed owner) +func (_Erc20Wrapper *Erc20WrapperFilterer) FilterERC20Created(opts *bind.FilterOpts, erc20 []common.Address, owner []common.Address) (*Erc20WrapperERC20CreatedIterator, error) { + + var erc20Rule []interface{} + for _, erc20Item := range erc20 { + erc20Rule = append(erc20Rule, erc20Item) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _Erc20Wrapper.contract.FilterLogs(opts, "ERC20Created", erc20Rule, ownerRule) + if err != nil { + return nil, err + } + return &Erc20WrapperERC20CreatedIterator{contract: _Erc20Wrapper.contract, event: "ERC20Created", logs: logs, sub: sub}, nil +} + +// WatchERC20Created is a free log subscription operation binding the contract event 0x85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d1. +// +// Solidity: event ERC20Created(address indexed erc20, address indexed owner) +func (_Erc20Wrapper *Erc20WrapperFilterer) WatchERC20Created(opts *bind.WatchOpts, sink chan<- *Erc20WrapperERC20Created, erc20 []common.Address, owner []common.Address) (event.Subscription, error) { + + var erc20Rule []interface{} + for _, erc20Item := range erc20 { + erc20Rule = append(erc20Rule, erc20Item) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _Erc20Wrapper.contract.WatchLogs(opts, "ERC20Created", erc20Rule, ownerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(Erc20WrapperERC20Created) + if err := _Erc20Wrapper.contract.UnpackLog(event, "ERC20Created", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseERC20Created is a log parse operation binding the contract event 0x85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d1. +// +// Solidity: event ERC20Created(address indexed erc20, address indexed owner) +func (_Erc20Wrapper *Erc20WrapperFilterer) ParseERC20Created(log types.Log) (*Erc20WrapperERC20Created, error) { + event := new(Erc20WrapperERC20Created) + if err := _Erc20Wrapper.contract.UnpackLog(event, "ERC20Created", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// Erc20WrapperOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Erc20Wrapper contract. +type Erc20WrapperOwnershipTransferredIterator struct { + Event *Erc20WrapperOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *Erc20WrapperOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(Erc20WrapperOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(Erc20WrapperOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *Erc20WrapperOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *Erc20WrapperOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// Erc20WrapperOwnershipTransferred represents a OwnershipTransferred event raised by the Erc20Wrapper contract. +type Erc20WrapperOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Erc20Wrapper *Erc20WrapperFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*Erc20WrapperOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _Erc20Wrapper.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &Erc20WrapperOwnershipTransferredIterator{contract: _Erc20Wrapper.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Erc20Wrapper *Erc20WrapperFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *Erc20WrapperOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _Erc20Wrapper.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(Erc20WrapperOwnershipTransferred) + if err := _Erc20Wrapper.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Erc20Wrapper *Erc20WrapperFilterer) ParseOwnershipTransferred(log types.Log) (*Erc20WrapperOwnershipTransferred, error) { + event := new(Erc20WrapperOwnershipTransferred) + if err := _Erc20Wrapper.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol new file mode 100644 index 00000000..cb294571 --- /dev/null +++ b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import "../util/Strings.sol"; +import "../i_cosmos/ICosmos.sol"; +import "../erc20_factory/ERC20Factory.sol"; +import "../i_erc20/IERC20.sol"; +import "../ownable/Ownable.sol"; +import "../erc20_registry/ERC20Registry.sol"; +import "../erc20_acl/ERC20ACL.sol"; +import {ERC165, IERC165} from "../erc165/ERC165.sol"; + +contract ERC20Wrapper is + Ownable, + ERC20Registry, + ERC165, + ERC20ACL, + ERC20Factory +{ + struct IbcCallBack { + address sender; + string wrappedTokenDenom; + uint wrappedAmt; + } + + uint8 constant WRAPPED_DECIMAL = 6; + string constant NAME_PREFIX = "Wrapped"; + string constant SYMBOL_PREFIX = "W"; + uint64 callBackId = 0; + mapping(address => address) public wrappedTokens; // origin -> wrapped + mapping(address => address) public originTokens; // wrapped -> origin + mapping(uint64 => IbcCallBack) private ibcCallBack; // id -> CallBackInfo + + /** + * @notice This function wraps the tokens and transfer the tokens by ibc transfer + */ + function wrap( + string memory channel, + address token, + string memory receiver, + uint amount, + uint timeout + ) public { + _ensureWrappedTokenExists(token); + // lock origin token + IERC20(token).transferFrom(msg.sender, address(this), amount); + uint wrappedAmt = _convertDecimal( + amount, + IERC20(token).decimals(), + WRAPPED_DECIMAL + ); + // mint wrapped token + ERC20(wrappedTokens[token]).mint(address(this), wrappedAmt); + + callBackId += 1; + // do ibc transfer wrapped token + COSMOS_CONTRACT.execute_cosmos( + _ibc_transfer( + channel, + wrappedTokens[token], + wrappedAmt, + timeout, + receiver + ) + ); + } + + /** + * @notice This function is executed as an IBC hook to unwrap the wrapped tokens. + * @dev This function is used by a hook and requires sender approve to this contract to burn wrapped tokens. + */ + function unwrap( + string memory wrappedTokenDenom, + address receiver, + uint wrappedAmt + ) public { + address wrappedToken = address( + COSMOS_CONTRACT.to_erc20(wrappedTokenDenom) + ); + require( + originTokens[wrappedToken] != address(0), + "origin token doesn't exist" + ); + // burn wrapped token + ERC20(wrappedToken).burnFrom(msg.sender, wrappedAmt); + // unlock origin token and transfer to receiver + uint amount = _convertDecimal( + wrappedAmt, + WRAPPED_DECIMAL, + IERC20(originTokens[wrappedToken]).decimals() + ); + + ERC20(originTokens[wrappedToken]).transfer(receiver, amount); + } + + function ibc_ack(uint64 callback_id, bool success) external { + if (success) { + return; + } + _handleFailedIbcTransfer(callback_id); + } + + function ibc_timeout(uint64 callback_id) external { + _handleFailedIbcTransfer(callback_id); + } + + // internal function // + function _handleFailedIbcTransfer(uint64 callback_id) internal { + IbcCallBack memory callback = ibcCallBack[callback_id]; + unwrap( + callback.wrappedTokenDenom, + callback.sender, + callback.wrappedAmt + ); + } + + function _createERC20( + string memory name, + string memory symbol, + uint8 decimals + ) internal returns (address) { + ERC20 erc20 = new ERC20(name, symbol, decimals); + + // register the ERC20 contract with the ERC20 registry + ERC20_REGISTRY_CONTRACT.register_erc20_from_factory(address(erc20)); + + emit ERC20Created(address(erc20), address(this)); + return address(erc20); + } + + function _ensureWrappedTokenExists(address token) internal { + if (wrappedTokens[token] == address(0)) { + address wrappedToken = _createERC20( + string.concat(NAME_PREFIX, IERC20(token).name()), + string.concat(SYMBOL_PREFIX, IERC20(token).symbol()), + WRAPPED_DECIMAL + ); + wrappedTokens[token] = wrappedToken; + originTokens[wrappedToken] = token; + } + } + + function _convertDecimal( + uint amount, + uint8 decimal, + uint8 newDecimal + ) internal pure returns (uint convertedAmount) { + if (decimal > newDecimal) { + uint factor = 10 ** uint(decimal - newDecimal); + convertedAmount = amount / factor; + } else if (decimal < newDecimal) { + uint factor = 10 ** uint(newDecimal - decimal); + convertedAmount = amount * factor; + } else { + convertedAmount = amount; + } + require(convertedAmount != 0, "converted amount is zero"); + } + + function _ibc_transfer( + string memory channel, + address token, + uint amount, + uint timeout, + string memory receiver + ) internal returns (string memory message) { + // Construct the IBC transfer message + message = string( + abi.encodePacked( + '{"@type": "/ibc.applications.transfer.v1.MsgTransfer",', + '"source_port": "transfer",', + '"source_channel": "', + channel, + '",', + '"token": { "denom": "', + COSMOS_CONTRACT.to_denom(token), + '",', + '"amount": "', + Strings.toString(amount), + '"},', + '"sender": "', + COSMOS_CONTRACT.to_cosmos_address(address(this)), + '",', + '"receiver": "', + receiver, + '",', + '"timeout_height": {"revision_number": "0","revision_height": "0"},', + '"timeout_timestamp": "', + Strings.toString(timeout), + '",', + '"memo": "",', + '"async_callback": {"id": "', + Strings.toString(callBackId), + '",', + '"contract_address": "', + Strings.toHexString(address(this)), + '"}}' + ) + ); + } +} diff --git a/x/evm/contracts/util/Strings.go b/x/evm/contracts/util/Strings.go new file mode 100644 index 00000000..44245173 --- /dev/null +++ b/x/evm/contracts/util/Strings.go @@ -0,0 +1,203 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package util + +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 +) + +// UtilMetaData contains all meta data concerning the Util contract. +var UtilMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"StringsInsufficientHexLength\",\"type\":\"error\"}]", + Bin: "0x6055604b600b8282823980515f1a607314603f577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea2646970667358221220c8a20e32684b8eb475517477c61e8fbe77e3c5335efa1a66ec78960a607261e064736f6c63430008190033", +} + +// UtilABI is the input ABI used to generate the binding from. +// Deprecated: Use UtilMetaData.ABI instead. +var UtilABI = UtilMetaData.ABI + +// UtilBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use UtilMetaData.Bin instead. +var UtilBin = UtilMetaData.Bin + +// DeployUtil deploys a new Ethereum contract, binding an instance of Util to it. +func DeployUtil(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Util, error) { + parsed, err := UtilMetaData.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(UtilBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Util{UtilCaller: UtilCaller{contract: contract}, UtilTransactor: UtilTransactor{contract: contract}, UtilFilterer: UtilFilterer{contract: contract}}, nil +} + +// Util is an auto generated Go binding around an Ethereum contract. +type Util struct { + UtilCaller // Read-only binding to the contract + UtilTransactor // Write-only binding to the contract + UtilFilterer // Log filterer for contract events +} + +// UtilCaller is an auto generated read-only Go binding around an Ethereum contract. +type UtilCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UtilTransactor is an auto generated write-only Go binding around an Ethereum contract. +type UtilTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UtilFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type UtilFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UtilSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type UtilSession struct { + Contract *Util // 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 +} + +// UtilCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type UtilCallerSession struct { + Contract *UtilCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// UtilTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type UtilTransactorSession struct { + Contract *UtilTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// UtilRaw is an auto generated low-level Go binding around an Ethereum contract. +type UtilRaw struct { + Contract *Util // Generic contract binding to access the raw methods on +} + +// UtilCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type UtilCallerRaw struct { + Contract *UtilCaller // Generic read-only contract binding to access the raw methods on +} + +// UtilTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type UtilTransactorRaw struct { + Contract *UtilTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewUtil creates a new instance of Util, bound to a specific deployed contract. +func NewUtil(address common.Address, backend bind.ContractBackend) (*Util, error) { + contract, err := bindUtil(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Util{UtilCaller: UtilCaller{contract: contract}, UtilTransactor: UtilTransactor{contract: contract}, UtilFilterer: UtilFilterer{contract: contract}}, nil +} + +// NewUtilCaller creates a new read-only instance of Util, bound to a specific deployed contract. +func NewUtilCaller(address common.Address, caller bind.ContractCaller) (*UtilCaller, error) { + contract, err := bindUtil(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &UtilCaller{contract: contract}, nil +} + +// NewUtilTransactor creates a new write-only instance of Util, bound to a specific deployed contract. +func NewUtilTransactor(address common.Address, transactor bind.ContractTransactor) (*UtilTransactor, error) { + contract, err := bindUtil(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &UtilTransactor{contract: contract}, nil +} + +// NewUtilFilterer creates a new log filterer instance of Util, bound to a specific deployed contract. +func NewUtilFilterer(address common.Address, filterer bind.ContractFilterer) (*UtilFilterer, error) { + contract, err := bindUtil(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &UtilFilterer{contract: contract}, nil +} + +// bindUtil binds a generic wrapper to an already deployed contract. +func bindUtil(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := UtilMetaData.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 (_Util *UtilRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Util.Contract.UtilCaller.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 (_Util *UtilRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Util.Contract.UtilTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Util *UtilRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Util.Contract.UtilTransactor.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 (_Util *UtilCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Util.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 (_Util *UtilTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Util.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Util *UtilTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Util.Contract.contract.Transact(opts, method, params...) +} diff --git a/x/evm/contracts/util/Strings.sol b/x/evm/contracts/util/Strings.sol new file mode 100644 index 00000000..415c5a2f --- /dev/null +++ b/x/evm/contracts/util/Strings.sol @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +//ref. https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol +library Strings { + bytes16 private constant HEX_DIGITS = "0123456789abcdef"; + uint8 private constant ADDRESS_LENGTH = 20; + /** + * @dev The `value` string doesn't fit in the specified `length`. + */ + error StringsInsufficientHexLength(uint256 value, uint256 length); + + function toHexString( + uint256 value, + uint256 length + ) internal pure returns (string memory) { + uint256 localValue = value; + bytes memory buffer = new bytes(2 * length + 2); + buffer[0] = "0"; + buffer[1] = "x"; + for (uint256 i = 2 * length + 1; i > 1; --i) { + buffer[i] = HEX_DIGITS[localValue & 0xf]; + localValue >>= 4; + } + if (localValue != 0) { + revert StringsInsufficientHexLength(value, length); + } + return string(buffer); + } + + function toHexString(address addr) internal pure returns (string memory) { + return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); + } + + function toString(uint256 value) internal pure returns (string memory) { + unchecked { + uint256 length = log10(value) + 1; + string memory buffer = new string(length); + uint256 ptr; + assembly ("memory-safe") { + ptr := add(buffer, add(32, length)) + } + while (true) { + ptr--; + assembly ("memory-safe") { + mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) + } + value /= 10; + if (value == 0) break; + } + return buffer; + } + } + + function log10(uint256 value) internal pure returns (uint256) { + uint256 result = 0; + unchecked { + if (value >= 10 ** 64) { + value /= 10 ** 64; + result += 64; + } + if (value >= 10 ** 32) { + value /= 10 ** 32; + result += 32; + } + if (value >= 10 ** 16) { + value /= 10 ** 16; + result += 16; + } + if (value >= 10 ** 8) { + value /= 10 ** 8; + result += 8; + } + if (value >= 10 ** 4) { + value /= 10 ** 4; + result += 4; + } + if (value >= 10 ** 2) { + value /= 10 ** 2; + result += 2; + } + if (value >= 10 ** 1) { + result += 1; + } + } + return result; + } +} diff --git a/x/evm/keeper/erc721_test.go b/x/evm/keeper/erc721_test.go index b99e219f..362c8f67 100644 --- a/x/evm/keeper/erc721_test.go +++ b/x/evm/keeper/erc721_test.go @@ -20,7 +20,7 @@ func Test_CreateCollection(t *testing.T) { classId := "test-class-id" classUri := "test-class-uri" - contractAddr := crypto.CreateAddress(types.StdAddress, 1) + contractAddr := crypto.CreateAddress(types.StdAddress, 2) err = erc721Keeper.CreateOrUpdateClass(ctx, classId, classUri, "") require.NoError(t, err) diff --git a/x/evm/keeper/genesis.go b/x/evm/keeper/genesis.go index b06e4247..f006e47b 100644 --- a/x/evm/keeper/genesis.go +++ b/x/evm/keeper/genesis.go @@ -12,16 +12,17 @@ import ( "github.com/initia-labs/minievm/x/evm/types" ) -// Initialize initializes the EVM state at genesis -// 1. deploy and store erc20 factory contract -// 2. deploy fee denom erc20 coins at genesis bootstrapping with 18 decimals +// Initialize initializes the EVM state at genesis by performing the following steps: +// 1. Deploy and store the ERC20 factory contract. +// 2. Deploy fee denom ERC20 coins at genesis bootstrapping with 18 decimals. +// 3. Deploy and store the wrapper ERC20 factory contract for IBC transfers to the destination chain (not compatible due to 18 decimals). func (k Keeper) Initialize(ctx context.Context) error { return k.InitializeWithDecimals(ctx, types.EtherDecimals) } // InitializeWithDecimals initializes the EVM state at genesis with the given decimals func (k Keeper) InitializeWithDecimals(ctx context.Context, decimals uint8) error { - // 1. deploy and store erc20 factory contract + // 1. Deploy and store the ERC20 factory contract. code, err := hexutil.Decode(erc20_factory.Erc20FactoryBin) if err != nil { return err @@ -42,12 +43,23 @@ func (k Keeper) InitializeWithDecimals(ctx context.Context, decimals uint8) erro return err } - // 2. deploy fee denom erc20 coins at genesis bootstrapping + // 2. Deploy fee denom ERC20 coins at genesis bootstrapping with decimals. err = k.erc20Keeper.CreateERC20(ctx, params.FeeDenom, decimals) if err != nil { return err } + // 3. Deploy and store the wrapper ERC20 factory contract for IBC transfers to the destination chain (not compatible due to 18 decimals). + _, wrapperAddr, _, err := k.EVMCreate2(ctx, types.StdAddress, code, nil, types.ERC20WrapperSalt) + if err != nil { + return err + } + + err = k.ERC20WrapperAddr.Set(ctx, wrapperAddr.Bytes()) + if err != nil { + return err + } + return nil } @@ -65,6 +77,9 @@ func (k Keeper) InitGenesis(ctx context.Context, genState types.GenesisState) er if err := k.ERC20FactoryAddr.Set(ctx, genState.Erc20Factory); err != nil { return err } + if err := k.ERC20WrapperAddr.Set(ctx, genState.Erc20Wrapper); err != nil { + return err + } } for _, kv := range genState.KeyValues { @@ -214,6 +229,11 @@ func (k Keeper) ExportGenesis(ctx context.Context) *types.GenesisState { panic(err) } + wrapperAddr, err := k.ERC20WrapperAddr.Get(ctx) + if err != nil { + panic(err) + } + return &types.GenesisState{ Params: params, KeyValues: kvs, @@ -222,6 +242,7 @@ func (k Keeper) ExportGenesis(ctx context.Context) *types.GenesisState { DenomTraces: denomTraces, ClassTraces: classTraces, Erc20Factory: factoryAddr, + Erc20Wrapper: wrapperAddr, EVMBlockHashes: evmBlockHashes, } } diff --git a/x/evm/keeper/genesis_test.go b/x/evm/keeper/genesis_test.go index 7008cde9..94985518 100644 --- a/x/evm/keeper/genesis_test.go +++ b/x/evm/keeper/genesis_test.go @@ -16,6 +16,7 @@ func Test_Genesis(t *testing.T) { {1, 2, 3}, {4, 5, 6}, } + genState.Erc20Wrapper = []byte{5, 6, 7, 8} genState.Erc20Stores = []types.GenesisERC20Stores{ { Address: []byte{1, 2, 3}, diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index 3b355e50..9842ad1c 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -60,6 +60,7 @@ type Keeper struct { // erc20 stores of users ERC20FactoryAddr collections.Item[[]byte] + ERC20WrapperAddr collections.Item[[]byte] ERC20s collections.KeySet[[]byte] ERC20Stores collections.KeySet[collections.Pair[[]byte, []byte]] ERC20DenomsByContractAddr collections.Map[[]byte, string] @@ -129,6 +130,7 @@ func NewKeeper( TransientAccessList: collections.NewKeySet(tsb, types.TransientAccessListPrefix, "transient_access_list", collections.PairKeyCodec(collections.Uint64Key, collections.BytesKey)), TransientRefund: collections.NewMap(tsb, types.TransientRefundPrefix, "transient_refund", collections.Uint64Key, collections.Uint64Value), + ERC20WrapperAddr: collections.NewItem(sb, types.ERC20WrapperAddrKey, "erc20_wrapper_addr", collections.BytesValue), ERC20FactoryAddr: collections.NewItem(sb, types.ERC20FactoryAddrKey, "erc20_factory_addr", collections.BytesValue), ERC20s: collections.NewKeySet(sb, types.ERC20sPrefix, "erc20s", collections.BytesKey), ERC20Stores: collections.NewKeySet(sb, types.ERC20StoresPrefix, "erc20_stores", collections.PairKeyCodec(collections.BytesKey, collections.BytesKey)), @@ -253,6 +255,15 @@ func (k Keeper) GetERC20FactoryAddr(ctx context.Context) (common.Address, error) return common.BytesToAddress(factoryAddr), nil } +func (k Keeper) GetERC20WrapperAddr(ctx context.Context) (common.Address, error) { + wrapperAddr, err := k.ERC20WrapperAddr.Get(ctx) + if err != nil { + return common.Address{}, types.ErrFailedToGetERC20WrapperAddr.Wrap(err.Error()) + } + + return common.BytesToAddress(wrapperAddr), nil +} + // keep track recent 256 block hashes // - https://www.ethervm.io/#40 func (k Keeper) TrackBlockHash(ctx context.Context, blockHeight uint64, hash common.Hash) error { diff --git a/x/evm/keeper/query_server.go b/x/evm/keeper/query_server.go index ea9e2a5c..165b2685 100644 --- a/x/evm/keeper/query_server.go +++ b/x/evm/keeper/query_server.go @@ -156,6 +156,18 @@ func (qs *queryServerImpl) ERC20Factory(ctx context.Context, req *types.QueryERC }, nil } +// ERC20Wrapper implements types.QueryServer. +func (qs *queryServerImpl) ERC20Wrapper(ctx context.Context, req *types.QueryERC20WrapperRequest) (*types.QueryERC20WrapperResponse, error) { + wrapper, err := qs.Keeper.GetERC20WrapperAddr(ctx) + if err != nil { + return nil, err + } + + return &types.QueryERC20WrapperResponse{ + Address: wrapper.Hex(), + }, nil +} + // ContractAddrByDenom implements types.QueryServer. func (qs *queryServerImpl) ContractAddrByDenom(ctx context.Context, req *types.QueryContractAddrByDenomRequest) (*types.QueryContractAddrByDenomResponse, error) { contractAddr, err := types.DenomToContractAddr(ctx, qs, req.Denom) diff --git a/x/evm/keeper/query_server_test.go b/x/evm/keeper/query_server_test.go index 0a8e6840..3726f45d 100644 --- a/x/evm/keeper/query_server_test.go +++ b/x/evm/keeper/query_server_test.go @@ -64,3 +64,17 @@ func Test_Query_ERC20Factory(t *testing.T) { require.Equal(t, factoryAddr.Hex(), res.Address) } + +func Test_Query_ERC20Wrapper(t *testing.T) { + ctx, input := createDefaultTestInput(t) + + wrapperAddr, err := input.EVMKeeper.GetERC20WrapperAddr(ctx) + require.NoError(t, err) + + qs := keeper.NewQueryServer(&input.EVMKeeper) + res, err := qs.ERC20Wrapper(ctx, &types.QueryERC20WrapperRequest{}) + require.NoError(t, err) + + require.Equal(t, wrapperAddr.Hex(), res.Address) +} + diff --git a/x/evm/types/address.go b/x/evm/types/address.go index 1734bd59..30b6e692 100644 --- a/x/evm/types/address.go +++ b/x/evm/types/address.go @@ -14,6 +14,7 @@ var StdAddress common.Address = common.HexToAddress("0x1") // ERC20FactorySalt is the salt used to create the ERC20 factory address var ERC20FactorySalt = uint64(1) +var ERC20WrapperSalt = uint64(2) // 0xf1 Cosmos precompile address var CosmosPrecompileAddress common.Address = common.HexToAddress("0xf1") diff --git a/x/evm/types/errors.go b/x/evm/types/errors.go index d619daa2..e4e631e1 100644 --- a/x/evm/types/errors.go +++ b/x/evm/types/errors.go @@ -34,6 +34,7 @@ var ( ErrFailedToGetERC20FactoryAddr = errorsmod.Register(ModuleName, 25, "Failed to get ERC20 factory address") ErrInvalidFeeDenom = errorsmod.Register(ModuleName, 26, "Invalid fee denom") ErrInvalidGasRefundRatio = errorsmod.Register(ModuleName, 27, "Invalid gas refund ratio") + ErrFailedToGetERC20WrapperAddr = errorsmod.Register(ModuleName, 28, "Failed to get ERC20 wrapper address") ) func NewRevertError(revert []byte) error { diff --git a/x/evm/types/genesis.pb.go b/x/evm/types/genesis.pb.go index 65bc6fbc..ca2c8e1a 100644 --- a/x/evm/types/genesis.pb.go +++ b/x/evm/types/genesis.pb.go @@ -37,7 +37,9 @@ type GenesisState struct { ClassTraces []GenesisClassTrace `protobuf:"bytes,6,rep,name=class_traces,json=classTraces,proto3" json:"class_traces" yaml:"class_traces"` EVMBlockHashes []GenesisEVMBlockHash `protobuf:"bytes,7,rep,name=evm_block_hashes,json=evmBlockHashes,proto3" json:"evm_block_hashes" yaml:"evm_block_hashes"` // erc20 factory contract address - Erc20Factory []byte `protobuf:"bytes,8,opt,name=erc20_factory,json=erc20Factory,proto3" json:"erc20_factory,omitempty"` + Erc20Factory []byte `protobuf:"bytes,5,opt,name=erc20_factory,json=erc20Factory,proto3" json:"erc20_factory,omitempty"` + // erc20 wrapper contract address + Erc20Wrapper []byte `protobuf:"bytes,6,opt,name=erc20_wrapper,json=erc20Wrapper,proto3" json:"erc20_wrapper,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -129,6 +131,13 @@ func (m *GenesisState) GetErc20Factory() []byte { return nil } +func (m *GenesisState) GetErc20Wrapper() []byte { + if m != nil { + return m.Erc20Wrapper + } + return nil +} + // GenesisKeyValue defines store KV values. type GenesisKeyValue struct { Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` @@ -475,6 +484,13 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Erc20Wrapper) > 0 { + i -= len(m.Erc20Wrapper) + copy(dAtA[i:], m.Erc20Wrapper) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Erc20Wrapper))) + i-- + dAtA[i] = 0x32 + } if len(m.Erc20Factory) > 0 { i -= len(m.Erc20Factory) copy(dAtA[i:], m.Erc20Factory) @@ -825,6 +841,10 @@ func (m *GenesisState) Size() (n int) { if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } + l = len(m.Erc20Wrapper) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } return n } @@ -1222,6 +1242,40 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { m.Erc20Factory = []byte{} } iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Erc20Wrapper", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Erc20Wrapper = append(m.Erc20Wrapper[:0], dAtA[iNdEx:postIndex]...) + if m.Erc20Wrapper == nil { + m.Erc20Wrapper = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/evm/types/keys.go b/x/evm/types/keys.go index ae1af147..8c6aa2bc 100644 --- a/x/evm/types/keys.go +++ b/x/evm/types/keys.go @@ -42,6 +42,7 @@ var ( ParamsKey = []byte{0x51} // key of parameters for module x/evm ERC20FactoryAddrKey = []byte{0x61} // key of erc20 factory contract address + ERC20WrapperAddrKey = []byte{0x62} // key of erc20 wrapper contract address ) // ContextKey type for context key diff --git a/x/evm/types/query.pb.go b/x/evm/types/query.pb.go index 7aeda17e..b86758aa 100644 --- a/x/evm/types/query.pb.go +++ b/x/evm/types/query.pb.go @@ -270,6 +270,84 @@ func (m *QueryERC20FactoryResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryERC20FactoryResponse proto.InternalMessageInfo +// QueryERC20WrapperRequest is the request type for the Query/ERC20Wrapper RPC +// method +type QueryERC20WrapperRequest struct { +} + +func (m *QueryERC20WrapperRequest) Reset() { *m = QueryERC20WrapperRequest{} } +func (m *QueryERC20WrapperRequest) String() string { return proto.CompactTextString(m) } +func (*QueryERC20WrapperRequest) ProtoMessage() {} +func (*QueryERC20WrapperRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_2bf9e0bee7cfd1a4, []int{6} +} +func (m *QueryERC20WrapperRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryERC20WrapperRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryERC20WrapperRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryERC20WrapperRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryERC20WrapperRequest.Merge(m, src) +} +func (m *QueryERC20WrapperRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryERC20WrapperRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryERC20WrapperRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryERC20WrapperRequest proto.InternalMessageInfo + +// QueryERC20WrapperResponse is the response type for the Query/ERC20Wrapper RPC +// method +type QueryERC20WrapperResponse struct { + // 0x prefixed hex address + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` +} + +func (m *QueryERC20WrapperResponse) Reset() { *m = QueryERC20WrapperResponse{} } +func (m *QueryERC20WrapperResponse) String() string { return proto.CompactTextString(m) } +func (*QueryERC20WrapperResponse) ProtoMessage() {} +func (*QueryERC20WrapperResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_2bf9e0bee7cfd1a4, []int{7} +} +func (m *QueryERC20WrapperResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryERC20WrapperResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryERC20WrapperResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryERC20WrapperResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryERC20WrapperResponse.Merge(m, src) +} +func (m *QueryERC20WrapperResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryERC20WrapperResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryERC20WrapperResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryERC20WrapperResponse proto.InternalMessageInfo + // QueryContractAddrByDenomRequest is the request type for the Query/ContractAddrByDenom RPC // method type QueryContractAddrByDenomRequest struct { @@ -280,7 +358,7 @@ func (m *QueryContractAddrByDenomRequest) Reset() { *m = QueryContractAd func (m *QueryContractAddrByDenomRequest) String() string { return proto.CompactTextString(m) } func (*QueryContractAddrByDenomRequest) ProtoMessage() {} func (*QueryContractAddrByDenomRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_2bf9e0bee7cfd1a4, []int{6} + return fileDescriptor_2bf9e0bee7cfd1a4, []int{8} } func (m *QueryContractAddrByDenomRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -320,7 +398,7 @@ func (m *QueryContractAddrByDenomResponse) Reset() { *m = QueryContractA func (m *QueryContractAddrByDenomResponse) String() string { return proto.CompactTextString(m) } func (*QueryContractAddrByDenomResponse) ProtoMessage() {} func (*QueryContractAddrByDenomResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_2bf9e0bee7cfd1a4, []int{7} + return fileDescriptor_2bf9e0bee7cfd1a4, []int{9} } func (m *QueryContractAddrByDenomResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -360,7 +438,7 @@ func (m *QueryDenomRequest) Reset() { *m = QueryDenomRequest{} } func (m *QueryDenomRequest) String() string { return proto.CompactTextString(m) } func (*QueryDenomRequest) ProtoMessage() {} func (*QueryDenomRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_2bf9e0bee7cfd1a4, []int{8} + return fileDescriptor_2bf9e0bee7cfd1a4, []int{10} } func (m *QueryDenomRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -399,7 +477,7 @@ func (m *QueryDenomResponse) Reset() { *m = QueryDenomResponse{} } func (m *QueryDenomResponse) String() string { return proto.CompactTextString(m) } func (*QueryDenomResponse) ProtoMessage() {} func (*QueryDenomResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_2bf9e0bee7cfd1a4, []int{9} + return fileDescriptor_2bf9e0bee7cfd1a4, []int{11} } func (m *QueryDenomResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -448,7 +526,7 @@ func (m *QueryCallRequest) Reset() { *m = QueryCallRequest{} } func (m *QueryCallRequest) String() string { return proto.CompactTextString(m) } func (*QueryCallRequest) ProtoMessage() {} func (*QueryCallRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_2bf9e0bee7cfd1a4, []int{10} + return fileDescriptor_2bf9e0bee7cfd1a4, []int{12} } func (m *QueryCallRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -493,7 +571,7 @@ func (m *TraceOptions) Reset() { *m = TraceOptions{} } func (m *TraceOptions) String() string { return proto.CompactTextString(m) } func (*TraceOptions) ProtoMessage() {} func (*TraceOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_2bf9e0bee7cfd1a4, []int{11} + return fileDescriptor_2bf9e0bee7cfd1a4, []int{13} } func (m *TraceOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -537,7 +615,7 @@ func (m *QueryCallResponse) Reset() { *m = QueryCallResponse{} } func (m *QueryCallResponse) String() string { return proto.CompactTextString(m) } func (*QueryCallResponse) ProtoMessage() {} func (*QueryCallResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_2bf9e0bee7cfd1a4, []int{12} + return fileDescriptor_2bf9e0bee7cfd1a4, []int{14} } func (m *QueryCallResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -574,7 +652,7 @@ func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } func (*QueryParamsRequest) ProtoMessage() {} func (*QueryParamsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_2bf9e0bee7cfd1a4, []int{13} + return fileDescriptor_2bf9e0bee7cfd1a4, []int{15} } func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -613,7 +691,7 @@ func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } func (*QueryParamsResponse) ProtoMessage() {} func (*QueryParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_2bf9e0bee7cfd1a4, []int{14} + return fileDescriptor_2bf9e0bee7cfd1a4, []int{16} } func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -649,6 +727,8 @@ func init() { proto.RegisterType((*QueryStateResponse)(nil), "minievm.evm.v1.QueryStateResponse") proto.RegisterType((*QueryERC20FactoryRequest)(nil), "minievm.evm.v1.QueryERC20FactoryRequest") proto.RegisterType((*QueryERC20FactoryResponse)(nil), "minievm.evm.v1.QueryERC20FactoryResponse") + proto.RegisterType((*QueryERC20WrapperRequest)(nil), "minievm.evm.v1.QueryERC20WrapperRequest") + proto.RegisterType((*QueryERC20WrapperResponse)(nil), "minievm.evm.v1.QueryERC20WrapperResponse") proto.RegisterType((*QueryContractAddrByDenomRequest)(nil), "minievm.evm.v1.QueryContractAddrByDenomRequest") proto.RegisterType((*QueryContractAddrByDenomResponse)(nil), "minievm.evm.v1.QueryContractAddrByDenomResponse") proto.RegisterType((*QueryDenomRequest)(nil), "minievm.evm.v1.QueryDenomRequest") @@ -663,68 +743,70 @@ func init() { func init() { proto.RegisterFile("minievm/evm/v1/query.proto", fileDescriptor_2bf9e0bee7cfd1a4) } var fileDescriptor_2bf9e0bee7cfd1a4 = []byte{ - // 968 bytes of a gzipped FileDescriptorProto + // 1000 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0x41, 0x6f, 0x1b, 0x45, - 0x14, 0xf6, 0x26, 0x76, 0xe2, 0x3c, 0xa7, 0x55, 0x3a, 0x31, 0x91, 0xb3, 0x2a, 0x6b, 0x77, 0x0b, - 0xd4, 0x8d, 0xc8, 0x6e, 0x6a, 0x2a, 0xb5, 0x2a, 0xa7, 0xba, 0x05, 0x04, 0x14, 0x01, 0x5b, 0x4e, - 0x5c, 0xac, 0x89, 0x77, 0xd8, 0xac, 0xe2, 0xdd, 0x71, 0x76, 0xc6, 0x01, 0x53, 0x95, 0x03, 0xe2, - 0x07, 0x20, 0xc1, 0x8d, 0x0b, 0x07, 0x0e, 0xe5, 0xc6, 0x8d, 0xbf, 0x90, 0x63, 0x25, 0x2e, 0x88, - 0x43, 0x05, 0x0e, 0x12, 0xfc, 0x0c, 0x34, 0x6f, 0x67, 0x5b, 0x7b, 0xbd, 0x8e, 0xc2, 0xc1, 0xd6, - 0xbc, 0x37, 0xdf, 0xbc, 0xef, 0x7b, 0xef, 0xcd, 0x3c, 0x2d, 0x98, 0x51, 0x18, 0x87, 0xec, 0x38, - 0x72, 0xd5, 0xef, 0xf8, 0x86, 0x7b, 0x34, 0x62, 0xc9, 0xd8, 0x19, 0x26, 0x5c, 0x72, 0x72, 0x51, - 0xef, 0x39, 0xea, 0x77, 0x7c, 0xc3, 0xbc, 0x44, 0xa3, 0x30, 0xe6, 0x2e, 0xfe, 0xa7, 0x10, 0xb3, - 0x1e, 0xf0, 0x80, 0xe3, 0xd2, 0x55, 0x2b, 0xed, 0xbd, 0x1c, 0x70, 0x1e, 0x0c, 0x98, 0x4b, 0x87, - 0xa1, 0x4b, 0xe3, 0x98, 0x4b, 0x2a, 0x43, 0x1e, 0x0b, 0xbd, 0x9b, 0xa7, 0x94, 0xe3, 0x21, 0xd3, - 0x7b, 0xf6, 0x2d, 0xd8, 0xf8, 0x58, 0x29, 0xb8, 0xc7, 0x7d, 0xe6, 0xb1, 0xa3, 0x11, 0x13, 0x92, - 0x5c, 0x85, 0x0b, 0x7d, 0x1e, 0xcb, 0x84, 0xf6, 0x65, 0x8f, 0xfa, 0x7e, 0xd2, 0x30, 0x5a, 0x46, - 0x7b, 0xcd, 0x5b, 0xcf, 0x9c, 0x77, 0x7d, 0x3f, 0xb1, 0x77, 0xe1, 0xd2, 0xd4, 0x41, 0x31, 0xe4, - 0xb1, 0x60, 0x84, 0x40, 0xb9, 0xcf, 0x7d, 0xa6, 0x0f, 0xe0, 0xfa, 0x4e, 0xf9, 0xdf, 0x1f, 0x9b, - 0x86, 0xfd, 0x9e, 0x86, 0x3f, 0x94, 0x54, 0xfe, 0x2f, 0x22, 0xb2, 0x01, 0xcb, 0x87, 0x6c, 0xdc, - 0x58, 0xc2, 0x2d, 0xb5, 0xb4, 0xf7, 0x80, 0x4c, 0xc7, 0xd2, 0xdc, 0x75, 0xa8, 0x1c, 0xd3, 0xc1, - 0x28, 0x23, 0x4f, 0x0d, 0xcd, 0x6e, 0x42, 0x03, 0x4f, 0xbc, 0xe5, 0xdd, 0xeb, 0xec, 0xbd, 0x4d, - 0xfb, 0x92, 0x27, 0x63, 0x2d, 0xc2, 0x7e, 0x13, 0xb6, 0x0b, 0xf6, 0x74, 0xd0, 0x06, 0xac, 0x2a, - 0x61, 0x4c, 0x08, 0x1d, 0x36, 0x33, 0x75, 0xe0, 0x5b, 0xd0, 0xd4, 0x55, 0x78, 0xa1, 0xb8, 0x3b, - 0xbe, 0xcf, 0x62, 0x1e, 0x65, 0x49, 0xd6, 0xa1, 0xe2, 0x2b, 0x3b, 0xd3, 0x85, 0x86, 0xdd, 0x85, - 0xd6, 0xe2, 0x83, 0xe7, 0x24, 0xbf, 0xad, 0x6b, 0x3a, 0x43, 0x77, 0xae, 0xe6, 0x65, 0x15, 0x9c, - 0xe5, 0x2b, 0x54, 0xaa, 0xb9, 0x26, 0x46, 0x76, 0x51, 0xe8, 0x60, 0x90, 0x71, 0x6d, 0xc1, 0x8a, - 0x60, 0xb1, 0xcf, 0x32, 0x12, 0x6d, 0xcd, 0x6b, 0x58, 0x2a, 0xe8, 0x6b, 0x1d, 0x2a, 0x61, 0x3c, - 0x1c, 0xc9, 0xc6, 0x72, 0xca, 0x86, 0x06, 0xb9, 0x9d, 0x75, 0xb1, 0xac, 0xbc, 0x5d, 0xfb, 0xe4, - 0x59, 0xb3, 0xf4, 0xc7, 0xb3, 0xe6, 0x4b, 0x7d, 0x2e, 0x22, 0x2e, 0x84, 0x7f, 0xe8, 0x84, 0xdc, - 0x8d, 0xa8, 0x3c, 0x70, 0xde, 0x8d, 0xe5, 0x93, 0x7f, 0x7e, 0xd9, 0x31, 0x74, 0xa7, 0xc9, 0x5d, - 0xb8, 0xa0, 0x82, 0xb3, 0x1e, 0x1f, 0xe2, 0xe5, 0x6f, 0x54, 0x5a, 0x46, 0xbb, 0xd6, 0xb9, 0xec, - 0xcc, 0x3e, 0x2a, 0xe7, 0x13, 0x05, 0xfa, 0x30, 0xc5, 0x78, 0xeb, 0x72, 0xca, 0xb2, 0x7f, 0x30, - 0x60, 0x7d, 0x7a, 0x9b, 0x34, 0xa1, 0xf6, 0x79, 0x28, 0x0f, 0x7a, 0x11, 0x8b, 0x78, 0x32, 0xc6, - 0x2c, 0xab, 0x1e, 0x28, 0xd7, 0x07, 0xe8, 0x21, 0x2f, 0x03, 0x5a, 0x3d, 0x21, 0x69, 0xff, 0x10, - 0xd3, 0xac, 0x7a, 0x6b, 0xca, 0xf3, 0x50, 0x39, 0xc8, 0x15, 0x58, 0xd7, 0xdb, 0x3c, 0xa1, 0x01, - 0xc3, 0x54, 0xab, 0x5e, 0x2d, 0x05, 0xa0, 0x8b, 0xb4, 0x61, 0x03, 0x21, 0x09, 0x93, 0xa3, 0x24, - 0xee, 0xf9, 0x54, 0x52, 0xcc, 0xbd, 0xea, 0x5d, 0x54, 0x7e, 0x0f, 0xdd, 0xf7, 0xa9, 0xa4, 0xf6, - 0xaf, 0x46, 0xf6, 0xe4, 0xb0, 0x05, 0xba, 0x69, 0x26, 0x54, 0x13, 0xbd, 0xd6, 0x5d, 0x78, 0x6e, - 0x93, 0x6d, 0xa8, 0x8e, 0x04, 0xf3, 0x7b, 0x01, 0x15, 0xa8, 0xad, 0xec, 0xad, 0x2a, 0xfb, 0x1d, - 0x2a, 0x48, 0x07, 0xca, 0x03, 0x1e, 0x88, 0xc6, 0x72, 0x6b, 0xb9, 0x5d, 0xeb, 0x6c, 0xe6, 0x8b, - 0xf4, 0x80, 0x07, 0xdd, 0x35, 0x55, 0xfb, 0xb4, 0xc4, 0x88, 0x55, 0xd9, 0xe8, 0x0a, 0x8f, 0xa4, - 0x6a, 0x1c, 0xb6, 0xc8, 0xab, 0xa5, 0x25, 0x44, 0x97, 0x6a, 0x2a, 0x4b, 0x12, 0x9e, 0x60, 0xf1, - 0xd7, 0xbc, 0xd4, 0xb0, 0xeb, 0xfa, 0xba, 0x7d, 0x44, 0x13, 0x1a, 0x89, 0xec, 0xe1, 0xbd, 0x0f, - 0x9b, 0x33, 0x5e, 0x2d, 0xfa, 0x26, 0xac, 0x0c, 0xd1, 0x83, 0xe9, 0xd4, 0x3a, 0x5b, 0x79, 0x6d, - 0x29, 0xbe, 0x5b, 0x56, 0xf2, 0x3c, 0x8d, 0xed, 0xfc, 0xbc, 0x0a, 0x15, 0x8c, 0x46, 0xbe, 0x84, - 0xb2, 0x9a, 0x49, 0xa4, 0x95, 0x3f, 0x97, 0x9f, 0x73, 0xe6, 0x95, 0x33, 0x10, 0xa9, 0x18, 0x7b, - 0xf7, 0xeb, 0xdf, 0xfe, 0xfe, 0x6e, 0xe9, 0x1a, 0x79, 0xd5, 0xcd, 0xcd, 0x50, 0x35, 0xda, 0x84, - 0xfb, 0x68, 0xe6, 0x9a, 0x3f, 0x26, 0xdf, 0x18, 0x50, 0xc1, 0xa9, 0x44, 0x8a, 0x63, 0x4f, 0x4f, - 0x3f, 0xd3, 0x3e, 0x0b, 0xa2, 0xf9, 0x6f, 0x22, 0xbf, 0x43, 0x5e, 0xcf, 0xf3, 0x0b, 0x05, 0x9b, - 0x13, 0xe0, 0x3e, 0x3a, 0x64, 0xe3, 0xc7, 0xe4, 0x7b, 0x03, 0xd6, 0xa7, 0xc7, 0x19, 0x69, 0x17, - 0x52, 0x15, 0x4c, 0x43, 0xf3, 0xfa, 0x39, 0x90, 0x5a, 0x9b, 0x8b, 0xda, 0xae, 0x93, 0x6b, 0xf3, - 0xb5, 0x49, 0x35, 0x09, 0x97, 0x25, 0xfd, 0xce, 0x5e, 0xef, 0x33, 0xad, 0xe2, 0x27, 0x03, 0x36, - 0x0b, 0xe6, 0x1d, 0x71, 0x17, 0xf4, 0x61, 0xd1, 0x48, 0x35, 0xf7, 0xce, 0x7f, 0x40, 0x6b, 0xdd, - 0x41, 0xad, 0xaf, 0x10, 0x7b, 0xb1, 0xd6, 0xfd, 0x71, 0x0f, 0x07, 0x1e, 0xf9, 0x0a, 0x2a, 0xa9, - 0xae, 0xe2, 0x1e, 0xce, 0x28, 0xb1, 0xcf, 0x82, 0x68, 0x6e, 0x07, 0xb9, 0xdb, 0xe4, 0xb5, 0x3c, - 0x37, 0xd2, 0xcd, 0x5f, 0xa2, 0x01, 0x94, 0xd5, 0x0b, 0x5f, 0x74, 0x81, 0x5f, 0xcc, 0xdf, 0x45, - 0x17, 0x78, 0x6a, 0x3c, 0xd8, 0x4d, 0x24, 0xdf, 0xbe, 0x63, 0xec, 0xd8, 0xf5, 0xb9, 0xdc, 0x15, - 0xcb, 0x11, 0xac, 0xa4, 0x0f, 0x8a, 0x14, 0xe7, 0x32, 0xf3, 0x66, 0xcd, 0xab, 0x67, 0x62, 0x34, - 0xa7, 0x85, 0x9c, 0x0d, 0xb2, 0x95, 0x27, 0x4c, 0xdf, 0x6a, 0xf7, 0xc1, 0xc9, 0x5f, 0x56, 0xe9, - 0xc9, 0xc4, 0x2a, 0x9d, 0x4c, 0x2c, 0xe3, 0xe9, 0xc4, 0x32, 0xfe, 0x9c, 0x58, 0xc6, 0xb7, 0xa7, - 0x56, 0xe9, 0xe9, 0xa9, 0x55, 0xfa, 0xfd, 0xd4, 0x2a, 0x7d, 0xba, 0x13, 0x84, 0xf2, 0x60, 0xb4, - 0xef, 0xf4, 0x79, 0xe4, 0x86, 0x71, 0x28, 0x43, 0xba, 0x3b, 0xa0, 0xfb, 0xe2, 0x79, 0xbc, 0x2f, - 0x30, 0x22, 0x7e, 0xc7, 0xec, 0xaf, 0xe0, 0x87, 0xcc, 0x1b, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, - 0xec, 0xe7, 0xcf, 0xd0, 0x59, 0x09, 0x00, 0x00, + 0x14, 0xf6, 0x26, 0x76, 0xea, 0x3c, 0xbb, 0x55, 0x3a, 0x31, 0x91, 0xb3, 0x2a, 0xb6, 0xbb, 0x05, + 0xea, 0x46, 0xc4, 0x9b, 0x9a, 0x4a, 0xad, 0xca, 0xa9, 0x6e, 0x01, 0x01, 0x45, 0xc0, 0x16, 0x09, + 0x89, 0x8b, 0x35, 0xf1, 0x0e, 0xce, 0x2a, 0xde, 0x9d, 0xcd, 0xce, 0x38, 0x60, 0xaa, 0x72, 0x40, + 0xfc, 0x00, 0x24, 0xb8, 0x71, 0xe1, 0xc0, 0xa1, 0x47, 0x6e, 0x5c, 0x39, 0xe6, 0x58, 0x89, 0x0b, + 0xe2, 0x50, 0x81, 0x83, 0x04, 0x3f, 0x03, 0xcd, 0xdb, 0xd9, 0xd4, 0x5e, 0xaf, 0x2d, 0xe7, 0xe0, + 0x68, 0xde, 0x9b, 0x37, 0xef, 0xfb, 0xde, 0x9b, 0x37, 0x5f, 0x16, 0x4c, 0xdf, 0x0b, 0x3c, 0x76, + 0xec, 0xdb, 0xea, 0x77, 0x7c, 0xd3, 0x3e, 0x1a, 0xb2, 0x68, 0xd4, 0x0a, 0x23, 0x2e, 0x39, 0xb9, + 0xa4, 0xf7, 0x5a, 0xea, 0x77, 0x7c, 0xd3, 0xbc, 0x4c, 0x7d, 0x2f, 0xe0, 0x36, 0xfe, 0x8d, 0x43, + 0xcc, 0x4a, 0x9f, 0xf7, 0x39, 0x2e, 0x6d, 0xb5, 0xd2, 0xde, 0x2b, 0x7d, 0xce, 0xfb, 0x03, 0x66, + 0xd3, 0xd0, 0xb3, 0x69, 0x10, 0x70, 0x49, 0xa5, 0xc7, 0x03, 0xa1, 0x77, 0xd3, 0x90, 0x72, 0x14, + 0x32, 0xbd, 0x67, 0xdd, 0x86, 0x8d, 0x8f, 0x15, 0x83, 0xfb, 0xdc, 0x65, 0x0e, 0x3b, 0x1a, 0x32, + 0x21, 0xc9, 0x35, 0xb8, 0xd8, 0xe3, 0x81, 0x8c, 0x68, 0x4f, 0x76, 0xa9, 0xeb, 0x46, 0x55, 0xa3, + 0x61, 0x34, 0xd7, 0x9d, 0x72, 0xe2, 0xbc, 0xe7, 0xba, 0x91, 0xb5, 0x0b, 0x97, 0x27, 0x0e, 0x8a, + 0x90, 0x07, 0x82, 0x11, 0x02, 0xf9, 0x1e, 0x77, 0x99, 0x3e, 0x80, 0xeb, 0xbb, 0xf9, 0xff, 0x7e, + 0xaa, 0x1b, 0xd6, 0x7b, 0x3a, 0xfc, 0x91, 0xa4, 0xf2, 0x5c, 0x40, 0x64, 0x03, 0x56, 0x0f, 0xd9, + 0xa8, 0xba, 0x82, 0x5b, 0x6a, 0x69, 0xed, 0x01, 0x99, 0xcc, 0xa5, 0xb1, 0x2b, 0x50, 0x38, 0xa6, + 0x83, 0x61, 0x02, 0x1e, 0x1b, 0x1a, 0xdd, 0x84, 0x2a, 0x9e, 0x78, 0xcb, 0xb9, 0xdf, 0xde, 0x7b, + 0x9b, 0xf6, 0x24, 0x8f, 0x46, 0x9a, 0x84, 0xf5, 0x26, 0x6c, 0x67, 0xec, 0xe9, 0xa4, 0x55, 0xb8, + 0xa0, 0x88, 0x31, 0x21, 0x74, 0xda, 0xc4, 0xcc, 0x4a, 0xfc, 0x69, 0x44, 0xc3, 0x90, 0x45, 0x99, + 0x89, 0xcf, 0xf6, 0x96, 0x4c, 0x7c, 0x1b, 0xea, 0xba, 0xbd, 0x2f, 0x5a, 0xd1, 0x19, 0x3d, 0x60, + 0x01, 0xf7, 0x93, 0xee, 0x55, 0xa0, 0xe0, 0x2a, 0x3b, 0x29, 0x18, 0x0d, 0xab, 0x03, 0x8d, 0xf9, + 0x07, 0x97, 0x04, 0xbf, 0xa3, 0x2f, 0x6b, 0x0a, 0x6e, 0xa9, 0xa9, 0x48, 0xae, 0x66, 0x1a, 0x2f, + 0x93, 0xa9, 0xc6, 0x1a, 0x1b, 0xc9, 0x04, 0xd2, 0xc1, 0x20, 0xc1, 0xda, 0x82, 0x35, 0xc1, 0x02, + 0x97, 0x25, 0x20, 0xda, 0x9a, 0xe5, 0xb0, 0x92, 0x31, 0x30, 0x15, 0x28, 0x78, 0x41, 0x38, 0x94, + 0xd5, 0xd5, 0x18, 0x0d, 0x0d, 0x72, 0x27, 0x19, 0x8f, 0xbc, 0xf2, 0x76, 0xac, 0x93, 0xe7, 0xf5, + 0xdc, 0x9f, 0xcf, 0xeb, 0x2f, 0xf5, 0xb8, 0xf0, 0xb9, 0x10, 0xee, 0x61, 0xcb, 0xe3, 0xb6, 0x4f, + 0xe5, 0x41, 0xeb, 0xdd, 0x40, 0x3e, 0xfd, 0xf7, 0x97, 0x1d, 0x43, 0x8f, 0x10, 0xb9, 0x07, 0x17, + 0x55, 0x72, 0xd6, 0xe5, 0x21, 0xbe, 0xaa, 0x6a, 0xa1, 0x61, 0x34, 0x4b, 0xed, 0x2b, 0xad, 0xe9, + 0xd7, 0xda, 0xfa, 0x44, 0x05, 0x7d, 0x18, 0xc7, 0x38, 0x65, 0x39, 0x61, 0x59, 0x3f, 0x1a, 0x50, + 0x9e, 0xdc, 0x26, 0x75, 0x28, 0x7d, 0xe1, 0xc9, 0x83, 0xae, 0xcf, 0x7c, 0x1e, 0x8d, 0xb0, 0xca, + 0xa2, 0x03, 0xca, 0xf5, 0x01, 0x7a, 0xc8, 0xcb, 0x80, 0x56, 0x57, 0x48, 0xda, 0x3b, 0xc4, 0x32, + 0x8b, 0xce, 0xba, 0xf2, 0x3c, 0x52, 0x0e, 0x72, 0x15, 0xca, 0x7a, 0x9b, 0x47, 0xb4, 0xcf, 0xb0, + 0xd4, 0xa2, 0x53, 0x8a, 0x03, 0xd0, 0x45, 0x9a, 0xb0, 0x81, 0x21, 0x11, 0x93, 0xc3, 0x28, 0xe8, + 0xba, 0x54, 0x52, 0xac, 0xbd, 0xe8, 0x5c, 0x52, 0x7e, 0x07, 0xdd, 0x0f, 0xa8, 0xa4, 0xd6, 0xaf, + 0x46, 0xf2, 0x96, 0xf1, 0x0a, 0xf4, 0xa5, 0x99, 0x50, 0x8c, 0xf4, 0x5a, 0xdf, 0xc2, 0x99, 0x4d, + 0xb6, 0xa1, 0x38, 0x14, 0xcc, 0xed, 0xf6, 0xa9, 0x40, 0x6e, 0x79, 0xe7, 0x82, 0xb2, 0xdf, 0xa1, + 0x82, 0xb4, 0x21, 0x3f, 0xe0, 0x7d, 0x51, 0x5d, 0x6d, 0xac, 0x36, 0x4b, 0xed, 0xcd, 0x74, 0x93, + 0x1e, 0xf2, 0x7e, 0x67, 0x5d, 0xf5, 0x3e, 0x6e, 0x31, 0xc6, 0xaa, 0x6a, 0x74, 0x87, 0x87, 0x52, + 0x5d, 0x1c, 0x5e, 0x91, 0x53, 0x8a, 0x5b, 0x88, 0x2e, 0x75, 0xa9, 0x2c, 0x8a, 0x78, 0x84, 0xcd, + 0x5f, 0x77, 0x62, 0xc3, 0xaa, 0xe8, 0x71, 0xfb, 0x88, 0x46, 0xd4, 0x17, 0xc9, 0xc3, 0x7b, 0x1f, + 0x36, 0xa7, 0xbc, 0x9a, 0xf4, 0x2d, 0x58, 0x0b, 0xd1, 0x83, 0xe5, 0x94, 0xda, 0x5b, 0x69, 0x6e, + 0x71, 0x7c, 0x27, 0xaf, 0xe8, 0x39, 0x3a, 0xb6, 0xfd, 0x5b, 0x11, 0x0a, 0x98, 0x8d, 0x7c, 0x05, + 0x79, 0x25, 0x76, 0xa4, 0x91, 0x3e, 0x97, 0x16, 0x50, 0xf3, 0xea, 0x82, 0x88, 0x98, 0x8c, 0xb5, + 0xfb, 0xcd, 0xef, 0xff, 0x7c, 0xbf, 0x72, 0x9d, 0xbc, 0x6a, 0xa7, 0xc4, 0x59, 0x69, 0xa6, 0xb0, + 0x1f, 0x4f, 0x8d, 0xf9, 0x13, 0xf2, 0xad, 0x01, 0x05, 0x94, 0x3b, 0x92, 0x9d, 0x7b, 0x52, 0x56, + 0x4d, 0x6b, 0x51, 0x88, 0xc6, 0xbf, 0x85, 0xf8, 0x2d, 0xf2, 0x7a, 0x1a, 0x5f, 0xa8, 0xb0, 0x19, + 0x02, 0xf6, 0xe3, 0x43, 0x36, 0x7a, 0x42, 0x7e, 0x30, 0xa0, 0x3c, 0xa9, 0x93, 0xa4, 0x99, 0x09, + 0x95, 0x21, 0xb3, 0xe6, 0x8d, 0x25, 0x22, 0x35, 0x37, 0x1b, 0xb9, 0xdd, 0x20, 0xd7, 0x67, 0x7b, + 0x13, 0x73, 0x12, 0x36, 0x8b, 0x7a, 0xed, 0xbd, 0xee, 0xe7, 0x9a, 0xc5, 0x19, 0x2d, 0xad, 0xb2, + 0x8b, 0x68, 0x4d, 0x8b, 0xf4, 0x22, 0x5a, 0x29, 0xc9, 0x3e, 0x3f, 0xad, 0x9f, 0x0d, 0xd8, 0xcc, + 0x90, 0x61, 0x62, 0xcf, 0x19, 0x8f, 0x79, 0x4a, 0x6f, 0xee, 0x2d, 0x7f, 0x40, 0x73, 0xdd, 0x41, + 0xae, 0xaf, 0x10, 0x6b, 0x3e, 0xd7, 0xfd, 0x51, 0x17, 0x75, 0x98, 0x7c, 0x0d, 0x85, 0x98, 0x57, + 0xf6, 0x68, 0x4d, 0x31, 0xb1, 0x16, 0x85, 0x68, 0xec, 0x16, 0x62, 0x37, 0xc9, 0x6b, 0x69, 0x6c, + 0x84, 0x9b, 0x9d, 0xed, 0x01, 0xe4, 0x95, 0xf0, 0xcc, 0x7b, 0x57, 0x2f, 0xfe, 0x2d, 0xcc, 0x7b, + 0x57, 0x13, 0xaa, 0x65, 0xd5, 0x11, 0x7c, 0xfb, 0xae, 0xb1, 0x63, 0x55, 0x66, 0x6a, 0x57, 0x28, + 0x47, 0xb0, 0x16, 0xbf, 0x73, 0x92, 0x5d, 0xcb, 0x94, 0x94, 0x98, 0xd7, 0x16, 0xc6, 0x68, 0xcc, + 0x1a, 0x62, 0x56, 0xc9, 0x56, 0x1a, 0x30, 0x96, 0x90, 0xce, 0xc3, 0x93, 0xbf, 0x6b, 0xb9, 0xa7, + 0xe3, 0x5a, 0xee, 0x64, 0x5c, 0x33, 0x9e, 0x8d, 0x6b, 0xc6, 0x5f, 0xe3, 0x9a, 0xf1, 0xdd, 0x69, + 0x2d, 0xf7, 0xec, 0xb4, 0x96, 0xfb, 0xe3, 0xb4, 0x96, 0xfb, 0x6c, 0xa7, 0xef, 0xc9, 0x83, 0xe1, + 0x7e, 0xab, 0xc7, 0x7d, 0xdb, 0x0b, 0x3c, 0xe9, 0xd1, 0xdd, 0x01, 0xdd, 0x17, 0x67, 0xf9, 0xbe, + 0xc4, 0x8c, 0xf8, 0xdd, 0xb6, 0xbf, 0x86, 0x1f, 0x6e, 0x6f, 0xfc, 0x1f, 0x00, 0x00, 0xff, 0xff, + 0xab, 0x3a, 0x89, 0x56, 0x49, 0x0a, 0x00, 0x00, } func (this *QueryCodeResponse) Equal(that interface{}) bool { @@ -799,6 +881,30 @@ func (this *QueryERC20FactoryResponse) Equal(that interface{}) bool { } return true } +func (this *QueryERC20WrapperResponse) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*QueryERC20WrapperResponse) + if !ok { + that2, ok := that.(QueryERC20WrapperResponse) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Address != that1.Address { + return false + } + return true +} func (this *QueryContractAddrByDenomResponse) Equal(that interface{}) bool { if that == nil { return this == nil @@ -866,6 +972,8 @@ type QueryClient interface { State(ctx context.Context, in *QueryStateRequest, opts ...grpc.CallOption) (*QueryStateResponse, error) // ERC20Factory gets the ERC20Factory contract address. ERC20Factory(ctx context.Context, in *QueryERC20FactoryRequest, opts ...grpc.CallOption) (*QueryERC20FactoryResponse, error) + // ERC20Wrapper gets the ERC20Wrapper contract address. + ERC20Wrapper(ctx context.Context, in *QueryERC20WrapperRequest, opts ...grpc.CallOption) (*QueryERC20WrapperResponse, error) // ContractAddrByDenom gets the contract address by denom. ContractAddrByDenom(ctx context.Context, in *QueryContractAddrByDenomRequest, opts ...grpc.CallOption) (*QueryContractAddrByDenomResponse, error) // Denom gets the denom of the given contract address. @@ -911,6 +1019,15 @@ func (c *queryClient) ERC20Factory(ctx context.Context, in *QueryERC20FactoryReq return out, nil } +func (c *queryClient) ERC20Wrapper(ctx context.Context, in *QueryERC20WrapperRequest, opts ...grpc.CallOption) (*QueryERC20WrapperResponse, error) { + out := new(QueryERC20WrapperResponse) + err := c.cc.Invoke(ctx, "/minievm.evm.v1.Query/ERC20Wrapper", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *queryClient) ContractAddrByDenom(ctx context.Context, in *QueryContractAddrByDenomRequest, opts ...grpc.CallOption) (*QueryContractAddrByDenomResponse, error) { out := new(QueryContractAddrByDenomResponse) err := c.cc.Invoke(ctx, "/minievm.evm.v1.Query/ContractAddrByDenom", in, out, opts...) @@ -955,6 +1072,8 @@ type QueryServer interface { State(context.Context, *QueryStateRequest) (*QueryStateResponse, error) // ERC20Factory gets the ERC20Factory contract address. ERC20Factory(context.Context, *QueryERC20FactoryRequest) (*QueryERC20FactoryResponse, error) + // ERC20Wrapper gets the ERC20Wrapper contract address. + ERC20Wrapper(context.Context, *QueryERC20WrapperRequest) (*QueryERC20WrapperResponse, error) // ContractAddrByDenom gets the contract address by denom. ContractAddrByDenom(context.Context, *QueryContractAddrByDenomRequest) (*QueryContractAddrByDenomResponse, error) // Denom gets the denom of the given contract address. @@ -978,6 +1097,9 @@ func (*UnimplementedQueryServer) State(ctx context.Context, req *QueryStateReque func (*UnimplementedQueryServer) ERC20Factory(ctx context.Context, req *QueryERC20FactoryRequest) (*QueryERC20FactoryResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ERC20Factory not implemented") } +func (*UnimplementedQueryServer) ERC20Wrapper(ctx context.Context, req *QueryERC20WrapperRequest) (*QueryERC20WrapperResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ERC20Wrapper not implemented") +} func (*UnimplementedQueryServer) ContractAddrByDenom(ctx context.Context, req *QueryContractAddrByDenomRequest) (*QueryContractAddrByDenomResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ContractAddrByDenom not implemented") } @@ -1049,6 +1171,24 @@ func _Query_ERC20Factory_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _Query_ERC20Wrapper_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryERC20WrapperRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ERC20Wrapper(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/minievm.evm.v1.Query/ERC20Wrapper", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ERC20Wrapper(ctx, req.(*QueryERC20WrapperRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Query_ContractAddrByDenom_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryContractAddrByDenomRequest) if err := dec(in); err != nil { @@ -1137,6 +1277,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "ERC20Factory", Handler: _Query_ERC20Factory_Handler, }, + { + MethodName: "ERC20Wrapper", + Handler: _Query_ERC20Wrapper_Handler, + }, { MethodName: "ContractAddrByDenom", Handler: _Query_ContractAddrByDenom_Handler, @@ -1338,6 +1482,59 @@ func (m *QueryERC20FactoryResponse) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } +func (m *QueryERC20WrapperRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryERC20WrapperRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryERC20WrapperRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryERC20WrapperResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryERC20WrapperResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryERC20WrapperResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *QueryContractAddrByDenomRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1795,6 +1992,28 @@ func (m *QueryERC20FactoryResponse) Size() (n int) { return n } +func (m *QueryERC20WrapperRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryERC20WrapperResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func (m *QueryContractAddrByDenomRequest) Size() (n int) { if m == nil { return 0 @@ -2443,6 +2662,138 @@ func (m *QueryERC20FactoryResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryERC20WrapperRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryERC20WrapperRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryERC20WrapperRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryERC20WrapperResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryERC20WrapperResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryERC20WrapperResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *QueryContractAddrByDenomRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/evm/types/query.pb.gw.go b/x/evm/types/query.pb.gw.go index f8c3ed58..a815939f 100644 --- a/x/evm/types/query.pb.gw.go +++ b/x/evm/types/query.pb.gw.go @@ -181,6 +181,24 @@ func local_request_Query_ERC20Factory_0(ctx context.Context, marshaler runtime.M } +func request_Query_ERC20Wrapper_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryERC20WrapperRequest + var metadata runtime.ServerMetadata + + msg, err := client.ERC20Wrapper(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ERC20Wrapper_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryERC20WrapperRequest + var metadata runtime.ServerMetadata + + msg, err := server.ERC20Wrapper(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_Query_ContractAddrByDenom_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} ) @@ -398,6 +416,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_ERC20Wrapper_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_ERC20Wrapper_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ERC20Wrapper_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_ContractAddrByDenom_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -591,6 +632,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_ERC20Wrapper_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_ERC20Wrapper_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ERC20Wrapper_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_ContractAddrByDenom_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -681,6 +742,8 @@ var ( pattern_Query_ERC20Factory_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"minievm", "evm", "v1", "contracts", "erc20_factory"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_ERC20Wrapper_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"minievm", "evm", "v1", "contracts", "erc20_factory"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_ContractAddrByDenom_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"minievm", "evm", "v1", "contracts", "by_denom"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_Denom_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"minievm", "evm", "v1", "denoms", "contract_addr"}, "", runtime.AssumeColonVerbOpt(false))) @@ -697,6 +760,8 @@ var ( forward_Query_ERC20Factory_0 = runtime.ForwardResponseMessage + forward_Query_ERC20Wrapper_0 = runtime.ForwardResponseMessage + forward_Query_ContractAddrByDenom_0 = runtime.ForwardResponseMessage forward_Query_Denom_0 = runtime.ForwardResponseMessage From bf4624c53d4e61d6114002579045fee0101fb567 Mon Sep 17 00:00:00 2001 From: suha jin <89185836+djm07073@users.noreply.github.com> Date: Sat, 19 Oct 2024 01:41:40 +0900 Subject: [PATCH 2/6] fix: proto generation --- x/evm/contracts/erc20_wrapper/ERC20Wrapper.go | 2 +- x/evm/types/genesis.pb.go | 86 +++++++++---------- x/evm/types/query.pb.go | 78 ++++++++--------- x/evm/types/query.pb.gw.go | 2 +- 4 files changed, 84 insertions(+), 84 deletions(-) diff --git a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go index 8d78de01..1f95d43a 100644 --- a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go +++ b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go @@ -32,7 +32,7 @@ var ( // Erc20WrapperMetaData contains all meta data concerning the Erc20Wrapper contract. var Erc20WrapperMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"StringsInsufficientHexLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"erc20\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"ERC20Created\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"name\":\"createERC20\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"ibc_ack\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"}],\"name\":\"ibc_timeout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"originTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"wrappedTokenDenom\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wrappedAmt\",\"type\":\"uint256\"}],\"name\":\"unwrap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"channel\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"receiver\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"wrap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"wrappedTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60806040525f8060146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055503480156036575f80fd5b50335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550614a7f806100835f395ff3fe608060405234801561000f575f80fd5b506004361061009c575f3560e01c80639a111432116100645780639a11143214610156578063b5ad1fb614610172578063d5c6b504146101a2578063f2fde38b146101d2578063fc078758146101ee5761009c565b806301ffc9a7146100a057806306ef1a86146100d05780630d4f1f9d1461010057806331a503f01461011c5780638da5cb5b14610138575b5f80fd5b6100ba60048036038101906100b59190611ba1565b61020a565b6040516100c79190611be6565b60405180910390f35b6100ea60048036038101906100e59190611d71565b610273565b6040516100f79190611e38565b60405180910390f35b61011a60048036038101906101159190611eb8565b6103f2565b005b61013660048036038101906101319190611ef6565b610405565b005b610140610411565b60405161014d9190611e38565b60405180910390f35b610170600480360381019061016b9190611f7e565b610434565b005b61018c6004803603810190610187919061202d565b610730565b6040516101999190611e38565b60405180910390f35b6101bc60048036038101906101b7919061202d565b610760565b6040516101c99190611e38565b60405180910390f35b6101ec60048036038101906101e7919061202d565b610790565b005b61020860048036038101906102039190612058565b6108d8565b005b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f8084848460405161028490611b2e565b61029093929190612133565b604051809103905ff0801580156102a9573d5f803e3d5ffd5b50905060f273ffffffffffffffffffffffffffffffffffffffff1663d126274a826040518263ffffffff1660e01b81526004016102e69190611e38565b6020604051808303815f875af1158015610302573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610326919061218a565b508073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b336040518263ffffffff1660e01b81526004016103609190611e38565b5f604051808303815f87803b158015610377575f80fd5b505af1158015610389573d5f803e3d5ffd5b505050503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d160405160405180910390a3809150509392505050565b806104015761040082610c51565b5b5050565b61040e81610c51565b50565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61043d84610d8c565b8373ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161047a939291906121c4565b6020604051808303815f875af1158015610496573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104ba919061218a565b505f610534838673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610509573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061052d919061220d565b60066110af565b905060015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1930836040518363ffffffff1660e01b81526004016105cd929190612238565b5f604051808303815f87803b1580156105e4575f80fd5b505af11580156105f6573d5f803e3d5ffd5b5050505060015f60148282829054906101000a900467ffffffffffffffff1661061f919061228c565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e66106cb8860015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685878a61117e565b6040518263ffffffff1660e01b81526004016106e791906122c7565b6020604051808303815f875af1158015610703573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610727919061218a565b50505050505050565b6002602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6001602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107e6575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361081d575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60f173ffffffffffffffffffffffffffffffffffffffff16632b3324ce856040518263ffffffff1660e01b815260040161091391906122c7565b6020604051808303815f875af115801561092f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061095391906122fb565b90505f73ffffffffffffffffffffffffffffffffffffffff1660025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610a1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1690612370565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166379cc679033846040518363ffffffff1660e01b8152600401610a5a929190612238565b6020604051808303815f875af1158015610a76573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a9a919061218a565b505f610b7083600660025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b6b919061220d565b6110af565b905060025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85836040518363ffffffff1660e01b8152600401610c09929190612238565b6020604051808303815f875af1158015610c25573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c49919061218a565b505050505050565b5f60035f8367ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f206040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182018054610ce6906123bb565b80601f0160208091040260200160405190810160405280929190818152602001828054610d12906123bb565b8015610d5d5780601f10610d3457610100808354040283529160200191610d5d565b820191905f5260205f20905b815481529060010190602001808311610d4057829003601f168201915b505050505081526020016002820154815250509050610d888160200151825f015183604001516108d8565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff1660015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036110ac575f610fb26040518060400160405280600781526020017f57726170706564000000000000000000000000000000000000000000000000008152508373ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa158015610e9d573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610ec59190612459565b604051602001610ed69291906124da565b6040516020818303038152906040526040518060400160405280600181526020017f57000000000000000000000000000000000000000000000000000000000000008152508473ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015610f63573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610f8b9190612459565b604051602001610f9c9291906124da565b604051602081830303815290604052600661158f565b90508060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505b50565b5f8160ff168360ff1611156110f0575f82846110cb91906124fd565b60ff16600a6110da9190612660565b905080856110e891906126d7565b915050611135565b8160ff168360ff161015611130575f838361110b91906124fd565b60ff16600a61111a9190612660565b905080856111289190612707565b915050611134565b8390505b5b5f8103611177576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116e90612792565b60405180910390fd5b9392505050565b6060806060805f6040518060a00160405280606381526020016149e76063913990505f6040518060400160405280601781526020017f222c22746f6b656e223a207b202264656e6f6d223a202200000000000000000081525090505f6040518060400160405280600d81526020017f222c22616d6f756e74223a2022000000000000000000000000000000000000008152509050828c8360f173ffffffffffffffffffffffffffffffffffffffff166381cf0f6a8f6040518263ffffffff1660e01b815260040161124f9190611e38565b5f604051808303815f875af115801561126a573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906112929190612459565b846040516020016112a79594939291906127b0565b60405160208183030381529060405295505050505f6040518060400160405280600d81526020017f222c2273656e646572223a20220000000000000000000000000000000000000081525090505f6040518060400160405280600f81526020017f222c227265636569766572223a2022000000000000000000000000000000000081525090505f6040518060800160405280605a815260200161498d605a913990505f6040518060400160405280600c81526020017f222c226d656d6f223a202222000000000000000000000000000000000000000081525090505f61138c8c6116a8565b90505f6113988c6116a8565b9050818660f173ffffffffffffffffffffffffffffffffffffffff16636af32a55306040518263ffffffff1660e01b81526004016113d69190611e38565b5f604051808303815f875af11580156113f1573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906114199190612459565b878e8886896040516020016114359897969594939291906127fa565b60405160208183030381529060405297505050505050505f6040518060400160405280601b81526020017f2c226173796e635f63616c6c6261636b223a207b226964223a2022000000000081525090505f6040518060400160405280601781526020017f222c22636f6e74726163745f61646472657373223a202200000000000000000081525090505f6040518060400160405280600381526020017f227d7d000000000000000000000000000000000000000000000000000000000081525090505f6115205f60149054906101000a900467ffffffffffffffff1667ffffffffffffffff166116a8565b90505f61152c30611772565b905084828583866040516020016115479594939291906127b0565b604051602081830303815290604052955050505050508282826040516020016115729392919061286b565b604051602081830303815290604052935050505095945050505050565b5f808484846040516115a090611b2e565b6115ac93929190612133565b604051809103905ff0801580156115c5573d5f803e3d5ffd5b50905060f273ffffffffffffffffffffffffffffffffffffffff1663d126274a826040518263ffffffff1660e01b81526004016116029190611e38565b6020604051808303815f875af115801561161e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611642919061218a565b503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d160405160405180910390a3809150509392505050565b60605f60016116b68461179f565b0190505f8167ffffffffffffffff8111156116d4576116d3611c17565b5b6040519080825280601f01601f1916602001820160405280156117065781602001600182028036833780820191505090505b5090505f82602001820190505b600115611767578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161175c5761175b6126aa565b5b0494505f8503611713575b819350505050919050565b60606117988273ffffffffffffffffffffffffffffffffffffffff16601460ff166118f0565b9050919050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106117fb577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816117f1576117f06126aa565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611838576d04ee2d6d415b85acef8100000000838161182e5761182d6126aa565b5b0492506020810190505b662386f26fc10000831061186757662386f26fc10000838161185d5761185c6126aa565b5b0492506010810190505b6305f5e1008310611890576305f5e1008381611886576118856126aa565b5b0492506008810190505b61271083106118b55761271083816118ab576118aa6126aa565b5b0492506004810190505b606483106118d857606483816118ce576118cd6126aa565b5b0492506002810190505b600a83106118e7576001810190505b80915050919050565b60605f8390505f60028460026119069190612707565b611910919061289b565b67ffffffffffffffff81111561192957611928611c17565b5b6040519080825280601f01601f19166020018201604052801561195b5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f81518110611992576119916128ce565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106119f5576119f46128ce565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f6001856002611a339190612707565b611a3d919061289b565b90505b6001811115611adc577f3031323334353637383961626364656600000000000000000000000000000000600f841660108110611a7f57611a7e6128ce565b5b1a60f81b828281518110611a9657611a956128ce565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600483901c925080611ad5906128fb565b9050611a40565b505f8214611b235784846040517fe22e27eb000000000000000000000000000000000000000000000000000000008152600401611b1a929190612922565b60405180910390fd5b809250505092915050565b6120438061294a83390190565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611b8081611b4c565b8114611b8a575f80fd5b50565b5f81359050611b9b81611b77565b92915050565b5f60208284031215611bb657611bb5611b44565b5b5f611bc384828501611b8d565b91505092915050565b5f8115159050919050565b611be081611bcc565b82525050565b5f602082019050611bf95f830184611bd7565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611c4d82611c07565b810181811067ffffffffffffffff82111715611c6c57611c6b611c17565b5b80604052505050565b5f611c7e611b3b565b9050611c8a8282611c44565b919050565b5f67ffffffffffffffff821115611ca957611ca8611c17565b5b611cb282611c07565b9050602081019050919050565b828183375f83830152505050565b5f611cdf611cda84611c8f565b611c75565b905082815260208101848484011115611cfb57611cfa611c03565b5b611d06848285611cbf565b509392505050565b5f82601f830112611d2257611d21611bff565b5b8135611d32848260208601611ccd565b91505092915050565b5f60ff82169050919050565b611d5081611d3b565b8114611d5a575f80fd5b50565b5f81359050611d6b81611d47565b92915050565b5f805f60608486031215611d8857611d87611b44565b5b5f84013567ffffffffffffffff811115611da557611da4611b48565b5b611db186828701611d0e565b935050602084013567ffffffffffffffff811115611dd257611dd1611b48565b5b611dde86828701611d0e565b9250506040611def86828701611d5d565b9150509250925092565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611e2282611df9565b9050919050565b611e3281611e18565b82525050565b5f602082019050611e4b5f830184611e29565b92915050565b5f67ffffffffffffffff82169050919050565b611e6d81611e51565b8114611e77575f80fd5b50565b5f81359050611e8881611e64565b92915050565b611e9781611bcc565b8114611ea1575f80fd5b50565b5f81359050611eb281611e8e565b92915050565b5f8060408385031215611ece57611ecd611b44565b5b5f611edb85828601611e7a565b9250506020611eec85828601611ea4565b9150509250929050565b5f60208284031215611f0b57611f0a611b44565b5b5f611f1884828501611e7a565b91505092915050565b611f2a81611e18565b8114611f34575f80fd5b50565b5f81359050611f4581611f21565b92915050565b5f819050919050565b611f5d81611f4b565b8114611f67575f80fd5b50565b5f81359050611f7881611f54565b92915050565b5f805f805f60a08688031215611f9757611f96611b44565b5b5f86013567ffffffffffffffff811115611fb457611fb3611b48565b5b611fc088828901611d0e565b9550506020611fd188828901611f37565b945050604086013567ffffffffffffffff811115611ff257611ff1611b48565b5b611ffe88828901611d0e565b935050606061200f88828901611f6a565b925050608061202088828901611f6a565b9150509295509295909350565b5f6020828403121561204257612041611b44565b5b5f61204f84828501611f37565b91505092915050565b5f805f6060848603121561206f5761206e611b44565b5b5f84013567ffffffffffffffff81111561208c5761208b611b48565b5b61209886828701611d0e565b93505060206120a986828701611f37565b92505060406120ba86828701611f6a565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f6120f6826120c4565b61210081856120ce565b93506121108185602086016120de565b61211981611c07565b840191505092915050565b61212d81611d3b565b82525050565b5f6060820190508181035f83015261214b81866120ec565b9050818103602083015261215f81856120ec565b905061216e6040830184612124565b949350505050565b5f8151905061218481611e8e565b92915050565b5f6020828403121561219f5761219e611b44565b5b5f6121ac84828501612176565b91505092915050565b6121be81611f4b565b82525050565b5f6060820190506121d75f830186611e29565b6121e46020830185611e29565b6121f160408301846121b5565b949350505050565b5f8151905061220781611d47565b92915050565b5f6020828403121561222257612221611b44565b5b5f61222f848285016121f9565b91505092915050565b5f60408201905061224b5f830185611e29565b61225860208301846121b5565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61229682611e51565b91506122a183611e51565b9250828201905067ffffffffffffffff8111156122c1576122c061225f565b5b92915050565b5f6020820190508181035f8301526122df81846120ec565b905092915050565b5f815190506122f581611f21565b92915050565b5f602082840312156123105761230f611b44565b5b5f61231d848285016122e7565b91505092915050565b7f6f726967696e20746f6b656e20646f65736e27742065786973740000000000005f82015250565b5f61235a601a836120ce565b915061236582612326565b602082019050919050565b5f6020820190508181035f8301526123878161234e565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806123d257607f821691505b6020821081036123e5576123e461238e565b5b50919050565b5f6123fd6123f884611c8f565b611c75565b90508281526020810184848401111561241957612418611c03565b5b6124248482856120de565b509392505050565b5f82601f8301126124405761243f611bff565b5b81516124508482602086016123eb565b91505092915050565b5f6020828403121561246e5761246d611b44565b5b5f82015167ffffffffffffffff81111561248b5761248a611b48565b5b6124978482850161242c565b91505092915050565b5f81905092915050565b5f6124b4826120c4565b6124be81856124a0565b93506124ce8185602086016120de565b80840191505092915050565b5f6124e582856124aa565b91506124f182846124aa565b91508190509392505050565b5f61250782611d3b565b915061251283611d3b565b9250828203905060ff81111561252b5761252a61225f565b5b92915050565b5f8160011c9050919050565b5f808291508390505b6001851115612586578086048111156125625761256161225f565b5b60018516156125715780820291505b808102905061257f85612531565b9450612546565b94509492505050565b5f8261259e5760019050612659565b816125ab575f9050612659565b81600181146125c157600281146125cb576125fa565b6001915050612659565b60ff8411156125dd576125dc61225f565b5b8360020a9150848211156125f4576125f361225f565b5b50612659565b5060208310610133831016604e8410600b841016171561262f5782820a90508381111561262a5761262961225f565b5b612659565b61263c848484600161253d565b925090508184048111156126535761265261225f565b5b81810290505b9392505050565b5f61266a82611f4b565b915061267583611f4b565b92506126a27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461258f565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6126e182611f4b565b91506126ec83611f4b565b9250826126fc576126fb6126aa565b5b828204905092915050565b5f61271182611f4b565b915061271c83611f4b565b925082820261272a81611f4b565b915082820484148315176127415761274061225f565b5b5092915050565b7f636f6e76657274656420616d6f756e74206973207a65726f00000000000000005f82015250565b5f61277c6018836120ce565b915061278782612748565b602082019050919050565b5f6020820190508181035f8301526127a981612770565b9050919050565b5f6127bb82886124aa565b91506127c782876124aa565b91506127d382866124aa565b91506127df82856124aa565b91506127eb82846124aa565b91508190509695505050505050565b5f612805828b6124aa565b9150612811828a6124aa565b915061281d82896124aa565b915061282982886124aa565b915061283582876124aa565b915061284182866124aa565b915061284d82856124aa565b915061285982846124aa565b91508190509998505050505050505050565b5f61287682866124aa565b915061288282856124aa565b915061288e82846124aa565b9150819050949350505050565b5f6128a582611f4b565b91506128b083611f4b565b92508282019050808211156128c8576128c761225f565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f61290582611f4b565b91505f82036129175761291661225f565b5b600182039050919050565b5f6040820190506129355f8301856121b5565b61294260208301846121b5565b939250505056fe608060405234801561000f575f80fd5b5060405161204338038061204383398181016040528101906100319190610235565b335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826003908161007f91906104ca565b50816004908161008f91906104ca565b508060055f6101000a81548160ff021916908360ff160217905550505050610599565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610111826100cb565b810181811067ffffffffffffffff821117156101305761012f6100db565b5b80604052505050565b5f6101426100b2565b905061014e8282610108565b919050565b5f67ffffffffffffffff82111561016d5761016c6100db565b5b610176826100cb565b9050602081019050919050565b8281835e5f83830152505050565b5f6101a361019e84610153565b610139565b9050828152602081018484840111156101bf576101be6100c7565b5b6101ca848285610183565b509392505050565b5f82601f8301126101e6576101e56100c3565b5b81516101f6848260208601610191565b91505092915050565b5f60ff82169050919050565b610214816101ff565b811461021e575f80fd5b50565b5f8151905061022f8161020b565b92915050565b5f805f6060848603121561024c5761024b6100bb565b5b5f84015167ffffffffffffffff811115610269576102686100bf565b5b610275868287016101d2565b935050602084015167ffffffffffffffff811115610296576102956100bf565b5b6102a2868287016101d2565b92505060406102b386828701610221565b9150509250925092565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061030b57607f821691505b60208210810361031e5761031d6102c7565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026103807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610345565b61038a8683610345565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6103ce6103c96103c4846103a2565b6103ab565b6103a2565b9050919050565b5f819050919050565b6103e7836103b4565b6103fb6103f3826103d5565b848454610351565b825550505050565b5f90565b61040f610403565b61041a8184846103de565b505050565b5b8181101561043d576104325f82610407565b600181019050610420565b5050565b601f8211156104825761045381610324565b61045c84610336565b8101602085101561046b578190505b61047f61047785610336565b83018261041f565b50505b505050565b5f82821c905092915050565b5f6104a25f1984600802610487565b1980831691505092915050565b5f6104ba8383610493565b9150826002028217905092915050565b6104d3826102bd565b67ffffffffffffffff8111156104ec576104eb6100db565b5b6104f682546102f4565b610501828285610441565b5f60209050601f831160018114610532575f8415610520578287015190505b61052a85826104af565b865550610591565b601f19841661054086610324565b5f5b8281101561056757848901518255600182019150602085019450602081019050610542565b868310156105845784890151610580601f891682610493565b8355505b6001600288020188555050505b505050505050565b611a9d806105a65f395ff3fe608060405234801561000f575f80fd5b5060043610610114575f3560e01c806342966c68116100a057806395d89b411161006f57806395d89b41146102f0578063a9059cbb1461030e578063dd62ed3e1461033e578063f2fde38b1461036e578063fe1195ec1461038a57610114565b806342966c681461025657806370a082311461027257806379cc6790146102a25780638da5cb5b146102d257610114565b80631988513b116100e75780631988513b146101b457806323b872dd146101d05780632d688ca814610200578063313ce5671461021c57806340c10f191461023a57610114565b806301ffc9a71461011857806306fdde0314610148578063095ea7b31461016657806318160ddd14610196575b5f80fd5b610132600480360381019061012d919061143b565b6103a6565b60405161013f9190611480565b60405180910390f35b61015061041f565b60405161015d9190611509565b60405180910390f35b610180600480360381019061017b91906115b6565b6104ab565b60405161018d9190611480565b60405180910390f35b61019e610598565b6040516101ab9190611603565b60405180910390f35b6101ce60048036038101906101c9919061161c565b61059e565b005b6101ea60048036038101906101e5919061161c565b61061d565b6040516101f79190611480565b60405180910390f35b61021a600480360381019061021591906115b6565b61077d565b005b6102246107fa565b6040516102319190611687565b60405180910390f35b610254600480360381019061024f91906115b6565b61080c565b005b610270600480360381019061026b91906116a0565b61092b565b005b61028c600480360381019061028791906116cb565b6109f3565b6040516102999190611603565b60405180910390f35b6102bc60048036038101906102b791906115b6565b610a08565b6040516102c99190611480565b60405180910390f35b6102da610b66565b6040516102e79190611705565b60405180910390f35b6102f8610b89565b6040516103059190611509565b60405180910390f35b610328600480360381019061032391906115b6565b610c15565b6040516103359190611480565b60405180910390f35b6103586004803603810190610353919061171e565b610ce6565b6040516103659190611603565b60405180910390f35b610388600480360381019061038391906116cb565b610d06565b005b6103a4600480360381019061039f91906115b6565b610e4e565b005b5f7f8da6da19000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610418575061041782610ecb565b5b9050919050565b6003805461042c90611789565b80601f016020809104026020016040519081016040528092919081815260200182805461045890611789565b80156104a35780601f1061047a576101008083540402835291602001916104a3565b820191905f5260205f20905b81548152906001019060200180831161048657829003601f168201915b505050505081565b5f8160025f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516105869190611603565b60405180910390a36001905092915050565b60065481565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461060d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060490611803565b60405180910390fd5b610618838383610f34565b505050565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016106599190611705565b602060405180830381865afa158015610674573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610698919061184b565b156106d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106cf906118e6565b60405180910390fd5b8260025f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461075f9190611931565b92505081905550610771858585610f34565b60019150509392505050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e390611803565b60405180910390fd5b6107f6828261113f565b5050565b60055f9054906101000a900460ff1681565b8160f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016108479190611705565b602060405180830381865afa158015610862573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610886919061184b565b156108c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108bd906119ae565b60405180910390fd5b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461091c575f80fd5b610926838361113f565b505050565b3360f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b81526004016109669190611705565b602060405180830381865afa158015610981573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109a5919061184b565b156109e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109dc90611a16565b60405180910390fd5b6109ef338361130e565b5050565b6001602052805f5260405f205f915090505481565b5f8260f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b8152600401610a449190611705565b602060405180830381865afa158015610a5f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a83919061184b565b15610ac3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aba90611a16565b60405180910390fd5b8260025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610b4a9190611931565b92505081905550610b5b848461130e565b600191505092915050565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60048054610b9690611789565b80601f0160208091040260200160405190810160405280929190818152602001828054610bc290611789565b8015610c0d5780601f10610be457610100808354040283529160200191610c0d565b820191905f5260205f20905b815481529060010190602001808311610bf057829003601f168201915b505050505081565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b8152600401610c519190611705565b602060405180830381865afa158015610c6c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c90919061184b565b15610cd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc7906118e6565b60405180910390fd5b610cdb338585610f34565b600191505092915050565b6002602052815f5260405f20602052805f5260405f205f91509150505481565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d5c575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d93575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ebd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb490611803565b60405180910390fd5b610ec7828261130e565b5050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b8152600401610f6f9190611705565b602060405180830381865afa158015610f8a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fae919061184b565b61102e5760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b8152600401610fec9190611705565b6020604051808303815f875af1158015611008573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061102c919061184b565b505b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461107a9190611931565b925050819055508160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546110cd9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516111319190611603565b60405180910390a350505050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b815260040161117a9190611705565b602060405180830381865afa158015611195573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b9919061184b565b6112395760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b81526004016111f79190611705565b6020604051808303815f875af1158015611213573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611237919061184b565b505b8160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546112859190611a34565b925050819055508160065f82825461129d9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516113019190611603565b60405180910390a3505050565b8060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461135a9190611931565b925050819055508060065f8282546113729190611931565b925050819055505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516113d69190611603565b60405180910390a35050565b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61141a816113e6565b8114611424575f80fd5b50565b5f8135905061143581611411565b92915050565b5f602082840312156114505761144f6113e2565b5b5f61145d84828501611427565b91505092915050565b5f8115159050919050565b61147a81611466565b82525050565b5f6020820190506114935f830184611471565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6114db82611499565b6114e581856114a3565b93506114f58185602086016114b3565b6114fe816114c1565b840191505092915050565b5f6020820190508181035f83015261152181846114d1565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61155282611529565b9050919050565b61156281611548565b811461156c575f80fd5b50565b5f8135905061157d81611559565b92915050565b5f819050919050565b61159581611583565b811461159f575f80fd5b50565b5f813590506115b08161158c565b92915050565b5f80604083850312156115cc576115cb6113e2565b5b5f6115d98582860161156f565b92505060206115ea858286016115a2565b9150509250929050565b6115fd81611583565b82525050565b5f6020820190506116165f8301846115f4565b92915050565b5f805f60608486031215611633576116326113e2565b5b5f6116408682870161156f565b93505060206116518682870161156f565b9250506040611662868287016115a2565b9150509250925092565b5f60ff82169050919050565b6116818161166c565b82525050565b5f60208201905061169a5f830184611678565b92915050565b5f602082840312156116b5576116b46113e2565b5b5f6116c2848285016115a2565b91505092915050565b5f602082840312156116e0576116df6113e2565b5b5f6116ed8482850161156f565b91505092915050565b6116ff81611548565b82525050565b5f6020820190506117185f8301846116f6565b92915050565b5f8060408385031215611734576117336113e2565b5b5f6117418582860161156f565b92505060206117528582860161156f565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806117a057607f821691505b6020821081036117b3576117b261175c565b5b50919050565b7f45524332303a2063616c6c6572206973206e6f742074686520636861696e00005f82015250565b5f6117ed601e836114a3565b91506117f8826117b9565b602082019050919050565b5f6020820190508181035f83015261181a816117e1565b9050919050565b61182a81611466565b8114611834575f80fd5b50565b5f8151905061184581611821565b92915050565b5f602082840312156118605761185f6113e2565b5b5f61186d84828501611837565b91505092915050565b7f45524332303a207472616e7366657220746f20626c6f636b65642061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f6118d06022836114a3565b91506118db82611876565b604082019050919050565b5f6020820190508181035f8301526118fd816118c4565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61193b82611583565b915061194683611583565b925082820390508181111561195e5761195d611904565b5b92915050565b7f45524332303a206d696e7420746f20626c6f636b6564206164647265737300005f82015250565b5f611998601e836114a3565b91506119a382611964565b602082019050919050565b5f6020820190508181035f8301526119c58161198c565b9050919050565b7f45524332303a206275726e2066726f6d206d6f64756c652061646472657373005f82015250565b5f611a00601f836114a3565b9150611a0b826119cc565b602082019050919050565b5f6020820190508181035f830152611a2d816119f4565b9050919050565b5f611a3e82611583565b9150611a4983611583565b9250828201905080821115611a6157611a60611904565b5b9291505056fea2646970667358221220de4043b1adb87162ffc06c0127fc335d705e04b467c9acd7522c8721ebd4c4bb64736f6c63430008190033222c2274696d656f75745f686569676874223a207b227265766973696f6e5f6e756d626572223a202230222c227265766973696f6e5f686569676874223a202230227d2c2274696d656f75745f74696d657374616d70223a20227b224074797065223a20222f6962632e6170706c69636174696f6e732e7472616e736665722e76312e4d73675472616e73666572222c22736f757263655f706f7274223a20227472616e73666572222c22736f757263655f6368616e6e656c223a2022a264697066735822122062e597885825f4a25ddd1c6cc3cb268b1ba175f3515b7a740be36eb6e19e38ed64736f6c63430008190033", + Bin: "0x60806040525f8060146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055503480156036575f80fd5b50335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550614c4d806100835f395ff3fe608060405234801561000f575f80fd5b506004361061009c575f3560e01c80639a111432116100645780639a11143214610156578063b5ad1fb614610172578063d5c6b504146101a2578063f2fde38b146101d2578063fc078758146101ee5761009c565b806301ffc9a7146100a057806306ef1a86146100d05780630d4f1f9d1461010057806331a503f01461011c5780638da5cb5b14610138575b5f80fd5b6100ba60048036038101906100b59190611902565b61020a565b6040516100c79190611947565b60405180910390f35b6100ea60048036038101906100e59190611ad2565b610273565b6040516100f79190611b99565b60405180910390f35b61011a60048036038101906101159190611c19565b6103f2565b005b61013660048036038101906101319190611c57565b610405565b005b610140610411565b60405161014d9190611b99565b60405180910390f35b610170600480360381019061016b9190611cdf565b610434565b005b61018c60048036038101906101879190611d8e565b610730565b6040516101999190611b99565b60405180910390f35b6101bc60048036038101906101b79190611d8e565b610760565b6040516101c99190611b99565b60405180910390f35b6101ec60048036038101906101e79190611d8e565b610790565b005b61020860048036038101906102039190611db9565b6108d8565b005b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f808484846040516102849061188f565b61029093929190611e94565b604051809103905ff0801580156102a9573d5f803e3d5ffd5b50905060f273ffffffffffffffffffffffffffffffffffffffff1663d126274a826040518263ffffffff1660e01b81526004016102e69190611b99565b6020604051808303815f875af1158015610302573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103269190611eeb565b508073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b336040518263ffffffff1660e01b81526004016103609190611b99565b5f604051808303815f87803b158015610377575f80fd5b505af1158015610389573d5f803e3d5ffd5b505050503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d160405160405180910390a3809150509392505050565b806104015761040082610c51565b5b5050565b61040e81610c51565b50565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61043d84610d8c565b8373ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161047a93929190611f25565b6020604051808303815f875af1158015610496573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104ba9190611eeb565b505f610534838673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610509573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061052d9190611f6e565b60066110af565b905060015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1930836040518363ffffffff1660e01b81526004016105cd929190611f99565b5f604051808303815f87803b1580156105e4575f80fd5b505af11580156105f6573d5f803e3d5ffd5b5050505060015f60148282829054906101000a900467ffffffffffffffff1661061f9190611fed565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e66106cb8860015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685878a61117e565b6040518263ffffffff1660e01b81526004016106e79190612028565b6020604051808303815f875af1158015610703573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107279190611eeb565b50505050505050565b6002602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6001602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107e6575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361081d575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60f173ffffffffffffffffffffffffffffffffffffffff16632b3324ce856040518263ffffffff1660e01b81526004016109139190612028565b6020604051808303815f875af115801561092f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610953919061205c565b90505f73ffffffffffffffffffffffffffffffffffffffff1660025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610a1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a16906120d1565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166379cc679033846040518363ffffffff1660e01b8152600401610a5a929190611f99565b6020604051808303815f875af1158015610a76573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a9a9190611eeb565b505f610b7083600660025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b6b9190611f6e565b6110af565b905060025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85836040518363ffffffff1660e01b8152600401610c09929190611f99565b6020604051808303815f875af1158015610c25573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c499190611eeb565b505050505050565b5f60035f8367ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f206040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182018054610ce69061211c565b80601f0160208091040260200160405190810160405280929190818152602001828054610d129061211c565b8015610d5d5780601f10610d3457610100808354040283529160200191610d5d565b820191905f5260205f20905b815481529060010190602001808311610d4057829003601f168201915b505050505081526020016002820154815250509050610d888160200151825f015183604001516108d8565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff1660015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036110ac575f610fb26040518060400160405280600781526020017f57726170706564000000000000000000000000000000000000000000000000008152508373ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa158015610e9d573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610ec591906121ba565b604051602001610ed692919061223b565b6040516020818303038152906040526040518060400160405280600181526020017f57000000000000000000000000000000000000000000000000000000000000008152508473ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015610f63573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610f8b91906121ba565b604051602001610f9c92919061223b565b60405160208183030381529060405260066112f0565b90508060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505b50565b5f8160ff168360ff1611156110f0575f82846110cb919061225e565b60ff16600a6110da91906123c1565b905080856110e89190612438565b915050611135565b8160ff168360ff161015611130575f838361110b919061225e565b60ff16600a61111a91906123c1565b905080856111289190612468565b915050611134565b8390505b5b5f8103611177576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116e906124f3565b60405180910390fd5b9392505050565b60608560f173ffffffffffffffffffffffffffffffffffffffff166381cf0f6a876040518263ffffffff1660e01b81526004016111bb9190611b99565b5f604051808303815f875af11580156111d6573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906111fe91906121ba565b61120786611409565b60f173ffffffffffffffffffffffffffffffffffffffff16636af32a55306040518263ffffffff1660e01b81526004016112419190611b99565b5f604051808303815f875af115801561125c573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061128491906121ba565b8561128e88611409565b6112b65f60149054906101000a900467ffffffffffffffff1667ffffffffffffffff16611409565b6112bf306114d3565b6040516020016112d69897969594939291906129d9565b604051602081830303815290604052905095945050505050565b5f808484846040516113019061188f565b61130d93929190611e94565b604051809103905ff080158015611326573d5f803e3d5ffd5b50905060f273ffffffffffffffffffffffffffffffffffffffff1663d126274a826040518263ffffffff1660e01b81526004016113639190611b99565b6020604051808303815f875af115801561137f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113a39190611eeb565b503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d160405160405180910390a3809150509392505050565b60605f600161141784611500565b0190505f8167ffffffffffffffff81111561143557611434611978565b5b6040519080825280601f01601f1916602001820160405280156114675781602001600182028036833780820191505090505b5090505f82602001820190505b6001156114c8578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816114bd576114bc61240b565b5b0494505f8503611474575b819350505050919050565b60606114f98273ffffffffffffffffffffffffffffffffffffffff16601460ff16611651565b9050919050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061155c577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816115525761155161240b565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611599576d04ee2d6d415b85acef8100000000838161158f5761158e61240b565b5b0492506020810190505b662386f26fc1000083106115c857662386f26fc1000083816115be576115bd61240b565b5b0492506010810190505b6305f5e10083106115f1576305f5e10083816115e7576115e661240b565b5b0492506008810190505b612710831061161657612710838161160c5761160b61240b565b5b0492506004810190505b60648310611639576064838161162f5761162e61240b565b5b0492506002810190505b600a8310611648576001810190505b80915050919050565b60605f8390505f60028460026116679190612468565b6116719190612b26565b67ffffffffffffffff81111561168a57611689611978565b5b6040519080825280601f01601f1916602001820160405280156116bc5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f815181106116f3576116f2612b59565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061175657611755612b59565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f60018560026117949190612468565b61179e9190612b26565b90505b600181111561183d577f3031323334353637383961626364656600000000000000000000000000000000600f8416601081106117e0576117df612b59565b5b1a60f81b8282815181106117f7576117f6612b59565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600483901c92508061183690612b86565b90506117a1565b505f82146118845784846040517fe22e27eb00000000000000000000000000000000000000000000000000000000815260040161187b929190612bad565b60405180910390fd5b809250505092915050565b61204380612bd583390190565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6118e1816118ad565b81146118eb575f80fd5b50565b5f813590506118fc816118d8565b92915050565b5f60208284031215611917576119166118a5565b5b5f611924848285016118ee565b91505092915050565b5f8115159050919050565b6119418161192d565b82525050565b5f60208201905061195a5f830184611938565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6119ae82611968565b810181811067ffffffffffffffff821117156119cd576119cc611978565b5b80604052505050565b5f6119df61189c565b90506119eb82826119a5565b919050565b5f67ffffffffffffffff821115611a0a57611a09611978565b5b611a1382611968565b9050602081019050919050565b828183375f83830152505050565b5f611a40611a3b846119f0565b6119d6565b905082815260208101848484011115611a5c57611a5b611964565b5b611a67848285611a20565b509392505050565b5f82601f830112611a8357611a82611960565b5b8135611a93848260208601611a2e565b91505092915050565b5f60ff82169050919050565b611ab181611a9c565b8114611abb575f80fd5b50565b5f81359050611acc81611aa8565b92915050565b5f805f60608486031215611ae957611ae86118a5565b5b5f84013567ffffffffffffffff811115611b0657611b056118a9565b5b611b1286828701611a6f565b935050602084013567ffffffffffffffff811115611b3357611b326118a9565b5b611b3f86828701611a6f565b9250506040611b5086828701611abe565b9150509250925092565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611b8382611b5a565b9050919050565b611b9381611b79565b82525050565b5f602082019050611bac5f830184611b8a565b92915050565b5f67ffffffffffffffff82169050919050565b611bce81611bb2565b8114611bd8575f80fd5b50565b5f81359050611be981611bc5565b92915050565b611bf88161192d565b8114611c02575f80fd5b50565b5f81359050611c1381611bef565b92915050565b5f8060408385031215611c2f57611c2e6118a5565b5b5f611c3c85828601611bdb565b9250506020611c4d85828601611c05565b9150509250929050565b5f60208284031215611c6c57611c6b6118a5565b5b5f611c7984828501611bdb565b91505092915050565b611c8b81611b79565b8114611c95575f80fd5b50565b5f81359050611ca681611c82565b92915050565b5f819050919050565b611cbe81611cac565b8114611cc8575f80fd5b50565b5f81359050611cd981611cb5565b92915050565b5f805f805f60a08688031215611cf857611cf76118a5565b5b5f86013567ffffffffffffffff811115611d1557611d146118a9565b5b611d2188828901611a6f565b9550506020611d3288828901611c98565b945050604086013567ffffffffffffffff811115611d5357611d526118a9565b5b611d5f88828901611a6f565b9350506060611d7088828901611ccb565b9250506080611d8188828901611ccb565b9150509295509295909350565b5f60208284031215611da357611da26118a5565b5b5f611db084828501611c98565b91505092915050565b5f805f60608486031215611dd057611dcf6118a5565b5b5f84013567ffffffffffffffff811115611ded57611dec6118a9565b5b611df986828701611a6f565b9350506020611e0a86828701611c98565b9250506040611e1b86828701611ccb565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f611e5782611e25565b611e618185611e2f565b9350611e71818560208601611e3f565b611e7a81611968565b840191505092915050565b611e8e81611a9c565b82525050565b5f6060820190508181035f830152611eac8186611e4d565b90508181036020830152611ec08185611e4d565b9050611ecf6040830184611e85565b949350505050565b5f81519050611ee581611bef565b92915050565b5f60208284031215611f0057611eff6118a5565b5b5f611f0d84828501611ed7565b91505092915050565b611f1f81611cac565b82525050565b5f606082019050611f385f830186611b8a565b611f456020830185611b8a565b611f526040830184611f16565b949350505050565b5f81519050611f6881611aa8565b92915050565b5f60208284031215611f8357611f826118a5565b5b5f611f9084828501611f5a565b91505092915050565b5f604082019050611fac5f830185611b8a565b611fb96020830184611f16565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611ff782611bb2565b915061200283611bb2565b9250828201905067ffffffffffffffff81111561202257612021611fc0565b5b92915050565b5f6020820190508181035f8301526120408184611e4d565b905092915050565b5f8151905061205681611c82565b92915050565b5f60208284031215612071576120706118a5565b5b5f61207e84828501612048565b91505092915050565b7f6f726967696e20746f6b656e20646f65736e27742065786973740000000000005f82015250565b5f6120bb601a83611e2f565b91506120c682612087565b602082019050919050565b5f6020820190508181035f8301526120e8816120af565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061213357607f821691505b602082108103612146576121456120ef565b5b50919050565b5f61215e612159846119f0565b6119d6565b90508281526020810184848401111561217a57612179611964565b5b612185848285611e3f565b509392505050565b5f82601f8301126121a1576121a0611960565b5b81516121b184826020860161214c565b91505092915050565b5f602082840312156121cf576121ce6118a5565b5b5f82015167ffffffffffffffff8111156121ec576121eb6118a9565b5b6121f88482850161218d565b91505092915050565b5f81905092915050565b5f61221582611e25565b61221f8185612201565b935061222f818560208601611e3f565b80840191505092915050565b5f612246828561220b565b9150612252828461220b565b91508190509392505050565b5f61226882611a9c565b915061227383611a9c565b9250828203905060ff81111561228c5761228b611fc0565b5b92915050565b5f8160011c9050919050565b5f808291508390505b60018511156122e7578086048111156122c3576122c2611fc0565b5b60018516156122d25780820291505b80810290506122e085612292565b94506122a7565b94509492505050565b5f826122ff57600190506123ba565b8161230c575f90506123ba565b8160018114612322576002811461232c5761235b565b60019150506123ba565b60ff84111561233e5761233d611fc0565b5b8360020a91508482111561235557612354611fc0565b5b506123ba565b5060208310610133831016604e8410600b84101617156123905782820a90508381111561238b5761238a611fc0565b5b6123ba565b61239d848484600161229e565b925090508184048111156123b4576123b3611fc0565b5b81810290505b9392505050565b5f6123cb82611cac565b91506123d683611cac565b92506124037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846122f0565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61244282611cac565b915061244d83611cac565b92508261245d5761245c61240b565b5b828204905092915050565b5f61247282611cac565b915061247d83611cac565b925082820261248b81611cac565b915082820484148315176124a2576124a1611fc0565b5b5092915050565b7f636f6e76657274656420616d6f756e74206973207a65726f00000000000000005f82015250565b5f6124dd601883611e2f565b91506124e8826124a9565b602082019050919050565b5f6020820190508181035f83015261250a816124d1565b9050919050565b7f7b224074797065223a20222f6962632e6170706c69636174696f6e732e7472615f8201527f6e736665722e76312e4d73675472616e73666572222c00000000000000000000602082015250565b5f61256b603683612201565b915061257682612511565b603682019050919050565b7f22736f757263655f706f7274223a20227472616e73666572222c0000000000005f82015250565b5f6125b5601a83612201565b91506125c082612581565b601a82019050919050565b7f22736f757263655f6368616e6e656c223a2022000000000000000000000000005f82015250565b5f6125ff601383612201565b915061260a826125cb565b601382019050919050565b7f222c0000000000000000000000000000000000000000000000000000000000005f82015250565b5f612649600283612201565b915061265482612615565b600282019050919050565b7f22746f6b656e223a207b202264656e6f6d223a202200000000000000000000005f82015250565b5f612693601583612201565b915061269e8261265f565b601582019050919050565b7f22616d6f756e74223a20220000000000000000000000000000000000000000005f82015250565b5f6126dd600b83612201565b91506126e8826126a9565b600b82019050919050565b7f227d2c00000000000000000000000000000000000000000000000000000000005f82015250565b5f612727600383612201565b9150612732826126f3565b600382019050919050565b7f2273656e646572223a20220000000000000000000000000000000000000000005f82015250565b5f612771600b83612201565b915061277c8261273d565b600b82019050919050565b7f227265636569766572223a2022000000000000000000000000000000000000005f82015250565b5f6127bb600d83612201565b91506127c682612787565b600d82019050919050565b7f2274696d656f75745f686569676874223a207b227265766973696f6e5f6e756d5f8201527f626572223a202230222c227265766973696f6e5f686569676874223a2022302260208201527f7d2c000000000000000000000000000000000000000000000000000000000000604082015250565b5f612851604283612201565b915061285c826127d1565b604282019050919050565b7f2274696d656f75745f74696d657374616d70223a2022000000000000000000005f82015250565b5f61289b601683612201565b91506128a682612867565b601682019050919050565b7f226d656d6f223a2022222c0000000000000000000000000000000000000000005f82015250565b5f6128e5600b83612201565b91506128f0826128b1565b600b82019050919050565b7f226173796e635f63616c6c6261636b223a207b226964223a20220000000000005f82015250565b5f61292f601a83612201565b915061293a826128fb565b601a82019050919050565b7f22636f6e74726163745f61646472657373223a202200000000000000000000005f82015250565b5f612979601583612201565b915061298482612945565b601582019050919050565b7f227d7d00000000000000000000000000000000000000000000000000000000005f82015250565b5f6129c3600383612201565b91506129ce8261298f565b600382019050919050565b5f6129e38261255f565b91506129ee826125a9565b91506129f9826125f3565b9150612a05828b61220b565b9150612a108261263d565b9150612a1b82612687565b9150612a27828a61220b565b9150612a328261263d565b9150612a3d826126d1565b9150612a49828961220b565b9150612a548261271b565b9150612a5f82612765565b9150612a6b828861220b565b9150612a768261263d565b9150612a81826127af565b9150612a8d828761220b565b9150612a988261263d565b9150612aa382612845565b9150612aae8261288f565b9150612aba828661220b565b9150612ac58261263d565b9150612ad0826128d9565b9150612adb82612923565b9150612ae7828561220b565b9150612af28261263d565b9150612afd8261296d565b9150612b09828461220b565b9150612b14826129b7565b91508190509998505050505050505050565b5f612b3082611cac565b9150612b3b83611cac565b9250828201905080821115612b5357612b52611fc0565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f612b9082611cac565b91505f8203612ba257612ba1611fc0565b5b600182039050919050565b5f604082019050612bc05f830185611f16565b612bcd6020830184611f16565b939250505056fe608060405234801561000f575f80fd5b5060405161204338038061204383398181016040528101906100319190610235565b335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826003908161007f91906104ca565b50816004908161008f91906104ca565b508060055f6101000a81548160ff021916908360ff160217905550505050610599565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610111826100cb565b810181811067ffffffffffffffff821117156101305761012f6100db565b5b80604052505050565b5f6101426100b2565b905061014e8282610108565b919050565b5f67ffffffffffffffff82111561016d5761016c6100db565b5b610176826100cb565b9050602081019050919050565b8281835e5f83830152505050565b5f6101a361019e84610153565b610139565b9050828152602081018484840111156101bf576101be6100c7565b5b6101ca848285610183565b509392505050565b5f82601f8301126101e6576101e56100c3565b5b81516101f6848260208601610191565b91505092915050565b5f60ff82169050919050565b610214816101ff565b811461021e575f80fd5b50565b5f8151905061022f8161020b565b92915050565b5f805f6060848603121561024c5761024b6100bb565b5b5f84015167ffffffffffffffff811115610269576102686100bf565b5b610275868287016101d2565b935050602084015167ffffffffffffffff811115610296576102956100bf565b5b6102a2868287016101d2565b92505060406102b386828701610221565b9150509250925092565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061030b57607f821691505b60208210810361031e5761031d6102c7565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026103807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610345565b61038a8683610345565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6103ce6103c96103c4846103a2565b6103ab565b6103a2565b9050919050565b5f819050919050565b6103e7836103b4565b6103fb6103f3826103d5565b848454610351565b825550505050565b5f90565b61040f610403565b61041a8184846103de565b505050565b5b8181101561043d576104325f82610407565b600181019050610420565b5050565b601f8211156104825761045381610324565b61045c84610336565b8101602085101561046b578190505b61047f61047785610336565b83018261041f565b50505b505050565b5f82821c905092915050565b5f6104a25f1984600802610487565b1980831691505092915050565b5f6104ba8383610493565b9150826002028217905092915050565b6104d3826102bd565b67ffffffffffffffff8111156104ec576104eb6100db565b5b6104f682546102f4565b610501828285610441565b5f60209050601f831160018114610532575f8415610520578287015190505b61052a85826104af565b865550610591565b601f19841661054086610324565b5f5b8281101561056757848901518255600182019150602085019450602081019050610542565b868310156105845784890151610580601f891682610493565b8355505b6001600288020188555050505b505050505050565b611a9d806105a65f395ff3fe608060405234801561000f575f80fd5b5060043610610114575f3560e01c806342966c68116100a057806395d89b411161006f57806395d89b41146102f0578063a9059cbb1461030e578063dd62ed3e1461033e578063f2fde38b1461036e578063fe1195ec1461038a57610114565b806342966c681461025657806370a082311461027257806379cc6790146102a25780638da5cb5b146102d257610114565b80631988513b116100e75780631988513b146101b457806323b872dd146101d05780632d688ca814610200578063313ce5671461021c57806340c10f191461023a57610114565b806301ffc9a71461011857806306fdde0314610148578063095ea7b31461016657806318160ddd14610196575b5f80fd5b610132600480360381019061012d919061143b565b6103a6565b60405161013f9190611480565b60405180910390f35b61015061041f565b60405161015d9190611509565b60405180910390f35b610180600480360381019061017b91906115b6565b6104ab565b60405161018d9190611480565b60405180910390f35b61019e610598565b6040516101ab9190611603565b60405180910390f35b6101ce60048036038101906101c9919061161c565b61059e565b005b6101ea60048036038101906101e5919061161c565b61061d565b6040516101f79190611480565b60405180910390f35b61021a600480360381019061021591906115b6565b61077d565b005b6102246107fa565b6040516102319190611687565b60405180910390f35b610254600480360381019061024f91906115b6565b61080c565b005b610270600480360381019061026b91906116a0565b61092b565b005b61028c600480360381019061028791906116cb565b6109f3565b6040516102999190611603565b60405180910390f35b6102bc60048036038101906102b791906115b6565b610a08565b6040516102c99190611480565b60405180910390f35b6102da610b66565b6040516102e79190611705565b60405180910390f35b6102f8610b89565b6040516103059190611509565b60405180910390f35b610328600480360381019061032391906115b6565b610c15565b6040516103359190611480565b60405180910390f35b6103586004803603810190610353919061171e565b610ce6565b6040516103659190611603565b60405180910390f35b610388600480360381019061038391906116cb565b610d06565b005b6103a4600480360381019061039f91906115b6565b610e4e565b005b5f7f8da6da19000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610418575061041782610ecb565b5b9050919050565b6003805461042c90611789565b80601f016020809104026020016040519081016040528092919081815260200182805461045890611789565b80156104a35780601f1061047a576101008083540402835291602001916104a3565b820191905f5260205f20905b81548152906001019060200180831161048657829003601f168201915b505050505081565b5f8160025f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516105869190611603565b60405180910390a36001905092915050565b60065481565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461060d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060490611803565b60405180910390fd5b610618838383610f34565b505050565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016106599190611705565b602060405180830381865afa158015610674573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610698919061184b565b156106d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106cf906118e6565b60405180910390fd5b8260025f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461075f9190611931565b92505081905550610771858585610f34565b60019150509392505050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e390611803565b60405180910390fd5b6107f6828261113f565b5050565b60055f9054906101000a900460ff1681565b8160f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016108479190611705565b602060405180830381865afa158015610862573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610886919061184b565b156108c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108bd906119ae565b60405180910390fd5b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461091c575f80fd5b610926838361113f565b505050565b3360f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b81526004016109669190611705565b602060405180830381865afa158015610981573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109a5919061184b565b156109e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109dc90611a16565b60405180910390fd5b6109ef338361130e565b5050565b6001602052805f5260405f205f915090505481565b5f8260f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b8152600401610a449190611705565b602060405180830381865afa158015610a5f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a83919061184b565b15610ac3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aba90611a16565b60405180910390fd5b8260025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610b4a9190611931565b92505081905550610b5b848461130e565b600191505092915050565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60048054610b9690611789565b80601f0160208091040260200160405190810160405280929190818152602001828054610bc290611789565b8015610c0d5780601f10610be457610100808354040283529160200191610c0d565b820191905f5260205f20905b815481529060010190602001808311610bf057829003601f168201915b505050505081565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b8152600401610c519190611705565b602060405180830381865afa158015610c6c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c90919061184b565b15610cd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc7906118e6565b60405180910390fd5b610cdb338585610f34565b600191505092915050565b6002602052815f5260405f20602052805f5260405f205f91509150505481565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d5c575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d93575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ebd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb490611803565b60405180910390fd5b610ec7828261130e565b5050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b8152600401610f6f9190611705565b602060405180830381865afa158015610f8a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fae919061184b565b61102e5760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b8152600401610fec9190611705565b6020604051808303815f875af1158015611008573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061102c919061184b565b505b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461107a9190611931565b925050819055508160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546110cd9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516111319190611603565b60405180910390a350505050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b815260040161117a9190611705565b602060405180830381865afa158015611195573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b9919061184b565b6112395760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b81526004016111f79190611705565b6020604051808303815f875af1158015611213573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611237919061184b565b505b8160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546112859190611a34565b925050819055508160065f82825461129d9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516113019190611603565b60405180910390a3505050565b8060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461135a9190611931565b925050819055508060065f8282546113729190611931565b925050819055505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516113d69190611603565b60405180910390a35050565b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61141a816113e6565b8114611424575f80fd5b50565b5f8135905061143581611411565b92915050565b5f602082840312156114505761144f6113e2565b5b5f61145d84828501611427565b91505092915050565b5f8115159050919050565b61147a81611466565b82525050565b5f6020820190506114935f830184611471565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6114db82611499565b6114e581856114a3565b93506114f58185602086016114b3565b6114fe816114c1565b840191505092915050565b5f6020820190508181035f83015261152181846114d1565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61155282611529565b9050919050565b61156281611548565b811461156c575f80fd5b50565b5f8135905061157d81611559565b92915050565b5f819050919050565b61159581611583565b811461159f575f80fd5b50565b5f813590506115b08161158c565b92915050565b5f80604083850312156115cc576115cb6113e2565b5b5f6115d98582860161156f565b92505060206115ea858286016115a2565b9150509250929050565b6115fd81611583565b82525050565b5f6020820190506116165f8301846115f4565b92915050565b5f805f60608486031215611633576116326113e2565b5b5f6116408682870161156f565b93505060206116518682870161156f565b9250506040611662868287016115a2565b9150509250925092565b5f60ff82169050919050565b6116818161166c565b82525050565b5f60208201905061169a5f830184611678565b92915050565b5f602082840312156116b5576116b46113e2565b5b5f6116c2848285016115a2565b91505092915050565b5f602082840312156116e0576116df6113e2565b5b5f6116ed8482850161156f565b91505092915050565b6116ff81611548565b82525050565b5f6020820190506117185f8301846116f6565b92915050565b5f8060408385031215611734576117336113e2565b5b5f6117418582860161156f565b92505060206117528582860161156f565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806117a057607f821691505b6020821081036117b3576117b261175c565b5b50919050565b7f45524332303a2063616c6c6572206973206e6f742074686520636861696e00005f82015250565b5f6117ed601e836114a3565b91506117f8826117b9565b602082019050919050565b5f6020820190508181035f83015261181a816117e1565b9050919050565b61182a81611466565b8114611834575f80fd5b50565b5f8151905061184581611821565b92915050565b5f602082840312156118605761185f6113e2565b5b5f61186d84828501611837565b91505092915050565b7f45524332303a207472616e7366657220746f20626c6f636b65642061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f6118d06022836114a3565b91506118db82611876565b604082019050919050565b5f6020820190508181035f8301526118fd816118c4565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61193b82611583565b915061194683611583565b925082820390508181111561195e5761195d611904565b5b92915050565b7f45524332303a206d696e7420746f20626c6f636b6564206164647265737300005f82015250565b5f611998601e836114a3565b91506119a382611964565b602082019050919050565b5f6020820190508181035f8301526119c58161198c565b9050919050565b7f45524332303a206275726e2066726f6d206d6f64756c652061646472657373005f82015250565b5f611a00601f836114a3565b9150611a0b826119cc565b602082019050919050565b5f6020820190508181035f830152611a2d816119f4565b9050919050565b5f611a3e82611583565b9150611a4983611583565b9250828201905080821115611a6157611a60611904565b5b9291505056fea2646970667358221220de4043b1adb87162ffc06c0127fc335d705e04b467c9acd7522c8721ebd4c4bb64736f6c63430008190033a26469706673582212202e4f7864079292b0782cc07ee12a5106426516f82438aca10898d14220a6a61864736f6c63430008190033", } // Erc20WrapperABI is the input ABI used to generate the binding from. diff --git a/x/evm/types/genesis.pb.go b/x/evm/types/genesis.pb.go index ca2c8e1a..7102999b 100644 --- a/x/evm/types/genesis.pb.go +++ b/x/evm/types/genesis.pb.go @@ -37,9 +37,9 @@ type GenesisState struct { ClassTraces []GenesisClassTrace `protobuf:"bytes,6,rep,name=class_traces,json=classTraces,proto3" json:"class_traces" yaml:"class_traces"` EVMBlockHashes []GenesisEVMBlockHash `protobuf:"bytes,7,rep,name=evm_block_hashes,json=evmBlockHashes,proto3" json:"evm_block_hashes" yaml:"evm_block_hashes"` // erc20 factory contract address - Erc20Factory []byte `protobuf:"bytes,5,opt,name=erc20_factory,json=erc20Factory,proto3" json:"erc20_factory,omitempty"` + Erc20Factory []byte `protobuf:"bytes,8,opt,name=erc20_factory,json=erc20Factory,proto3" json:"erc20_factory,omitempty"` // erc20 wrapper contract address - Erc20Wrapper []byte `protobuf:"bytes,6,opt,name=erc20_wrapper,json=erc20Wrapper,proto3" json:"erc20_wrapper,omitempty"` + Erc20Wrapper []byte `protobuf:"bytes,9,opt,name=erc20_wrapper,json=erc20Wrapper,proto3" json:"erc20_wrapper,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -421,47 +421,47 @@ func init() { func init() { proto.RegisterFile("minievm/evm/v1/genesis.proto", fileDescriptor_2f1b77281e8b59af) } var fileDescriptor_2f1b77281e8b59af = []byte{ - // 626 bytes of a gzipped FileDescriptorProto + // 639 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0xcd, 0x4e, 0xdb, 0x4c, 0x14, 0x86, 0x63, 0x12, 0x0c, 0x4c, 0xcc, 0xdf, 0x80, 0xf8, 0x0c, 0x7c, 0xb2, 0xd3, 0x61, 0x93, - 0x56, 0x6a, 0x42, 0x42, 0x37, 0xed, 0x0e, 0x43, 0x69, 0xab, 0xaa, 0x52, 0x35, 0x20, 0xa4, 0x76, - 0x63, 0x4d, 0xec, 0x69, 0x6c, 0x25, 0x8e, 0x23, 0x8f, 0x63, 0xd5, 0xbb, 0x5e, 0x42, 0xaf, 0xa2, - 0xd7, 0xc2, 0x92, 0x65, 0x57, 0x51, 0x95, 0xdc, 0x01, 0x57, 0x50, 0xcd, 0x4f, 0x42, 0x1a, 0x48, - 0xa5, 0x2e, 0x2c, 0x9d, 0x73, 0xe6, 0xf5, 0xf3, 0x8e, 0xce, 0x39, 0x1a, 0xf0, 0x7f, 0x14, 0xf6, - 0x42, 0x9a, 0x45, 0x75, 0xfe, 0x65, 0x8d, 0x7a, 0x9b, 0xf6, 0x28, 0x0b, 0x59, 0xad, 0x9f, 0xc4, - 0x69, 0x0c, 0x37, 0xd4, 0x69, 0x8d, 0x7f, 0x59, 0xe3, 0x60, 0xb7, 0x1d, 0xb7, 0x63, 0x71, 0x54, - 0xe7, 0x91, 0x54, 0x1d, 0x1c, 0xcc, 0x31, 0xd2, 0xbc, 0x4f, 0x15, 0x01, 0xfd, 0x58, 0x06, 0xc6, - 0x1b, 0xc9, 0xbc, 0x4c, 0x49, 0x4a, 0xe1, 0x0b, 0xa0, 0xf7, 0x49, 0x42, 0x22, 0x66, 0x6a, 0x15, - 0xad, 0x5a, 0x6e, 0xee, 0xd5, 0xfe, 0xf4, 0xa8, 0x7d, 0x14, 0xa7, 0x4e, 0xe9, 0x66, 0x68, 0x17, - 0xb0, 0xd2, 0xc2, 0x4f, 0x00, 0x74, 0x68, 0xee, 0x66, 0xa4, 0x3b, 0xa0, 0xcc, 0x5c, 0xaa, 0x14, - 0xab, 0xe5, 0xa6, 0x3d, 0xff, 0xa7, 0xf2, 0x79, 0x4f, 0xf3, 0x6b, 0xae, 0x73, 0xf6, 0x39, 0xe2, - 0x6e, 0x68, 0x6f, 0xe7, 0x24, 0xea, 0xbe, 0x42, 0xf7, 0x00, 0x84, 0xd7, 0x3a, 0x4a, 0xc4, 0xe0, - 0x09, 0xd0, 0x69, 0xe2, 0x35, 0x8f, 0x99, 0x59, 0xac, 0x14, 0xab, 0x86, 0x73, 0x38, 0x1a, 0xda, - 0xfa, 0x6b, 0x7c, 0xd6, 0x3c, 0x66, 0x77, 0x43, 0x7b, 0x5d, 0xfe, 0x2b, 0x15, 0x08, 0x2b, 0x29, - 0x6c, 0x01, 0x43, 0x44, 0x2e, 0x4b, 0xe3, 0x84, 0x32, 0xb3, 0x24, 0x6e, 0x84, 0x16, 0xdc, 0x48, - 0xd0, 0x2e, 0x85, 0xd2, 0x39, 0x54, 0x97, 0xda, 0x99, 0x01, 0x2b, 0x0a, 0xc2, 0x65, 0x91, 0x4a, - 0x25, 0x24, 0xc0, 0xf0, 0x69, 0x2f, 0x8e, 0xdc, 0x34, 0x21, 0x1e, 0x65, 0xe6, 0xb2, 0xf0, 0x78, - 0xb2, 0xc0, 0xe3, 0x9c, 0x4b, 0xaf, 0xb8, 0x72, 0xde, 0x62, 0x16, 0x82, 0x70, 0xd9, 0x9f, 0x0a, - 0x85, 0x85, 0xd7, 0x25, 0x8c, 0x4d, 0x2c, 0xf4, 0xbf, 0x5a, 0x9c, 0x71, 0xe9, 0xa3, 0x16, 0xb3, - 0x10, 0x84, 0xcb, 0xde, 0x54, 0xc8, 0xe0, 0x37, 0x0d, 0x6c, 0xd1, 0x2c, 0x72, 0x5b, 0xdd, 0xd8, - 0xeb, 0xb8, 0x01, 0x61, 0x01, 0x65, 0xe6, 0x8a, 0xf0, 0x39, 0x5a, 0xd4, 0xae, 0xeb, 0x0f, 0x0e, - 0x57, 0xbf, 0x25, 0x2c, 0x70, 0x1a, 0xdc, 0x69, 0x34, 0xb4, 0x37, 0x66, 0xab, 0x94, 0x8f, 0xe6, - 0x3f, 0xd5, 0xc1, 0x39, 0x38, 0xc2, 0x1b, 0x34, 0x8b, 0x66, 0xa4, 0xf0, 0x08, 0xac, 0xcb, 0x36, - 0x7f, 0x21, 0x5e, 0x1a, 0x27, 0xb9, 0xb9, 0x5a, 0xd1, 0xaa, 0x06, 0x96, 0x13, 0xbc, 0x90, 0x35, - 0xf4, 0x12, 0x6c, 0xce, 0xed, 0x0f, 0xdc, 0x02, 0xc5, 0x0e, 0xcd, 0xc5, 0x9e, 0x1a, 0x98, 0x87, - 0x70, 0x17, 0x2c, 0x8b, 0x0d, 0x32, 0x97, 0x44, 0x4d, 0x26, 0xe8, 0x02, 0xc0, 0x87, 0x83, 0x86, - 0x26, 0x58, 0x21, 0xbe, 0x9f, 0x50, 0xc6, 0x14, 0x61, 0x92, 0xc2, 0x3d, 0xa0, 0xab, 0xb5, 0xe1, - 0x8b, 0x6c, 0x60, 0x95, 0xa1, 0x2b, 0xb0, 0xfd, 0x60, 0x98, 0xdc, 0x52, 0x4c, 0x4c, 0x40, 0xd6, - 0xb0, 0x4c, 0xe0, 0x53, 0xb0, 0xe5, 0xc5, 0x3d, 0xde, 0xf0, 0xd4, 0x9d, 0xb8, 0xc8, 0x3b, 0x6d, - 0x4e, 0xea, 0xa7, 0xb2, 0x8c, 0x3a, 0x53, 0xea, 0xfd, 0xfc, 0xe0, 0x3e, 0x58, 0x95, 0x33, 0x0b, - 0x7d, 0x05, 0x5e, 0x11, 0xf9, 0x3b, 0xff, 0x1f, 0xd0, 0xbc, 0x41, 0x83, 0x24, 0x34, 0x8b, 0x02, - 0xc0, 0x43, 0x74, 0x0a, 0x76, 0x1e, 0x19, 0x22, 0x84, 0xa0, 0xc4, 0x87, 0xa3, 0x1a, 0x21, 0x62, - 0xde, 0x85, 0x80, 0x86, 0xed, 0x20, 0x15, 0xf4, 0x12, 0x56, 0x99, 0x73, 0x7e, 0x33, 0xb2, 0xb4, - 0xdb, 0x91, 0xa5, 0xfd, 0x1a, 0x59, 0xda, 0xf7, 0xb1, 0x55, 0xb8, 0x1d, 0x5b, 0x85, 0x9f, 0x63, - 0xab, 0xf0, 0xf9, 0x59, 0x3b, 0x4c, 0x83, 0x41, 0xab, 0xe6, 0xc5, 0x51, 0x3d, 0xec, 0x85, 0x69, - 0x48, 0x9e, 0x77, 0x49, 0x8b, 0xd5, 0x27, 0xcf, 0xcf, 0x57, 0xf1, 0x00, 0x89, 0xd7, 0xa7, 0xa5, - 0x8b, 0xe7, 0xe7, 0xe4, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x41, 0xe3, 0x75, 0x71, 0xe0, 0x04, - 0x00, 0x00, + 0x56, 0x6a, 0x02, 0xa1, 0x9b, 0x76, 0x87, 0xa1, 0xb4, 0x55, 0x55, 0xa9, 0x1a, 0x10, 0x55, 0xbb, + 0xb1, 0x26, 0xf6, 0x34, 0xb6, 0x12, 0xc7, 0x91, 0xc7, 0xb8, 0xf5, 0xae, 0x97, 0xd0, 0xcb, 0x42, + 0xea, 0x86, 0x65, 0x57, 0x51, 0x15, 0xee, 0x80, 0x2b, 0xa8, 0xe6, 0x27, 0xc4, 0x0d, 0xa4, 0x52, + 0x17, 0x96, 0xce, 0x39, 0xf3, 0xfa, 0x79, 0x47, 0xe7, 0x1c, 0x0d, 0xf8, 0x3f, 0x0a, 0xfb, 0x21, + 0xcd, 0xa2, 0x26, 0xff, 0xb2, 0x83, 0x66, 0x87, 0xf6, 0x29, 0x0b, 0x59, 0x63, 0x90, 0xc4, 0x69, + 0x0c, 0x57, 0xd4, 0x69, 0x83, 0x7f, 0xd9, 0xc1, 0xce, 0x66, 0x27, 0xee, 0xc4, 0xe2, 0xa8, 0xc9, + 0x23, 0xa9, 0xda, 0xd9, 0x99, 0x62, 0xa4, 0xf9, 0x80, 0x2a, 0x02, 0xfa, 0x31, 0x0f, 0x8c, 0x57, + 0x92, 0x79, 0x96, 0x92, 0x94, 0xc2, 0x67, 0x40, 0x1f, 0x90, 0x84, 0x44, 0xcc, 0xd4, 0x6a, 0x5a, + 0xbd, 0xda, 0xda, 0x6a, 0xfc, 0xe9, 0xd1, 0x78, 0x2f, 0x4e, 0x9d, 0xca, 0xd5, 0xd0, 0x2e, 0x61, + 0xa5, 0x85, 0x1f, 0x01, 0xe8, 0xd2, 0xdc, 0xcd, 0x48, 0xef, 0x92, 0x32, 0x73, 0xae, 0x56, 0xae, + 0x57, 0x5b, 0xf6, 0xf4, 0x9f, 0xca, 0xe7, 0x2d, 0xcd, 0x2f, 0xb8, 0xce, 0xd9, 0xe6, 0x88, 0xdb, + 0xa1, 0xbd, 0x9e, 0x93, 0xa8, 0xf7, 0x02, 0x4d, 0x00, 0x08, 0x2f, 0x75, 0x95, 0x88, 0xc1, 0x43, + 0xa0, 0xd3, 0xc4, 0x6b, 0xed, 0x33, 0xb3, 0x5c, 0x2b, 0xd7, 0x0d, 0x67, 0x77, 0x34, 0xb4, 0xf5, + 0x97, 0xf8, 0xb8, 0xb5, 0xcf, 0x6e, 0x87, 0xf6, 0xb2, 0xfc, 0x57, 0x2a, 0x10, 0x56, 0x52, 0xd8, + 0x06, 0x86, 0x88, 0x5c, 0x96, 0xc6, 0x09, 0x65, 0x66, 0x45, 0xdc, 0x08, 0xcd, 0xb8, 0x91, 0xa0, + 0x9d, 0x09, 0xa5, 0xb3, 0xab, 0x2e, 0xb5, 0x51, 0x00, 0x2b, 0x0a, 0xc2, 0x55, 0x91, 0x4a, 0x25, + 0x24, 0xc0, 0xf0, 0x69, 0x3f, 0x8e, 0xdc, 0x34, 0x21, 0x1e, 0x65, 0xe6, 0xbc, 0xf0, 0x78, 0x34, + 0xc3, 0xe3, 0x84, 0x4b, 0xcf, 0xb9, 0x72, 0xda, 0xa2, 0x08, 0x41, 0xb8, 0xea, 0xdf, 0x09, 0x85, + 0x85, 0xd7, 0x23, 0x8c, 0x8d, 0x2d, 0xf4, 0xbf, 0x5a, 0x1c, 0x73, 0xe9, 0x83, 0x16, 0x45, 0x08, + 0xc2, 0x55, 0xef, 0x4e, 0xc8, 0xe0, 0x37, 0x0d, 0xac, 0xd1, 0x2c, 0x72, 0xdb, 0xbd, 0xd8, 0xeb, + 0xba, 0x01, 0x61, 0x01, 0x65, 0xe6, 0x82, 0xf0, 0xd9, 0x9b, 0xd5, 0xae, 0x8b, 0x77, 0x0e, 0x57, + 0xbf, 0x26, 0x2c, 0x70, 0x0e, 0xb8, 0xd3, 0x68, 0x68, 0xaf, 0x14, 0xab, 0x94, 0x8f, 0xe6, 0x3f, + 0xd5, 0xc1, 0x29, 0x38, 0xc2, 0x2b, 0x34, 0x8b, 0x0a, 0x52, 0xb8, 0x07, 0x96, 0x65, 0x9b, 0x3f, + 0x13, 0x2f, 0x8d, 0x93, 0xdc, 0x5c, 0xac, 0x69, 0x75, 0x03, 0xcb, 0x09, 0x9e, 0xca, 0xda, 0x44, + 0xf4, 0x25, 0x21, 0x83, 0x01, 0x4d, 0xcc, 0xa5, 0x82, 0xe8, 0x83, 0xac, 0xa1, 0xe7, 0x60, 0x75, + 0x6a, 0xc9, 0xe0, 0x1a, 0x28, 0x77, 0x69, 0x2e, 0x96, 0xd9, 0xc0, 0x3c, 0x84, 0x9b, 0x60, 0x5e, + 0xac, 0x99, 0x39, 0x27, 0x6a, 0x32, 0x41, 0xa7, 0x00, 0xde, 0xdf, 0x06, 0x68, 0x82, 0x05, 0xe2, + 0xfb, 0x09, 0x65, 0x4c, 0x11, 0xc6, 0x29, 0xdc, 0x02, 0xba, 0xda, 0x2d, 0xbe, 0xed, 0x06, 0x56, + 0x19, 0x3a, 0x07, 0xeb, 0xf7, 0x26, 0xce, 0x2d, 0xc5, 0x58, 0x05, 0x64, 0x09, 0xcb, 0x04, 0x3e, + 0x06, 0x6b, 0x5e, 0xdc, 0xe7, 0x53, 0x49, 0xdd, 0xb1, 0x8b, 0xbc, 0xd3, 0xea, 0xb8, 0x7e, 0x24, + 0xcb, 0xa8, 0x7b, 0x47, 0x9d, 0x0c, 0x19, 0x6e, 0x83, 0x45, 0x39, 0xd8, 0xd0, 0x57, 0xe0, 0x05, + 0x91, 0xbf, 0xf1, 0xff, 0x01, 0xcd, 0x1b, 0x74, 0x99, 0x84, 0x66, 0x59, 0x00, 0x78, 0x88, 0x8e, + 0xc0, 0xc6, 0x03, 0x93, 0x86, 0x10, 0x54, 0xf8, 0x04, 0x55, 0x23, 0x44, 0xcc, 0xbb, 0x10, 0xd0, + 0xb0, 0x13, 0xa4, 0x82, 0x5e, 0xc1, 0x2a, 0x73, 0x4e, 0xae, 0x46, 0x96, 0x76, 0x3d, 0xb2, 0xb4, + 0x5f, 0x23, 0x4b, 0xfb, 0x7e, 0x63, 0x95, 0xae, 0x6f, 0xac, 0xd2, 0xcf, 0x1b, 0xab, 0xf4, 0xe9, + 0x49, 0x27, 0x4c, 0x83, 0xcb, 0x76, 0xc3, 0x8b, 0xa3, 0x66, 0xd8, 0x0f, 0xd3, 0x90, 0x3c, 0xed, + 0x91, 0x36, 0x6b, 0x8e, 0xdf, 0xa8, 0xaf, 0xe2, 0x95, 0x12, 0x4f, 0x54, 0x5b, 0x17, 0x6f, 0xd4, + 0xe1, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, 0x40, 0x76, 0xad, 0x05, 0x05, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -489,7 +489,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Erc20Wrapper) i = encodeVarintGenesis(dAtA, i, uint64(len(m.Erc20Wrapper))) i-- - dAtA[i] = 0x32 + dAtA[i] = 0x4a } if len(m.Erc20Factory) > 0 { i -= len(m.Erc20Factory) @@ -1242,7 +1242,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { m.Erc20Factory = []byte{} } iNdEx = postIndex - case 6: + case 9: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Erc20Wrapper", wireType) } diff --git a/x/evm/types/query.pb.go b/x/evm/types/query.pb.go index b86758aa..e4854cae 100644 --- a/x/evm/types/query.pb.go +++ b/x/evm/types/query.pb.go @@ -743,13 +743,13 @@ func init() { func init() { proto.RegisterFile("minievm/evm/v1/query.proto", fileDescriptor_2bf9e0bee7cfd1a4) } var fileDescriptor_2bf9e0bee7cfd1a4 = []byte{ - // 1000 bytes of a gzipped FileDescriptorProto + // 1003 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0x41, 0x6f, 0x1b, 0x45, 0x14, 0xf6, 0x26, 0x76, 0xea, 0x3c, 0xbb, 0x55, 0x3a, 0x31, 0x91, 0xb3, 0x2a, 0xb6, 0xbb, 0x05, 0xea, 0x46, 0xc4, 0x9b, 0x9a, 0x4a, 0xad, 0xca, 0xa9, 0x6e, 0x01, 0x01, 0x45, 0xc0, 0x16, 0x09, - 0x89, 0x8b, 0x35, 0xf1, 0x0e, 0xce, 0x2a, 0xde, 0x9d, 0xcd, 0xce, 0x38, 0x60, 0xaa, 0x72, 0x40, - 0xfc, 0x00, 0x24, 0xb8, 0x71, 0xe1, 0xc0, 0xa1, 0x47, 0x6e, 0x5c, 0x39, 0xe6, 0x58, 0x89, 0x0b, - 0xe2, 0x50, 0x81, 0x83, 0x04, 0x3f, 0x03, 0xcd, 0xdb, 0xd9, 0xd4, 0x5e, 0xaf, 0x2d, 0xe7, 0xe0, + 0x89, 0x8b, 0x35, 0xf1, 0x0e, 0xce, 0x2a, 0xde, 0x9d, 0xcd, 0xce, 0x38, 0xc5, 0x54, 0xe5, 0x80, + 0xf8, 0x01, 0x48, 0x70, 0xe3, 0xc2, 0x81, 0x43, 0x8f, 0xdc, 0xb8, 0x72, 0xcc, 0xb1, 0x12, 0x17, + 0xc4, 0xa1, 0x02, 0x07, 0x09, 0x7e, 0x06, 0x9a, 0xb7, 0xb3, 0x89, 0xbd, 0x5e, 0x5b, 0xe6, 0xe0, 0x68, 0xde, 0x9b, 0x37, 0xef, 0xfb, 0xde, 0x9b, 0x37, 0x5f, 0x16, 0x4c, 0xdf, 0x0b, 0x3c, 0x76, 0xec, 0xdb, 0xea, 0x77, 0x7c, 0xd3, 0x3e, 0x1a, 0xb2, 0x68, 0xd4, 0x0a, 0x23, 0x2e, 0x39, 0xb9, 0xa4, 0xf7, 0x5a, 0xea, 0x77, 0x7c, 0xd3, 0xbc, 0x4c, 0x7d, 0x2f, 0xe0, 0x36, 0xfe, 0x8d, 0x43, @@ -758,27 +758,27 @@ var fileDescriptor_2bf9e0bee7cfd1a4 = []byte{ 0x32, 0xbd, 0x67, 0xdd, 0x86, 0x8d, 0x8f, 0x15, 0x83, 0xfb, 0xdc, 0x65, 0x0e, 0x3b, 0x1a, 0x32, 0x21, 0xc9, 0x35, 0xb8, 0xd8, 0xe3, 0x81, 0x8c, 0x68, 0x4f, 0x76, 0xa9, 0xeb, 0x46, 0x55, 0xa3, 0x61, 0x34, 0xd7, 0x9d, 0x72, 0xe2, 0xbc, 0xe7, 0xba, 0x91, 0xb5, 0x0b, 0x97, 0x27, 0x0e, 0x8a, - 0x90, 0x07, 0x82, 0x11, 0x02, 0xf9, 0x1e, 0x77, 0x99, 0x3e, 0x80, 0xeb, 0xbb, 0xf9, 0xff, 0x7e, - 0xaa, 0x1b, 0xd6, 0x7b, 0x3a, 0xfc, 0x91, 0xa4, 0xf2, 0x5c, 0x40, 0x64, 0x03, 0x56, 0x0f, 0xd9, - 0xa8, 0xba, 0x82, 0x5b, 0x6a, 0x69, 0xed, 0x01, 0x99, 0xcc, 0xa5, 0xb1, 0x2b, 0x50, 0x38, 0xa6, - 0x83, 0x61, 0x02, 0x1e, 0x1b, 0x1a, 0xdd, 0x84, 0x2a, 0x9e, 0x78, 0xcb, 0xb9, 0xdf, 0xde, 0x7b, - 0x9b, 0xf6, 0x24, 0x8f, 0x46, 0x9a, 0x84, 0xf5, 0x26, 0x6c, 0x67, 0xec, 0xe9, 0xa4, 0x55, 0xb8, - 0xa0, 0x88, 0x31, 0x21, 0x74, 0xda, 0xc4, 0xcc, 0x4a, 0xfc, 0x69, 0x44, 0xc3, 0x90, 0x45, 0x99, - 0x89, 0xcf, 0xf6, 0x96, 0x4c, 0x7c, 0x1b, 0xea, 0xba, 0xbd, 0x2f, 0x5a, 0xd1, 0x19, 0x3d, 0x60, - 0x01, 0xf7, 0x93, 0xee, 0x55, 0xa0, 0xe0, 0x2a, 0x3b, 0x29, 0x18, 0x0d, 0xab, 0x03, 0x8d, 0xf9, - 0x07, 0x97, 0x04, 0xbf, 0xa3, 0x2f, 0x6b, 0x0a, 0x6e, 0xa9, 0xa9, 0x48, 0xae, 0x66, 0x1a, 0x2f, - 0x93, 0xa9, 0xc6, 0x1a, 0x1b, 0xc9, 0x04, 0xd2, 0xc1, 0x20, 0xc1, 0xda, 0x82, 0x35, 0xc1, 0x02, - 0x97, 0x25, 0x20, 0xda, 0x9a, 0xe5, 0xb0, 0x92, 0x31, 0x30, 0x15, 0x28, 0x78, 0x41, 0x38, 0x94, - 0xd5, 0xd5, 0x18, 0x0d, 0x0d, 0x72, 0x27, 0x19, 0x8f, 0xbc, 0xf2, 0x76, 0xac, 0x93, 0xe7, 0xf5, - 0xdc, 0x9f, 0xcf, 0xeb, 0x2f, 0xf5, 0xb8, 0xf0, 0xb9, 0x10, 0xee, 0x61, 0xcb, 0xe3, 0xb6, 0x4f, - 0xe5, 0x41, 0xeb, 0xdd, 0x40, 0x3e, 0xfd, 0xf7, 0x97, 0x1d, 0x43, 0x8f, 0x10, 0xb9, 0x07, 0x17, - 0x55, 0x72, 0xd6, 0xe5, 0x21, 0xbe, 0xaa, 0x6a, 0xa1, 0x61, 0x34, 0x4b, 0xed, 0x2b, 0xad, 0xe9, - 0xd7, 0xda, 0xfa, 0x44, 0x05, 0x7d, 0x18, 0xc7, 0x38, 0x65, 0x39, 0x61, 0x59, 0x3f, 0x1a, 0x50, - 0x9e, 0xdc, 0x26, 0x75, 0x28, 0x7d, 0xe1, 0xc9, 0x83, 0xae, 0xcf, 0x7c, 0x1e, 0x8d, 0xb0, 0xca, + 0x90, 0x07, 0x82, 0x11, 0x02, 0xf9, 0x1e, 0x77, 0x99, 0x3e, 0x80, 0xeb, 0xbb, 0xf9, 0x7f, 0x7f, + 0xac, 0x1b, 0xd6, 0x7b, 0x3a, 0xfc, 0x91, 0xa4, 0xf2, 0x7f, 0x01, 0x91, 0x0d, 0x58, 0x3d, 0x64, + 0xa3, 0xea, 0x0a, 0x6e, 0xa9, 0xa5, 0xb5, 0x07, 0x64, 0x32, 0x97, 0xc6, 0xae, 0x40, 0xe1, 0x98, + 0x0e, 0x86, 0x09, 0x78, 0x6c, 0x68, 0x74, 0x13, 0xaa, 0x78, 0xe2, 0x2d, 0xe7, 0x7e, 0x7b, 0xef, + 0x6d, 0xda, 0x93, 0x3c, 0x1a, 0x69, 0x12, 0xd6, 0x9b, 0xb0, 0x9d, 0xb1, 0xa7, 0x93, 0x56, 0xe1, + 0x82, 0x22, 0xc6, 0x84, 0xd0, 0x69, 0x13, 0x33, 0x2b, 0xf1, 0xa7, 0x11, 0x0d, 0x43, 0x16, 0x65, + 0x26, 0x3e, 0xdb, 0x5b, 0x32, 0xf1, 0x6d, 0xa8, 0xeb, 0xf6, 0x9e, 0xb7, 0xa2, 0x33, 0x7a, 0xc0, + 0x02, 0xee, 0x27, 0xdd, 0xab, 0x40, 0xc1, 0x55, 0x76, 0x52, 0x30, 0x1a, 0x56, 0x07, 0x1a, 0xf3, + 0x0f, 0x2e, 0x09, 0x7e, 0x47, 0x5f, 0xd6, 0x14, 0xdc, 0x52, 0x53, 0x91, 0x5c, 0xcd, 0x34, 0x5e, + 0x26, 0x53, 0x8d, 0x35, 0x36, 0x92, 0x09, 0xa4, 0x83, 0x41, 0x82, 0xb5, 0x05, 0x6b, 0x82, 0x05, + 0x2e, 0x4b, 0x40, 0xb4, 0x35, 0xcb, 0x61, 0x25, 0x63, 0x60, 0x2a, 0x50, 0xf0, 0x82, 0x70, 0x28, + 0xab, 0xab, 0x31, 0x1a, 0x1a, 0xe4, 0x4e, 0x32, 0x1e, 0x79, 0xe5, 0xed, 0x58, 0x27, 0x2f, 0xea, + 0xb9, 0x3f, 0x5e, 0xd4, 0x5f, 0xea, 0x71, 0xe1, 0x73, 0x21, 0xdc, 0xc3, 0x96, 0xc7, 0x6d, 0x9f, + 0xca, 0x83, 0xd6, 0xbb, 0x81, 0x7c, 0xf6, 0xcf, 0xcf, 0x3b, 0x86, 0x1e, 0x21, 0x72, 0x0f, 0x2e, + 0xaa, 0xe4, 0xac, 0xcb, 0x43, 0x7c, 0x55, 0xd5, 0x42, 0xc3, 0x68, 0x96, 0xda, 0x57, 0x5a, 0xd3, + 0xaf, 0xb5, 0xf5, 0x89, 0x0a, 0xfa, 0x30, 0x8e, 0x71, 0xca, 0x72, 0xc2, 0xb2, 0x7e, 0x30, 0xa0, + 0x3c, 0xb9, 0x4d, 0xea, 0x50, 0x7a, 0xec, 0xc9, 0x83, 0xae, 0xcf, 0x7c, 0x1e, 0x8d, 0xb0, 0xca, 0xa2, 0x03, 0xca, 0xf5, 0x01, 0x7a, 0xc8, 0xcb, 0x80, 0x56, 0x57, 0x48, 0xda, 0x3b, 0xc4, 0x32, 0x8b, 0xce, 0xba, 0xf2, 0x3c, 0x52, 0x0e, 0x72, 0x15, 0xca, 0x7a, 0x9b, 0x47, 0xb4, 0xcf, 0xb0, 0xd4, 0xa2, 0x53, 0x8a, 0x03, 0xd0, 0x45, 0x9a, 0xb0, 0x81, 0x21, 0x11, 0x93, 0xc3, 0x28, 0xe8, - 0xba, 0x54, 0x52, 0xac, 0xbd, 0xe8, 0x5c, 0x52, 0x7e, 0x07, 0xdd, 0x0f, 0xa8, 0xa4, 0xd6, 0xaf, + 0xba, 0x54, 0x52, 0xac, 0xbd, 0xe8, 0x5c, 0x52, 0x7e, 0x07, 0xdd, 0x0f, 0xa8, 0xa4, 0xd6, 0x2f, 0x46, 0xf2, 0x96, 0xf1, 0x0a, 0xf4, 0xa5, 0x99, 0x50, 0x8c, 0xf4, 0x5a, 0xdf, 0xc2, 0x99, 0x4d, 0xb6, 0xa1, 0x38, 0x14, 0xcc, 0xed, 0xf6, 0xa9, 0x40, 0x6e, 0x79, 0xe7, 0x82, 0xb2, 0xdf, 0xa1, 0x82, 0xb4, 0x21, 0x3f, 0xe0, 0x7d, 0x51, 0x5d, 0x6d, 0xac, 0x36, 0x4b, 0xed, 0xcd, 0x74, 0x93, @@ -786,27 +786,27 @@ var fileDescriptor_2bf9e0bee7cfd1a4 = []byte{ 0x5d, 0x1c, 0x5e, 0x91, 0x53, 0x8a, 0x5b, 0x88, 0x2e, 0x75, 0xa9, 0x2c, 0x8a, 0x78, 0x84, 0xcd, 0x5f, 0x77, 0x62, 0xc3, 0xaa, 0xe8, 0x71, 0xfb, 0x88, 0x46, 0xd4, 0x17, 0xc9, 0xc3, 0x7b, 0x1f, 0x36, 0xa7, 0xbc, 0x9a, 0xf4, 0x2d, 0x58, 0x0b, 0xd1, 0x83, 0xe5, 0x94, 0xda, 0x5b, 0x69, 0x6e, - 0x71, 0x7c, 0x27, 0xaf, 0xe8, 0x39, 0x3a, 0xb6, 0xfd, 0x5b, 0x11, 0x0a, 0x98, 0x8d, 0x7c, 0x05, + 0x71, 0x7c, 0x27, 0xaf, 0xe8, 0x39, 0x3a, 0xb6, 0xfd, 0x6b, 0x11, 0x0a, 0x98, 0x8d, 0x7c, 0x09, 0x79, 0x25, 0x76, 0xa4, 0x91, 0x3e, 0x97, 0x16, 0x50, 0xf3, 0xea, 0x82, 0x88, 0x98, 0x8c, 0xb5, - 0xfb, 0xcd, 0xef, 0xff, 0x7c, 0xbf, 0x72, 0x9d, 0xbc, 0x6a, 0xa7, 0xc4, 0x59, 0x69, 0xa6, 0xb0, - 0x1f, 0x4f, 0x8d, 0xf9, 0x13, 0xf2, 0xad, 0x01, 0x05, 0x94, 0x3b, 0x92, 0x9d, 0x7b, 0x52, 0x56, + 0xfb, 0xf5, 0x6f, 0x7f, 0x7f, 0xb7, 0x72, 0x9d, 0xbc, 0x6a, 0xa7, 0xc4, 0x59, 0x69, 0xa6, 0xb0, + 0x9f, 0x4c, 0x8d, 0xf9, 0x53, 0xf2, 0x8d, 0x01, 0x05, 0x94, 0x3b, 0x92, 0x9d, 0x7b, 0x52, 0x56, 0x4d, 0x6b, 0x51, 0x88, 0xc6, 0xbf, 0x85, 0xf8, 0x2d, 0xf2, 0x7a, 0x1a, 0x5f, 0xa8, 0xb0, 0x19, - 0x02, 0xf6, 0xe3, 0x43, 0x36, 0x7a, 0x42, 0x7e, 0x30, 0xa0, 0x3c, 0xa9, 0x93, 0xa4, 0x99, 0x09, + 0x02, 0xf6, 0x93, 0x43, 0x36, 0x7a, 0x4a, 0xbe, 0x37, 0xa0, 0x3c, 0xa9, 0x93, 0xa4, 0x99, 0x09, 0x95, 0x21, 0xb3, 0xe6, 0x8d, 0x25, 0x22, 0x35, 0x37, 0x1b, 0xb9, 0xdd, 0x20, 0xd7, 0x67, 0x7b, 0x13, 0x73, 0x12, 0x36, 0x8b, 0x7a, 0xed, 0xbd, 0xee, 0xe7, 0x9a, 0xc5, 0x19, 0x2d, 0xad, 0xb2, - 0x8b, 0x68, 0x4d, 0x8b, 0xf4, 0x22, 0x5a, 0x29, 0xc9, 0x3e, 0x3f, 0xad, 0x9f, 0x0d, 0xd8, 0xcc, - 0x90, 0x61, 0x62, 0xcf, 0x19, 0x8f, 0x79, 0x4a, 0x6f, 0xee, 0x2d, 0x7f, 0x40, 0x73, 0xdd, 0x41, - 0xae, 0xaf, 0x10, 0x6b, 0x3e, 0xd7, 0xfd, 0x51, 0x17, 0x75, 0x98, 0x7c, 0x0d, 0x85, 0x98, 0x57, - 0xf6, 0x68, 0x4d, 0x31, 0xb1, 0x16, 0x85, 0x68, 0xec, 0x16, 0x62, 0x37, 0xc9, 0x6b, 0x69, 0x6c, - 0x84, 0x9b, 0x9d, 0xed, 0x01, 0xe4, 0x95, 0xf0, 0xcc, 0x7b, 0x57, 0x2f, 0xfe, 0x2d, 0xcc, 0x7b, - 0x57, 0x13, 0xaa, 0x65, 0xd5, 0x11, 0x7c, 0xfb, 0xae, 0xb1, 0x63, 0x55, 0x66, 0x6a, 0x57, 0x28, - 0x47, 0xb0, 0x16, 0xbf, 0x73, 0x92, 0x5d, 0xcb, 0x94, 0x94, 0x98, 0xd7, 0x16, 0xc6, 0x68, 0xcc, - 0x1a, 0x62, 0x56, 0xc9, 0x56, 0x1a, 0x30, 0x96, 0x90, 0xce, 0xc3, 0x93, 0xbf, 0x6b, 0xb9, 0xa7, - 0xe3, 0x5a, 0xee, 0x64, 0x5c, 0x33, 0x9e, 0x8d, 0x6b, 0xc6, 0x5f, 0xe3, 0x9a, 0xf1, 0xdd, 0x69, - 0x2d, 0xf7, 0xec, 0xb4, 0x96, 0xfb, 0xe3, 0xb4, 0x96, 0xfb, 0x6c, 0xa7, 0xef, 0xc9, 0x83, 0xe1, - 0x7e, 0xab, 0xc7, 0x7d, 0xdb, 0x0b, 0x3c, 0xe9, 0xd1, 0xdd, 0x01, 0xdd, 0x17, 0x67, 0xf9, 0xbe, - 0xc4, 0x8c, 0xf8, 0xdd, 0xb6, 0xbf, 0x86, 0x1f, 0x6e, 0x6f, 0xfc, 0x1f, 0x00, 0x00, 0xff, 0xff, - 0xab, 0x3a, 0x89, 0x56, 0x49, 0x0a, 0x00, 0x00, + 0x8b, 0x68, 0x4d, 0x8b, 0xf4, 0x22, 0x5a, 0x29, 0xc9, 0x5e, 0x9e, 0xd6, 0x63, 0xcd, 0xe2, 0x27, + 0x03, 0x36, 0x33, 0x64, 0x98, 0xd8, 0x73, 0xc6, 0x63, 0x9e, 0xd2, 0x9b, 0x7b, 0xcb, 0x1f, 0xd0, + 0x5c, 0x77, 0x90, 0xeb, 0x2b, 0xc4, 0x9a, 0xcf, 0x75, 0x7f, 0xd4, 0x45, 0x1d, 0x26, 0x5f, 0x41, + 0x21, 0xe6, 0x95, 0x3d, 0x5a, 0x53, 0x4c, 0xac, 0x45, 0x21, 0x1a, 0xbb, 0x85, 0xd8, 0x4d, 0xf2, + 0x5a, 0x1a, 0x1b, 0xe1, 0x66, 0x67, 0x7b, 0x00, 0x79, 0x25, 0x3c, 0xf3, 0xde, 0xd5, 0xf9, 0xbf, + 0x85, 0x79, 0xef, 0x6a, 0x42, 0xb5, 0xac, 0x3a, 0x82, 0x6f, 0xdf, 0x35, 0x76, 0xac, 0xca, 0x4c, + 0xed, 0x0a, 0xe5, 0x08, 0xd6, 0xe2, 0x77, 0x4e, 0xb2, 0x6b, 0x99, 0x92, 0x12, 0xf3, 0xda, 0xc2, + 0x18, 0x8d, 0x59, 0x43, 0xcc, 0x2a, 0xd9, 0x4a, 0x03, 0xc6, 0x12, 0xd2, 0x79, 0x78, 0xf2, 0x57, + 0x2d, 0xf7, 0x6c, 0x5c, 0xcb, 0x9d, 0x8c, 0x6b, 0xc6, 0xf3, 0x71, 0xcd, 0xf8, 0x73, 0x5c, 0x33, + 0xbe, 0x3d, 0xad, 0xe5, 0x9e, 0x9f, 0xd6, 0x72, 0xbf, 0x9f, 0xd6, 0x72, 0x9f, 0xed, 0xf4, 0x3d, + 0x79, 0x30, 0xdc, 0x6f, 0xf5, 0xb8, 0x6f, 0x7b, 0x81, 0x27, 0x3d, 0xba, 0x3b, 0xa0, 0xfb, 0xe2, + 0x2c, 0xdf, 0x17, 0x98, 0x11, 0xbf, 0xdb, 0xf6, 0xd7, 0xf0, 0xc3, 0xed, 0x8d, 0xff, 0x02, 0x00, + 0x00, 0xff, 0xff, 0x93, 0x38, 0xd1, 0x8c, 0x49, 0x0a, 0x00, 0x00, } func (this *QueryCodeResponse) Equal(that interface{}) bool { diff --git a/x/evm/types/query.pb.gw.go b/x/evm/types/query.pb.gw.go index a815939f..4c2e106e 100644 --- a/x/evm/types/query.pb.gw.go +++ b/x/evm/types/query.pb.gw.go @@ -742,7 +742,7 @@ var ( pattern_Query_ERC20Factory_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"minievm", "evm", "v1", "contracts", "erc20_factory"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ERC20Wrapper_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"minievm", "evm", "v1", "contracts", "erc20_factory"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_ERC20Wrapper_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"minievm", "evm", "v1", "contracts", "erc20_wrapper"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_ContractAddrByDenom_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"minievm", "evm", "v1", "contracts", "by_denom"}, "", runtime.AssumeColonVerbOpt(false))) From e71b7cd31dec52764c110aa316228564fb747226 Mon Sep 17 00:00:00 2001 From: suha jin <89185836+djm07073@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:14:12 +0900 Subject: [PATCH 3/6] fix: store the callback data when wrap the token --- x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol index cb294571..f6f6178d 100644 --- a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol +++ b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol @@ -53,6 +53,12 @@ contract ERC20Wrapper is ERC20(wrappedTokens[token]).mint(address(this), wrappedAmt); callBackId += 1; + // store the callback data + ibcCallBack[callBackId] = IbcCallBack({ + sender: msg.sender, + wrappedTokenDenom: COSMOS_CONTRACT.to_denom(wrappedTokens[token]), + wrappedAmt: wrappedAmt + }); // do ibc transfer wrapped token COSMOS_CONTRACT.execute_cosmos( _ibc_transfer( @@ -74,9 +80,7 @@ contract ERC20Wrapper is address receiver, uint wrappedAmt ) public { - address wrappedToken = address( - COSMOS_CONTRACT.to_erc20(wrappedTokenDenom) - ); + address wrappedToken = COSMOS_CONTRACT.to_erc20(wrappedTokenDenom); require( originTokens[wrappedToken] != address(0), "origin token doesn't exist" From 1ea2c4b1330a0d4d2034d98b9574845163ca54b0 Mon Sep 17 00:00:00 2001 From: beer-1 Date: Mon, 21 Oct 2024 12:35:27 +0900 Subject: [PATCH 4/6] formatting --- app/ibc-hooks/README.md | 22 ++++++++----------- x/evm/contracts/erc20_wrapper/ERC20Wrapper.go | 2 +- .../contracts/erc20_wrapper/ERC20Wrapper.sol | 9 +++++++- x/evm/keeper/genesis.go | 2 +- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/app/ibc-hooks/README.md b/app/ibc-hooks/README.md index 72cf50b6..4f95b1b9 100644 --- a/app/ibc-hooks/README.md +++ b/app/ibc-hooks/README.md @@ -49,8 +49,7 @@ type MsgCall struct { // Hex encoded execution input bytes. Input string `protobuf:"bytes,3,opt,name=input,proto3" json:"input,omitempty"` // Value is the amount of fee denom token to transfer to the contract. -Value string `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` - + Value string `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` } ``` @@ -74,7 +73,7 @@ msg := MsgCall{ ContractAddr: packet.data.memo["evm"]["message"]["contract_addr"], // Hex encoded execution input bytes. Input: packet.data.memo["evm"]["message"]["input"], - + // Value is the amount of fee denom token to transfer to the contract. Value: packet.data.memo["evm"]["message"]["value"] } ``` @@ -170,10 +169,12 @@ Also when a contract make IBC transfer request, it should provide async callback ### IBC Transfer using ERC20Wrapper -`src -> dst`: use the ERC20Wrapper contract to wrap and do ibc-transfer +`src -> dst`: Execute the ERC20Wrapper contract to wrap and do ibc-transfer + +`dst -> src`: ibc-trasfer and execute the ERC20Wrapper contract via ibc-hook -`dst -> src`: unwrapped the wrapped token by execute hook - data example + ```json { //... other ibc fields that we don't care about @@ -181,19 +182,14 @@ Also when a contract make IBC transfer request, it should provide async callback "denom": "wrapped token denom", // will be transformed to the local denom (ibc/...) "amount": "1000", "sender": "addr on counterparty chain", // will be transformed - "receiver": "ModuleAddr::ModuleName::FunctionName", + "receiver": "0xcontractaddr", "memo": { "evm": { // execute message on receive packet "message": { - "contract_addr": "...", // should query erc20 wrapper contract addr - "input": "...", // function selector(fc078758) + abiCoder.encode([string,address,address],denom,amount) ref)https://docs.ethers.org/v6/api/abi/abi-coder/#AbiCoder-encode + "contract_addr": "0xerc20_wrapper_contract", // should query erc20 wrapper contract addr + "input": "pack(unwrap, denom, recipient, amount)", // function selector(fc078758) + abiCoder.encode([string,address,address],denom,amount) ref) https://docs.ethers.org/v6/api/abi/abi-coder/#AbiCoder-encode "value": "0" - }, - // optional field to get async callback (ack and timeout) - "async_callback": { - "id": 1, - "contract_addr": "0x1" } } } diff --git a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go index 1f95d43a..3e1fe58a 100644 --- a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go +++ b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go @@ -32,7 +32,7 @@ var ( // Erc20WrapperMetaData contains all meta data concerning the Erc20Wrapper contract. var Erc20WrapperMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"StringsInsufficientHexLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"erc20\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"ERC20Created\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"name\":\"createERC20\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"ibc_ack\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"}],\"name\":\"ibc_timeout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"originTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"wrappedTokenDenom\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wrappedAmt\",\"type\":\"uint256\"}],\"name\":\"unwrap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"channel\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"receiver\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"wrap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"wrappedTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60806040525f8060146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055503480156036575f80fd5b50335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550614c4d806100835f395ff3fe608060405234801561000f575f80fd5b506004361061009c575f3560e01c80639a111432116100645780639a11143214610156578063b5ad1fb614610172578063d5c6b504146101a2578063f2fde38b146101d2578063fc078758146101ee5761009c565b806301ffc9a7146100a057806306ef1a86146100d05780630d4f1f9d1461010057806331a503f01461011c5780638da5cb5b14610138575b5f80fd5b6100ba60048036038101906100b59190611902565b61020a565b6040516100c79190611947565b60405180910390f35b6100ea60048036038101906100e59190611ad2565b610273565b6040516100f79190611b99565b60405180910390f35b61011a60048036038101906101159190611c19565b6103f2565b005b61013660048036038101906101319190611c57565b610405565b005b610140610411565b60405161014d9190611b99565b60405180910390f35b610170600480360381019061016b9190611cdf565b610434565b005b61018c60048036038101906101879190611d8e565b610730565b6040516101999190611b99565b60405180910390f35b6101bc60048036038101906101b79190611d8e565b610760565b6040516101c99190611b99565b60405180910390f35b6101ec60048036038101906101e79190611d8e565b610790565b005b61020860048036038101906102039190611db9565b6108d8565b005b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f808484846040516102849061188f565b61029093929190611e94565b604051809103905ff0801580156102a9573d5f803e3d5ffd5b50905060f273ffffffffffffffffffffffffffffffffffffffff1663d126274a826040518263ffffffff1660e01b81526004016102e69190611b99565b6020604051808303815f875af1158015610302573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103269190611eeb565b508073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b336040518263ffffffff1660e01b81526004016103609190611b99565b5f604051808303815f87803b158015610377575f80fd5b505af1158015610389573d5f803e3d5ffd5b505050503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d160405160405180910390a3809150509392505050565b806104015761040082610c51565b5b5050565b61040e81610c51565b50565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61043d84610d8c565b8373ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161047a93929190611f25565b6020604051808303815f875af1158015610496573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104ba9190611eeb565b505f610534838673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610509573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061052d9190611f6e565b60066110af565b905060015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1930836040518363ffffffff1660e01b81526004016105cd929190611f99565b5f604051808303815f87803b1580156105e4575f80fd5b505af11580156105f6573d5f803e3d5ffd5b5050505060015f60148282829054906101000a900467ffffffffffffffff1661061f9190611fed565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e66106cb8860015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685878a61117e565b6040518263ffffffff1660e01b81526004016106e79190612028565b6020604051808303815f875af1158015610703573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107279190611eeb565b50505050505050565b6002602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6001602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107e6575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361081d575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60f173ffffffffffffffffffffffffffffffffffffffff16632b3324ce856040518263ffffffff1660e01b81526004016109139190612028565b6020604051808303815f875af115801561092f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610953919061205c565b90505f73ffffffffffffffffffffffffffffffffffffffff1660025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610a1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a16906120d1565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166379cc679033846040518363ffffffff1660e01b8152600401610a5a929190611f99565b6020604051808303815f875af1158015610a76573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a9a9190611eeb565b505f610b7083600660025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b6b9190611f6e565b6110af565b905060025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85836040518363ffffffff1660e01b8152600401610c09929190611f99565b6020604051808303815f875af1158015610c25573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c499190611eeb565b505050505050565b5f60035f8367ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f206040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182018054610ce69061211c565b80601f0160208091040260200160405190810160405280929190818152602001828054610d129061211c565b8015610d5d5780601f10610d3457610100808354040283529160200191610d5d565b820191905f5260205f20905b815481529060010190602001808311610d4057829003601f168201915b505050505081526020016002820154815250509050610d888160200151825f015183604001516108d8565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff1660015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036110ac575f610fb26040518060400160405280600781526020017f57726170706564000000000000000000000000000000000000000000000000008152508373ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa158015610e9d573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610ec591906121ba565b604051602001610ed692919061223b565b6040516020818303038152906040526040518060400160405280600181526020017f57000000000000000000000000000000000000000000000000000000000000008152508473ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015610f63573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610f8b91906121ba565b604051602001610f9c92919061223b565b60405160208183030381529060405260066112f0565b90508060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505b50565b5f8160ff168360ff1611156110f0575f82846110cb919061225e565b60ff16600a6110da91906123c1565b905080856110e89190612438565b915050611135565b8160ff168360ff161015611130575f838361110b919061225e565b60ff16600a61111a91906123c1565b905080856111289190612468565b915050611134565b8390505b5b5f8103611177576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116e906124f3565b60405180910390fd5b9392505050565b60608560f173ffffffffffffffffffffffffffffffffffffffff166381cf0f6a876040518263ffffffff1660e01b81526004016111bb9190611b99565b5f604051808303815f875af11580156111d6573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906111fe91906121ba565b61120786611409565b60f173ffffffffffffffffffffffffffffffffffffffff16636af32a55306040518263ffffffff1660e01b81526004016112419190611b99565b5f604051808303815f875af115801561125c573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061128491906121ba565b8561128e88611409565b6112b65f60149054906101000a900467ffffffffffffffff1667ffffffffffffffff16611409565b6112bf306114d3565b6040516020016112d69897969594939291906129d9565b604051602081830303815290604052905095945050505050565b5f808484846040516113019061188f565b61130d93929190611e94565b604051809103905ff080158015611326573d5f803e3d5ffd5b50905060f273ffffffffffffffffffffffffffffffffffffffff1663d126274a826040518263ffffffff1660e01b81526004016113639190611b99565b6020604051808303815f875af115801561137f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113a39190611eeb565b503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d160405160405180910390a3809150509392505050565b60605f600161141784611500565b0190505f8167ffffffffffffffff81111561143557611434611978565b5b6040519080825280601f01601f1916602001820160405280156114675781602001600182028036833780820191505090505b5090505f82602001820190505b6001156114c8578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816114bd576114bc61240b565b5b0494505f8503611474575b819350505050919050565b60606114f98273ffffffffffffffffffffffffffffffffffffffff16601460ff16611651565b9050919050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061155c577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816115525761155161240b565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611599576d04ee2d6d415b85acef8100000000838161158f5761158e61240b565b5b0492506020810190505b662386f26fc1000083106115c857662386f26fc1000083816115be576115bd61240b565b5b0492506010810190505b6305f5e10083106115f1576305f5e10083816115e7576115e661240b565b5b0492506008810190505b612710831061161657612710838161160c5761160b61240b565b5b0492506004810190505b60648310611639576064838161162f5761162e61240b565b5b0492506002810190505b600a8310611648576001810190505b80915050919050565b60605f8390505f60028460026116679190612468565b6116719190612b26565b67ffffffffffffffff81111561168a57611689611978565b5b6040519080825280601f01601f1916602001820160405280156116bc5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f815181106116f3576116f2612b59565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061175657611755612b59565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f60018560026117949190612468565b61179e9190612b26565b90505b600181111561183d577f3031323334353637383961626364656600000000000000000000000000000000600f8416601081106117e0576117df612b59565b5b1a60f81b8282815181106117f7576117f6612b59565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600483901c92508061183690612b86565b90506117a1565b505f82146118845784846040517fe22e27eb00000000000000000000000000000000000000000000000000000000815260040161187b929190612bad565b60405180910390fd5b809250505092915050565b61204380612bd583390190565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6118e1816118ad565b81146118eb575f80fd5b50565b5f813590506118fc816118d8565b92915050565b5f60208284031215611917576119166118a5565b5b5f611924848285016118ee565b91505092915050565b5f8115159050919050565b6119418161192d565b82525050565b5f60208201905061195a5f830184611938565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6119ae82611968565b810181811067ffffffffffffffff821117156119cd576119cc611978565b5b80604052505050565b5f6119df61189c565b90506119eb82826119a5565b919050565b5f67ffffffffffffffff821115611a0a57611a09611978565b5b611a1382611968565b9050602081019050919050565b828183375f83830152505050565b5f611a40611a3b846119f0565b6119d6565b905082815260208101848484011115611a5c57611a5b611964565b5b611a67848285611a20565b509392505050565b5f82601f830112611a8357611a82611960565b5b8135611a93848260208601611a2e565b91505092915050565b5f60ff82169050919050565b611ab181611a9c565b8114611abb575f80fd5b50565b5f81359050611acc81611aa8565b92915050565b5f805f60608486031215611ae957611ae86118a5565b5b5f84013567ffffffffffffffff811115611b0657611b056118a9565b5b611b1286828701611a6f565b935050602084013567ffffffffffffffff811115611b3357611b326118a9565b5b611b3f86828701611a6f565b9250506040611b5086828701611abe565b9150509250925092565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611b8382611b5a565b9050919050565b611b9381611b79565b82525050565b5f602082019050611bac5f830184611b8a565b92915050565b5f67ffffffffffffffff82169050919050565b611bce81611bb2565b8114611bd8575f80fd5b50565b5f81359050611be981611bc5565b92915050565b611bf88161192d565b8114611c02575f80fd5b50565b5f81359050611c1381611bef565b92915050565b5f8060408385031215611c2f57611c2e6118a5565b5b5f611c3c85828601611bdb565b9250506020611c4d85828601611c05565b9150509250929050565b5f60208284031215611c6c57611c6b6118a5565b5b5f611c7984828501611bdb565b91505092915050565b611c8b81611b79565b8114611c95575f80fd5b50565b5f81359050611ca681611c82565b92915050565b5f819050919050565b611cbe81611cac565b8114611cc8575f80fd5b50565b5f81359050611cd981611cb5565b92915050565b5f805f805f60a08688031215611cf857611cf76118a5565b5b5f86013567ffffffffffffffff811115611d1557611d146118a9565b5b611d2188828901611a6f565b9550506020611d3288828901611c98565b945050604086013567ffffffffffffffff811115611d5357611d526118a9565b5b611d5f88828901611a6f565b9350506060611d7088828901611ccb565b9250506080611d8188828901611ccb565b9150509295509295909350565b5f60208284031215611da357611da26118a5565b5b5f611db084828501611c98565b91505092915050565b5f805f60608486031215611dd057611dcf6118a5565b5b5f84013567ffffffffffffffff811115611ded57611dec6118a9565b5b611df986828701611a6f565b9350506020611e0a86828701611c98565b9250506040611e1b86828701611ccb565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f611e5782611e25565b611e618185611e2f565b9350611e71818560208601611e3f565b611e7a81611968565b840191505092915050565b611e8e81611a9c565b82525050565b5f6060820190508181035f830152611eac8186611e4d565b90508181036020830152611ec08185611e4d565b9050611ecf6040830184611e85565b949350505050565b5f81519050611ee581611bef565b92915050565b5f60208284031215611f0057611eff6118a5565b5b5f611f0d84828501611ed7565b91505092915050565b611f1f81611cac565b82525050565b5f606082019050611f385f830186611b8a565b611f456020830185611b8a565b611f526040830184611f16565b949350505050565b5f81519050611f6881611aa8565b92915050565b5f60208284031215611f8357611f826118a5565b5b5f611f9084828501611f5a565b91505092915050565b5f604082019050611fac5f830185611b8a565b611fb96020830184611f16565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611ff782611bb2565b915061200283611bb2565b9250828201905067ffffffffffffffff81111561202257612021611fc0565b5b92915050565b5f6020820190508181035f8301526120408184611e4d565b905092915050565b5f8151905061205681611c82565b92915050565b5f60208284031215612071576120706118a5565b5b5f61207e84828501612048565b91505092915050565b7f6f726967696e20746f6b656e20646f65736e27742065786973740000000000005f82015250565b5f6120bb601a83611e2f565b91506120c682612087565b602082019050919050565b5f6020820190508181035f8301526120e8816120af565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061213357607f821691505b602082108103612146576121456120ef565b5b50919050565b5f61215e612159846119f0565b6119d6565b90508281526020810184848401111561217a57612179611964565b5b612185848285611e3f565b509392505050565b5f82601f8301126121a1576121a0611960565b5b81516121b184826020860161214c565b91505092915050565b5f602082840312156121cf576121ce6118a5565b5b5f82015167ffffffffffffffff8111156121ec576121eb6118a9565b5b6121f88482850161218d565b91505092915050565b5f81905092915050565b5f61221582611e25565b61221f8185612201565b935061222f818560208601611e3f565b80840191505092915050565b5f612246828561220b565b9150612252828461220b565b91508190509392505050565b5f61226882611a9c565b915061227383611a9c565b9250828203905060ff81111561228c5761228b611fc0565b5b92915050565b5f8160011c9050919050565b5f808291508390505b60018511156122e7578086048111156122c3576122c2611fc0565b5b60018516156122d25780820291505b80810290506122e085612292565b94506122a7565b94509492505050565b5f826122ff57600190506123ba565b8161230c575f90506123ba565b8160018114612322576002811461232c5761235b565b60019150506123ba565b60ff84111561233e5761233d611fc0565b5b8360020a91508482111561235557612354611fc0565b5b506123ba565b5060208310610133831016604e8410600b84101617156123905782820a90508381111561238b5761238a611fc0565b5b6123ba565b61239d848484600161229e565b925090508184048111156123b4576123b3611fc0565b5b81810290505b9392505050565b5f6123cb82611cac565b91506123d683611cac565b92506124037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846122f0565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61244282611cac565b915061244d83611cac565b92508261245d5761245c61240b565b5b828204905092915050565b5f61247282611cac565b915061247d83611cac565b925082820261248b81611cac565b915082820484148315176124a2576124a1611fc0565b5b5092915050565b7f636f6e76657274656420616d6f756e74206973207a65726f00000000000000005f82015250565b5f6124dd601883611e2f565b91506124e8826124a9565b602082019050919050565b5f6020820190508181035f83015261250a816124d1565b9050919050565b7f7b224074797065223a20222f6962632e6170706c69636174696f6e732e7472615f8201527f6e736665722e76312e4d73675472616e73666572222c00000000000000000000602082015250565b5f61256b603683612201565b915061257682612511565b603682019050919050565b7f22736f757263655f706f7274223a20227472616e73666572222c0000000000005f82015250565b5f6125b5601a83612201565b91506125c082612581565b601a82019050919050565b7f22736f757263655f6368616e6e656c223a2022000000000000000000000000005f82015250565b5f6125ff601383612201565b915061260a826125cb565b601382019050919050565b7f222c0000000000000000000000000000000000000000000000000000000000005f82015250565b5f612649600283612201565b915061265482612615565b600282019050919050565b7f22746f6b656e223a207b202264656e6f6d223a202200000000000000000000005f82015250565b5f612693601583612201565b915061269e8261265f565b601582019050919050565b7f22616d6f756e74223a20220000000000000000000000000000000000000000005f82015250565b5f6126dd600b83612201565b91506126e8826126a9565b600b82019050919050565b7f227d2c00000000000000000000000000000000000000000000000000000000005f82015250565b5f612727600383612201565b9150612732826126f3565b600382019050919050565b7f2273656e646572223a20220000000000000000000000000000000000000000005f82015250565b5f612771600b83612201565b915061277c8261273d565b600b82019050919050565b7f227265636569766572223a2022000000000000000000000000000000000000005f82015250565b5f6127bb600d83612201565b91506127c682612787565b600d82019050919050565b7f2274696d656f75745f686569676874223a207b227265766973696f6e5f6e756d5f8201527f626572223a202230222c227265766973696f6e5f686569676874223a2022302260208201527f7d2c000000000000000000000000000000000000000000000000000000000000604082015250565b5f612851604283612201565b915061285c826127d1565b604282019050919050565b7f2274696d656f75745f74696d657374616d70223a2022000000000000000000005f82015250565b5f61289b601683612201565b91506128a682612867565b601682019050919050565b7f226d656d6f223a2022222c0000000000000000000000000000000000000000005f82015250565b5f6128e5600b83612201565b91506128f0826128b1565b600b82019050919050565b7f226173796e635f63616c6c6261636b223a207b226964223a20220000000000005f82015250565b5f61292f601a83612201565b915061293a826128fb565b601a82019050919050565b7f22636f6e74726163745f61646472657373223a202200000000000000000000005f82015250565b5f612979601583612201565b915061298482612945565b601582019050919050565b7f227d7d00000000000000000000000000000000000000000000000000000000005f82015250565b5f6129c3600383612201565b91506129ce8261298f565b600382019050919050565b5f6129e38261255f565b91506129ee826125a9565b91506129f9826125f3565b9150612a05828b61220b565b9150612a108261263d565b9150612a1b82612687565b9150612a27828a61220b565b9150612a328261263d565b9150612a3d826126d1565b9150612a49828961220b565b9150612a548261271b565b9150612a5f82612765565b9150612a6b828861220b565b9150612a768261263d565b9150612a81826127af565b9150612a8d828761220b565b9150612a988261263d565b9150612aa382612845565b9150612aae8261288f565b9150612aba828661220b565b9150612ac58261263d565b9150612ad0826128d9565b9150612adb82612923565b9150612ae7828561220b565b9150612af28261263d565b9150612afd8261296d565b9150612b09828461220b565b9150612b14826129b7565b91508190509998505050505050505050565b5f612b3082611cac565b9150612b3b83611cac565b9250828201905080821115612b5357612b52611fc0565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f612b9082611cac565b91505f8203612ba257612ba1611fc0565b5b600182039050919050565b5f604082019050612bc05f830185611f16565b612bcd6020830184611f16565b939250505056fe608060405234801561000f575f80fd5b5060405161204338038061204383398181016040528101906100319190610235565b335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826003908161007f91906104ca565b50816004908161008f91906104ca565b508060055f6101000a81548160ff021916908360ff160217905550505050610599565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610111826100cb565b810181811067ffffffffffffffff821117156101305761012f6100db565b5b80604052505050565b5f6101426100b2565b905061014e8282610108565b919050565b5f67ffffffffffffffff82111561016d5761016c6100db565b5b610176826100cb565b9050602081019050919050565b8281835e5f83830152505050565b5f6101a361019e84610153565b610139565b9050828152602081018484840111156101bf576101be6100c7565b5b6101ca848285610183565b509392505050565b5f82601f8301126101e6576101e56100c3565b5b81516101f6848260208601610191565b91505092915050565b5f60ff82169050919050565b610214816101ff565b811461021e575f80fd5b50565b5f8151905061022f8161020b565b92915050565b5f805f6060848603121561024c5761024b6100bb565b5b5f84015167ffffffffffffffff811115610269576102686100bf565b5b610275868287016101d2565b935050602084015167ffffffffffffffff811115610296576102956100bf565b5b6102a2868287016101d2565b92505060406102b386828701610221565b9150509250925092565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061030b57607f821691505b60208210810361031e5761031d6102c7565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026103807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610345565b61038a8683610345565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6103ce6103c96103c4846103a2565b6103ab565b6103a2565b9050919050565b5f819050919050565b6103e7836103b4565b6103fb6103f3826103d5565b848454610351565b825550505050565b5f90565b61040f610403565b61041a8184846103de565b505050565b5b8181101561043d576104325f82610407565b600181019050610420565b5050565b601f8211156104825761045381610324565b61045c84610336565b8101602085101561046b578190505b61047f61047785610336565b83018261041f565b50505b505050565b5f82821c905092915050565b5f6104a25f1984600802610487565b1980831691505092915050565b5f6104ba8383610493565b9150826002028217905092915050565b6104d3826102bd565b67ffffffffffffffff8111156104ec576104eb6100db565b5b6104f682546102f4565b610501828285610441565b5f60209050601f831160018114610532575f8415610520578287015190505b61052a85826104af565b865550610591565b601f19841661054086610324565b5f5b8281101561056757848901518255600182019150602085019450602081019050610542565b868310156105845784890151610580601f891682610493565b8355505b6001600288020188555050505b505050505050565b611a9d806105a65f395ff3fe608060405234801561000f575f80fd5b5060043610610114575f3560e01c806342966c68116100a057806395d89b411161006f57806395d89b41146102f0578063a9059cbb1461030e578063dd62ed3e1461033e578063f2fde38b1461036e578063fe1195ec1461038a57610114565b806342966c681461025657806370a082311461027257806379cc6790146102a25780638da5cb5b146102d257610114565b80631988513b116100e75780631988513b146101b457806323b872dd146101d05780632d688ca814610200578063313ce5671461021c57806340c10f191461023a57610114565b806301ffc9a71461011857806306fdde0314610148578063095ea7b31461016657806318160ddd14610196575b5f80fd5b610132600480360381019061012d919061143b565b6103a6565b60405161013f9190611480565b60405180910390f35b61015061041f565b60405161015d9190611509565b60405180910390f35b610180600480360381019061017b91906115b6565b6104ab565b60405161018d9190611480565b60405180910390f35b61019e610598565b6040516101ab9190611603565b60405180910390f35b6101ce60048036038101906101c9919061161c565b61059e565b005b6101ea60048036038101906101e5919061161c565b61061d565b6040516101f79190611480565b60405180910390f35b61021a600480360381019061021591906115b6565b61077d565b005b6102246107fa565b6040516102319190611687565b60405180910390f35b610254600480360381019061024f91906115b6565b61080c565b005b610270600480360381019061026b91906116a0565b61092b565b005b61028c600480360381019061028791906116cb565b6109f3565b6040516102999190611603565b60405180910390f35b6102bc60048036038101906102b791906115b6565b610a08565b6040516102c99190611480565b60405180910390f35b6102da610b66565b6040516102e79190611705565b60405180910390f35b6102f8610b89565b6040516103059190611509565b60405180910390f35b610328600480360381019061032391906115b6565b610c15565b6040516103359190611480565b60405180910390f35b6103586004803603810190610353919061171e565b610ce6565b6040516103659190611603565b60405180910390f35b610388600480360381019061038391906116cb565b610d06565b005b6103a4600480360381019061039f91906115b6565b610e4e565b005b5f7f8da6da19000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610418575061041782610ecb565b5b9050919050565b6003805461042c90611789565b80601f016020809104026020016040519081016040528092919081815260200182805461045890611789565b80156104a35780601f1061047a576101008083540402835291602001916104a3565b820191905f5260205f20905b81548152906001019060200180831161048657829003601f168201915b505050505081565b5f8160025f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516105869190611603565b60405180910390a36001905092915050565b60065481565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461060d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060490611803565b60405180910390fd5b610618838383610f34565b505050565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016106599190611705565b602060405180830381865afa158015610674573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610698919061184b565b156106d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106cf906118e6565b60405180910390fd5b8260025f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461075f9190611931565b92505081905550610771858585610f34565b60019150509392505050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e390611803565b60405180910390fd5b6107f6828261113f565b5050565b60055f9054906101000a900460ff1681565b8160f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016108479190611705565b602060405180830381865afa158015610862573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610886919061184b565b156108c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108bd906119ae565b60405180910390fd5b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461091c575f80fd5b610926838361113f565b505050565b3360f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b81526004016109669190611705565b602060405180830381865afa158015610981573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109a5919061184b565b156109e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109dc90611a16565b60405180910390fd5b6109ef338361130e565b5050565b6001602052805f5260405f205f915090505481565b5f8260f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b8152600401610a449190611705565b602060405180830381865afa158015610a5f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a83919061184b565b15610ac3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aba90611a16565b60405180910390fd5b8260025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610b4a9190611931565b92505081905550610b5b848461130e565b600191505092915050565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60048054610b9690611789565b80601f0160208091040260200160405190810160405280929190818152602001828054610bc290611789565b8015610c0d5780601f10610be457610100808354040283529160200191610c0d565b820191905f5260205f20905b815481529060010190602001808311610bf057829003601f168201915b505050505081565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b8152600401610c519190611705565b602060405180830381865afa158015610c6c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c90919061184b565b15610cd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc7906118e6565b60405180910390fd5b610cdb338585610f34565b600191505092915050565b6002602052815f5260405f20602052805f5260405f205f91509150505481565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d5c575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d93575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ebd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb490611803565b60405180910390fd5b610ec7828261130e565b5050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b8152600401610f6f9190611705565b602060405180830381865afa158015610f8a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fae919061184b565b61102e5760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b8152600401610fec9190611705565b6020604051808303815f875af1158015611008573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061102c919061184b565b505b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461107a9190611931565b925050819055508160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546110cd9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516111319190611603565b60405180910390a350505050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b815260040161117a9190611705565b602060405180830381865afa158015611195573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b9919061184b565b6112395760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b81526004016111f79190611705565b6020604051808303815f875af1158015611213573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611237919061184b565b505b8160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546112859190611a34565b925050819055508160065f82825461129d9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516113019190611603565b60405180910390a3505050565b8060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461135a9190611931565b925050819055508060065f8282546113729190611931565b925050819055505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516113d69190611603565b60405180910390a35050565b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61141a816113e6565b8114611424575f80fd5b50565b5f8135905061143581611411565b92915050565b5f602082840312156114505761144f6113e2565b5b5f61145d84828501611427565b91505092915050565b5f8115159050919050565b61147a81611466565b82525050565b5f6020820190506114935f830184611471565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6114db82611499565b6114e581856114a3565b93506114f58185602086016114b3565b6114fe816114c1565b840191505092915050565b5f6020820190508181035f83015261152181846114d1565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61155282611529565b9050919050565b61156281611548565b811461156c575f80fd5b50565b5f8135905061157d81611559565b92915050565b5f819050919050565b61159581611583565b811461159f575f80fd5b50565b5f813590506115b08161158c565b92915050565b5f80604083850312156115cc576115cb6113e2565b5b5f6115d98582860161156f565b92505060206115ea858286016115a2565b9150509250929050565b6115fd81611583565b82525050565b5f6020820190506116165f8301846115f4565b92915050565b5f805f60608486031215611633576116326113e2565b5b5f6116408682870161156f565b93505060206116518682870161156f565b9250506040611662868287016115a2565b9150509250925092565b5f60ff82169050919050565b6116818161166c565b82525050565b5f60208201905061169a5f830184611678565b92915050565b5f602082840312156116b5576116b46113e2565b5b5f6116c2848285016115a2565b91505092915050565b5f602082840312156116e0576116df6113e2565b5b5f6116ed8482850161156f565b91505092915050565b6116ff81611548565b82525050565b5f6020820190506117185f8301846116f6565b92915050565b5f8060408385031215611734576117336113e2565b5b5f6117418582860161156f565b92505060206117528582860161156f565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806117a057607f821691505b6020821081036117b3576117b261175c565b5b50919050565b7f45524332303a2063616c6c6572206973206e6f742074686520636861696e00005f82015250565b5f6117ed601e836114a3565b91506117f8826117b9565b602082019050919050565b5f6020820190508181035f83015261181a816117e1565b9050919050565b61182a81611466565b8114611834575f80fd5b50565b5f8151905061184581611821565b92915050565b5f602082840312156118605761185f6113e2565b5b5f61186d84828501611837565b91505092915050565b7f45524332303a207472616e7366657220746f20626c6f636b65642061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f6118d06022836114a3565b91506118db82611876565b604082019050919050565b5f6020820190508181035f8301526118fd816118c4565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61193b82611583565b915061194683611583565b925082820390508181111561195e5761195d611904565b5b92915050565b7f45524332303a206d696e7420746f20626c6f636b6564206164647265737300005f82015250565b5f611998601e836114a3565b91506119a382611964565b602082019050919050565b5f6020820190508181035f8301526119c58161198c565b9050919050565b7f45524332303a206275726e2066726f6d206d6f64756c652061646472657373005f82015250565b5f611a00601f836114a3565b9150611a0b826119cc565b602082019050919050565b5f6020820190508181035f830152611a2d816119f4565b9050919050565b5f611a3e82611583565b9150611a4983611583565b9250828201905080821115611a6157611a60611904565b5b9291505056fea2646970667358221220de4043b1adb87162ffc06c0127fc335d705e04b467c9acd7522c8721ebd4c4bb64736f6c63430008190033a26469706673582212202e4f7864079292b0782cc07ee12a5106426516f82438aca10898d14220a6a61864736f6c63430008190033", + Bin: "0x60806040525f8060146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055503480156036575f80fd5b50335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550615063806100835f395ff3fe608060405234801561000f575f80fd5b506004361061009c575f3560e01c80639a111432116100645780639a11143214610156578063b5ad1fb614610172578063d5c6b504146101a2578063f2fde38b146101d2578063fc078758146101ee5761009c565b806301ffc9a7146100a057806306ef1a86146100d05780630d4f1f9d1461010057806331a503f01461011c5780638da5cb5b14610138575b5f80fd5b6100ba60048036038101906100b59190611aac565b61020a565b6040516100c79190611af1565b60405180910390f35b6100ea60048036038101906100e59190611c7c565b610273565b6040516100f79190611d43565b60405180910390f35b61011a60048036038101906101159190611dc3565b6103f2565b005b61013660048036038101906101319190611e01565b610405565b005b610140610411565b60405161014d9190611d43565b60405180910390f35b610170600480360381019061016b9190611e89565b610434565b005b61018c60048036038101906101879190611f38565b6108da565b6040516101999190611d43565b60405180910390f35b6101bc60048036038101906101b79190611f38565b61090a565b6040516101c99190611d43565b60405180910390f35b6101ec60048036038101906101e79190611f38565b61093a565b005b61020860048036038101906102039190611f63565b610a82565b005b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f8084848460405161028490611a39565b6102909392919061203e565b604051809103905ff0801580156102a9573d5f803e3d5ffd5b50905060f273ffffffffffffffffffffffffffffffffffffffff1663d126274a826040518263ffffffff1660e01b81526004016102e69190611d43565b6020604051808303815f875af1158015610302573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103269190612095565b508073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b336040518263ffffffff1660e01b81526004016103609190611d43565b5f604051808303815f87803b158015610377575f80fd5b505af1158015610389573d5f803e3d5ffd5b505050503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d160405160405180910390a3809150509392505050565b806104015761040082610dfb565b5b5050565b61040e81610dfb565b50565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61043d84610f36565b8373ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161047a939291906120cf565b6020604051808303815f875af1158015610496573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104ba9190612095565b505f610534838673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610509573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061052d9190612118565b6006611259565b905060015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1930836040518363ffffffff1660e01b81526004016105cd929190612143565b5f604051808303815f87803b1580156105e4575f80fd5b505af11580156105f6573d5f803e3d5ffd5b5050505060015f60148282829054906101000a900467ffffffffffffffff1661061f9190612197565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060405180606001604052803373ffffffffffffffffffffffffffffffffffffffff16815260200160f173ffffffffffffffffffffffffffffffffffffffff166381cf0f6a60015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016107029190611d43565b5f604051808303815f875af115801561071d573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906107459190612240565b81526020018281525060035f8060149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010190816107e19190612481565b506040820151816002015590505060f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e66108758860015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685878a611328565b6040518263ffffffff1660e01b81526004016108919190612550565b6020604051808303815f875af11580156108ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108d19190612095565b50505050505050565b6002602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6001602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610990575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109c7575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60f173ffffffffffffffffffffffffffffffffffffffff16632b3324ce856040518263ffffffff1660e01b8152600401610abd9190612550565b6020604051808303815f875af1158015610ad9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610afd9190612584565b90505f73ffffffffffffffffffffffffffffffffffffffff1660025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610bc9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc0906125f9565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166379cc679033846040518363ffffffff1660e01b8152600401610c04929190612143565b6020604051808303815f875af1158015610c20573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c449190612095565b505f610d1a83600660025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cf1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d159190612118565b611259565b905060025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85836040518363ffffffff1660e01b8152600401610db3929190612143565b6020604051808303815f875af1158015610dcf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610df39190612095565b505050505050565b5f60035f8367ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f206040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182018054610e90906122b4565b80601f0160208091040260200160405190810160405280929190818152602001828054610ebc906122b4565b8015610f075780601f10610ede57610100808354040283529160200191610f07565b820191905f5260205f20905b815481529060010190602001808311610eea57829003601f168201915b505050505081526020016002820154815250509050610f328160200151825f01518360400151610a82565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff1660015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603611256575f61115c6040518060400160405280600781526020017f57726170706564000000000000000000000000000000000000000000000000008152508373ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa158015611047573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061106f9190612240565b604051602001611080929190612651565b6040516020818303038152906040526040518060400160405280600181526020017f57000000000000000000000000000000000000000000000000000000000000008152508473ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa15801561110d573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906111359190612240565b604051602001611146929190612651565b604051602081830303815290604052600661149a565b90508060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505b50565b5f8160ff168360ff16111561129a575f82846112759190612674565b60ff16600a61128491906127d7565b90508085611292919061284e565b9150506112df565b8160ff168360ff1610156112da575f83836112b59190612674565b60ff16600a6112c491906127d7565b905080856112d2919061287e565b9150506112de565b8390505b5b5f8103611321576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131890612909565b60405180910390fd5b9392505050565b60608560f173ffffffffffffffffffffffffffffffffffffffff166381cf0f6a876040518263ffffffff1660e01b81526004016113659190611d43565b5f604051808303815f875af1158015611380573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906113a89190612240565b6113b1866115b3565b60f173ffffffffffffffffffffffffffffffffffffffff16636af32a55306040518263ffffffff1660e01b81526004016113eb9190611d43565b5f604051808303815f875af1158015611406573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061142e9190612240565b85611438886115b3565b6114605f60149054906101000a900467ffffffffffffffff1667ffffffffffffffff166115b3565b6114693061167d565b604051602001611480989796959493929190612def565b604051602081830303815290604052905095945050505050565b5f808484846040516114ab90611a39565b6114b79392919061203e565b604051809103905ff0801580156114d0573d5f803e3d5ffd5b50905060f273ffffffffffffffffffffffffffffffffffffffff1663d126274a826040518263ffffffff1660e01b815260040161150d9190611d43565b6020604051808303815f875af1158015611529573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061154d9190612095565b503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d160405160405180910390a3809150509392505050565b60605f60016115c1846116aa565b0190505f8167ffffffffffffffff8111156115df576115de611b22565b5b6040519080825280601f01601f1916602001820160405280156116115781602001600182028036833780820191505090505b5090505f82602001820190505b600115611672578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161166757611666612821565b5b0494505f850361161e575b819350505050919050565b60606116a38273ffffffffffffffffffffffffffffffffffffffff16601460ff166117fb565b9050919050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611706577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816116fc576116fb612821565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611743576d04ee2d6d415b85acef8100000000838161173957611738612821565b5b0492506020810190505b662386f26fc10000831061177257662386f26fc10000838161176857611767612821565b5b0492506010810190505b6305f5e100831061179b576305f5e100838161179157611790612821565b5b0492506008810190505b61271083106117c05761271083816117b6576117b5612821565b5b0492506004810190505b606483106117e357606483816117d9576117d8612821565b5b0492506002810190505b600a83106117f2576001810190505b80915050919050565b60605f8390505f6002846002611811919061287e565b61181b9190612f3c565b67ffffffffffffffff81111561183457611833611b22565b5b6040519080825280601f01601f1916602001820160405280156118665781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f8151811061189d5761189c612f6f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611900576118ff612f6f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f600185600261193e919061287e565b6119489190612f3c565b90505b60018111156119e7577f3031323334353637383961626364656600000000000000000000000000000000600f84166010811061198a57611989612f6f565b5b1a60f81b8282815181106119a1576119a0612f6f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600483901c9250806119e090612f9c565b905061194b565b505f8214611a2e5784846040517fe22e27eb000000000000000000000000000000000000000000000000000000008152600401611a25929190612fc3565b60405180910390fd5b809250505092915050565b61204380612feb83390190565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611a8b81611a57565b8114611a95575f80fd5b50565b5f81359050611aa681611a82565b92915050565b5f60208284031215611ac157611ac0611a4f565b5b5f611ace84828501611a98565b91505092915050565b5f8115159050919050565b611aeb81611ad7565b82525050565b5f602082019050611b045f830184611ae2565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611b5882611b12565b810181811067ffffffffffffffff82111715611b7757611b76611b22565b5b80604052505050565b5f611b89611a46565b9050611b958282611b4f565b919050565b5f67ffffffffffffffff821115611bb457611bb3611b22565b5b611bbd82611b12565b9050602081019050919050565b828183375f83830152505050565b5f611bea611be584611b9a565b611b80565b905082815260208101848484011115611c0657611c05611b0e565b5b611c11848285611bca565b509392505050565b5f82601f830112611c2d57611c2c611b0a565b5b8135611c3d848260208601611bd8565b91505092915050565b5f60ff82169050919050565b611c5b81611c46565b8114611c65575f80fd5b50565b5f81359050611c7681611c52565b92915050565b5f805f60608486031215611c9357611c92611a4f565b5b5f84013567ffffffffffffffff811115611cb057611caf611a53565b5b611cbc86828701611c19565b935050602084013567ffffffffffffffff811115611cdd57611cdc611a53565b5b611ce986828701611c19565b9250506040611cfa86828701611c68565b9150509250925092565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611d2d82611d04565b9050919050565b611d3d81611d23565b82525050565b5f602082019050611d565f830184611d34565b92915050565b5f67ffffffffffffffff82169050919050565b611d7881611d5c565b8114611d82575f80fd5b50565b5f81359050611d9381611d6f565b92915050565b611da281611ad7565b8114611dac575f80fd5b50565b5f81359050611dbd81611d99565b92915050565b5f8060408385031215611dd957611dd8611a4f565b5b5f611de685828601611d85565b9250506020611df785828601611daf565b9150509250929050565b5f60208284031215611e1657611e15611a4f565b5b5f611e2384828501611d85565b91505092915050565b611e3581611d23565b8114611e3f575f80fd5b50565b5f81359050611e5081611e2c565b92915050565b5f819050919050565b611e6881611e56565b8114611e72575f80fd5b50565b5f81359050611e8381611e5f565b92915050565b5f805f805f60a08688031215611ea257611ea1611a4f565b5b5f86013567ffffffffffffffff811115611ebf57611ebe611a53565b5b611ecb88828901611c19565b9550506020611edc88828901611e42565b945050604086013567ffffffffffffffff811115611efd57611efc611a53565b5b611f0988828901611c19565b9350506060611f1a88828901611e75565b9250506080611f2b88828901611e75565b9150509295509295909350565b5f60208284031215611f4d57611f4c611a4f565b5b5f611f5a84828501611e42565b91505092915050565b5f805f60608486031215611f7a57611f79611a4f565b5b5f84013567ffffffffffffffff811115611f9757611f96611a53565b5b611fa386828701611c19565b9350506020611fb486828701611e42565b9250506040611fc586828701611e75565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61200182611fcf565b61200b8185611fd9565b935061201b818560208601611fe9565b61202481611b12565b840191505092915050565b61203881611c46565b82525050565b5f6060820190508181035f8301526120568186611ff7565b9050818103602083015261206a8185611ff7565b9050612079604083018461202f565b949350505050565b5f8151905061208f81611d99565b92915050565b5f602082840312156120aa576120a9611a4f565b5b5f6120b784828501612081565b91505092915050565b6120c981611e56565b82525050565b5f6060820190506120e25f830186611d34565b6120ef6020830185611d34565b6120fc60408301846120c0565b949350505050565b5f8151905061211281611c52565b92915050565b5f6020828403121561212d5761212c611a4f565b5b5f61213a84828501612104565b91505092915050565b5f6040820190506121565f830185611d34565b61216360208301846120c0565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6121a182611d5c565b91506121ac83611d5c565b9250828201905067ffffffffffffffff8111156121cc576121cb61216a565b5b92915050565b5f6121e46121df84611b9a565b611b80565b905082815260208101848484011115612200576121ff611b0e565b5b61220b848285611fe9565b509392505050565b5f82601f83011261222757612226611b0a565b5b81516122378482602086016121d2565b91505092915050565b5f6020828403121561225557612254611a4f565b5b5f82015167ffffffffffffffff81111561227257612271611a53565b5b61227e84828501612213565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806122cb57607f821691505b6020821081036122de576122dd612287565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026123407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612305565b61234a8683612305565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61238561238061237b84611e56565b612362565b611e56565b9050919050565b5f819050919050565b61239e8361236b565b6123b26123aa8261238c565b848454612311565b825550505050565b5f90565b6123c66123ba565b6123d1818484612395565b505050565b5b818110156123f4576123e95f826123be565b6001810190506123d7565b5050565b601f8211156124395761240a816122e4565b612413846122f6565b81016020851015612422578190505b61243661242e856122f6565b8301826123d6565b50505b505050565b5f82821c905092915050565b5f6124595f198460080261243e565b1980831691505092915050565b5f612471838361244a565b9150826002028217905092915050565b61248a82611fcf565b67ffffffffffffffff8111156124a3576124a2611b22565b5b6124ad82546122b4565b6124b88282856123f8565b5f60209050601f8311600181146124e9575f84156124d7578287015190505b6124e18582612466565b865550612548565b601f1984166124f7866122e4565b5f5b8281101561251e578489015182556001820191506020850194506020810190506124f9565b8683101561253b5784890151612537601f89168261244a565b8355505b6001600288020188555050505b505050505050565b5f6020820190508181035f8301526125688184611ff7565b905092915050565b5f8151905061257e81611e2c565b92915050565b5f6020828403121561259957612598611a4f565b5b5f6125a684828501612570565b91505092915050565b7f6f726967696e20746f6b656e20646f65736e27742065786973740000000000005f82015250565b5f6125e3601a83611fd9565b91506125ee826125af565b602082019050919050565b5f6020820190508181035f830152612610816125d7565b9050919050565b5f81905092915050565b5f61262b82611fcf565b6126358185612617565b9350612645818560208601611fe9565b80840191505092915050565b5f61265c8285612621565b91506126688284612621565b91508190509392505050565b5f61267e82611c46565b915061268983611c46565b9250828203905060ff8111156126a2576126a161216a565b5b92915050565b5f8160011c9050919050565b5f808291508390505b60018511156126fd578086048111156126d9576126d861216a565b5b60018516156126e85780820291505b80810290506126f6856126a8565b94506126bd565b94509492505050565b5f8261271557600190506127d0565b81612722575f90506127d0565b8160018114612738576002811461274257612771565b60019150506127d0565b60ff8411156127545761275361216a565b5b8360020a91508482111561276b5761276a61216a565b5b506127d0565b5060208310610133831016604e8410600b84101617156127a65782820a9050838111156127a1576127a061216a565b5b6127d0565b6127b384848460016126b4565b925090508184048111156127ca576127c961216a565b5b81810290505b9392505050565b5f6127e182611e56565b91506127ec83611e56565b92506128197fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484612706565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61285882611e56565b915061286383611e56565b92508261287357612872612821565b5b828204905092915050565b5f61288882611e56565b915061289383611e56565b92508282026128a181611e56565b915082820484148315176128b8576128b761216a565b5b5092915050565b7f636f6e76657274656420616d6f756e74206973207a65726f00000000000000005f82015250565b5f6128f3601883611fd9565b91506128fe826128bf565b602082019050919050565b5f6020820190508181035f830152612920816128e7565b9050919050565b7f7b224074797065223a20222f6962632e6170706c69636174696f6e732e7472615f8201527f6e736665722e76312e4d73675472616e73666572222c00000000000000000000602082015250565b5f612981603683612617565b915061298c82612927565b603682019050919050565b7f22736f757263655f706f7274223a20227472616e73666572222c0000000000005f82015250565b5f6129cb601a83612617565b91506129d682612997565b601a82019050919050565b7f22736f757263655f6368616e6e656c223a2022000000000000000000000000005f82015250565b5f612a15601383612617565b9150612a20826129e1565b601382019050919050565b7f222c0000000000000000000000000000000000000000000000000000000000005f82015250565b5f612a5f600283612617565b9150612a6a82612a2b565b600282019050919050565b7f22746f6b656e223a207b202264656e6f6d223a202200000000000000000000005f82015250565b5f612aa9601583612617565b9150612ab482612a75565b601582019050919050565b7f22616d6f756e74223a20220000000000000000000000000000000000000000005f82015250565b5f612af3600b83612617565b9150612afe82612abf565b600b82019050919050565b7f227d2c00000000000000000000000000000000000000000000000000000000005f82015250565b5f612b3d600383612617565b9150612b4882612b09565b600382019050919050565b7f2273656e646572223a20220000000000000000000000000000000000000000005f82015250565b5f612b87600b83612617565b9150612b9282612b53565b600b82019050919050565b7f227265636569766572223a2022000000000000000000000000000000000000005f82015250565b5f612bd1600d83612617565b9150612bdc82612b9d565b600d82019050919050565b7f2274696d656f75745f686569676874223a207b227265766973696f6e5f6e756d5f8201527f626572223a202230222c227265766973696f6e5f686569676874223a2022302260208201527f7d2c000000000000000000000000000000000000000000000000000000000000604082015250565b5f612c67604283612617565b9150612c7282612be7565b604282019050919050565b7f2274696d656f75745f74696d657374616d70223a2022000000000000000000005f82015250565b5f612cb1601683612617565b9150612cbc82612c7d565b601682019050919050565b7f226d656d6f223a2022222c0000000000000000000000000000000000000000005f82015250565b5f612cfb600b83612617565b9150612d0682612cc7565b600b82019050919050565b7f226173796e635f63616c6c6261636b223a207b226964223a20220000000000005f82015250565b5f612d45601a83612617565b9150612d5082612d11565b601a82019050919050565b7f22636f6e74726163745f61646472657373223a202200000000000000000000005f82015250565b5f612d8f601583612617565b9150612d9a82612d5b565b601582019050919050565b7f227d7d00000000000000000000000000000000000000000000000000000000005f82015250565b5f612dd9600383612617565b9150612de482612da5565b600382019050919050565b5f612df982612975565b9150612e04826129bf565b9150612e0f82612a09565b9150612e1b828b612621565b9150612e2682612a53565b9150612e3182612a9d565b9150612e3d828a612621565b9150612e4882612a53565b9150612e5382612ae7565b9150612e5f8289612621565b9150612e6a82612b31565b9150612e7582612b7b565b9150612e818288612621565b9150612e8c82612a53565b9150612e9782612bc5565b9150612ea38287612621565b9150612eae82612a53565b9150612eb982612c5b565b9150612ec482612ca5565b9150612ed08286612621565b9150612edb82612a53565b9150612ee682612cef565b9150612ef182612d39565b9150612efd8285612621565b9150612f0882612a53565b9150612f1382612d83565b9150612f1f8284612621565b9150612f2a82612dcd565b91508190509998505050505050505050565b5f612f4682611e56565b9150612f5183611e56565b9250828201905080821115612f6957612f6861216a565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f612fa682611e56565b91505f8203612fb857612fb761216a565b5b600182039050919050565b5f604082019050612fd65f8301856120c0565b612fe360208301846120c0565b939250505056fe608060405234801561000f575f80fd5b5060405161204338038061204383398181016040528101906100319190610235565b335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826003908161007f91906104ca565b50816004908161008f91906104ca565b508060055f6101000a81548160ff021916908360ff160217905550505050610599565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610111826100cb565b810181811067ffffffffffffffff821117156101305761012f6100db565b5b80604052505050565b5f6101426100b2565b905061014e8282610108565b919050565b5f67ffffffffffffffff82111561016d5761016c6100db565b5b610176826100cb565b9050602081019050919050565b8281835e5f83830152505050565b5f6101a361019e84610153565b610139565b9050828152602081018484840111156101bf576101be6100c7565b5b6101ca848285610183565b509392505050565b5f82601f8301126101e6576101e56100c3565b5b81516101f6848260208601610191565b91505092915050565b5f60ff82169050919050565b610214816101ff565b811461021e575f80fd5b50565b5f8151905061022f8161020b565b92915050565b5f805f6060848603121561024c5761024b6100bb565b5b5f84015167ffffffffffffffff811115610269576102686100bf565b5b610275868287016101d2565b935050602084015167ffffffffffffffff811115610296576102956100bf565b5b6102a2868287016101d2565b92505060406102b386828701610221565b9150509250925092565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061030b57607f821691505b60208210810361031e5761031d6102c7565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026103807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610345565b61038a8683610345565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6103ce6103c96103c4846103a2565b6103ab565b6103a2565b9050919050565b5f819050919050565b6103e7836103b4565b6103fb6103f3826103d5565b848454610351565b825550505050565b5f90565b61040f610403565b61041a8184846103de565b505050565b5b8181101561043d576104325f82610407565b600181019050610420565b5050565b601f8211156104825761045381610324565b61045c84610336565b8101602085101561046b578190505b61047f61047785610336565b83018261041f565b50505b505050565b5f82821c905092915050565b5f6104a25f1984600802610487565b1980831691505092915050565b5f6104ba8383610493565b9150826002028217905092915050565b6104d3826102bd565b67ffffffffffffffff8111156104ec576104eb6100db565b5b6104f682546102f4565b610501828285610441565b5f60209050601f831160018114610532575f8415610520578287015190505b61052a85826104af565b865550610591565b601f19841661054086610324565b5f5b8281101561056757848901518255600182019150602085019450602081019050610542565b868310156105845784890151610580601f891682610493565b8355505b6001600288020188555050505b505050505050565b611a9d806105a65f395ff3fe608060405234801561000f575f80fd5b5060043610610114575f3560e01c806342966c68116100a057806395d89b411161006f57806395d89b41146102f0578063a9059cbb1461030e578063dd62ed3e1461033e578063f2fde38b1461036e578063fe1195ec1461038a57610114565b806342966c681461025657806370a082311461027257806379cc6790146102a25780638da5cb5b146102d257610114565b80631988513b116100e75780631988513b146101b457806323b872dd146101d05780632d688ca814610200578063313ce5671461021c57806340c10f191461023a57610114565b806301ffc9a71461011857806306fdde0314610148578063095ea7b31461016657806318160ddd14610196575b5f80fd5b610132600480360381019061012d919061143b565b6103a6565b60405161013f9190611480565b60405180910390f35b61015061041f565b60405161015d9190611509565b60405180910390f35b610180600480360381019061017b91906115b6565b6104ab565b60405161018d9190611480565b60405180910390f35b61019e610598565b6040516101ab9190611603565b60405180910390f35b6101ce60048036038101906101c9919061161c565b61059e565b005b6101ea60048036038101906101e5919061161c565b61061d565b6040516101f79190611480565b60405180910390f35b61021a600480360381019061021591906115b6565b61077d565b005b6102246107fa565b6040516102319190611687565b60405180910390f35b610254600480360381019061024f91906115b6565b61080c565b005b610270600480360381019061026b91906116a0565b61092b565b005b61028c600480360381019061028791906116cb565b6109f3565b6040516102999190611603565b60405180910390f35b6102bc60048036038101906102b791906115b6565b610a08565b6040516102c99190611480565b60405180910390f35b6102da610b66565b6040516102e79190611705565b60405180910390f35b6102f8610b89565b6040516103059190611509565b60405180910390f35b610328600480360381019061032391906115b6565b610c15565b6040516103359190611480565b60405180910390f35b6103586004803603810190610353919061171e565b610ce6565b6040516103659190611603565b60405180910390f35b610388600480360381019061038391906116cb565b610d06565b005b6103a4600480360381019061039f91906115b6565b610e4e565b005b5f7f8da6da19000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610418575061041782610ecb565b5b9050919050565b6003805461042c90611789565b80601f016020809104026020016040519081016040528092919081815260200182805461045890611789565b80156104a35780601f1061047a576101008083540402835291602001916104a3565b820191905f5260205f20905b81548152906001019060200180831161048657829003601f168201915b505050505081565b5f8160025f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516105869190611603565b60405180910390a36001905092915050565b60065481565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461060d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060490611803565b60405180910390fd5b610618838383610f34565b505050565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016106599190611705565b602060405180830381865afa158015610674573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610698919061184b565b156106d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106cf906118e6565b60405180910390fd5b8260025f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461075f9190611931565b92505081905550610771858585610f34565b60019150509392505050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e390611803565b60405180910390fd5b6107f6828261113f565b5050565b60055f9054906101000a900460ff1681565b8160f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016108479190611705565b602060405180830381865afa158015610862573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610886919061184b565b156108c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108bd906119ae565b60405180910390fd5b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461091c575f80fd5b610926838361113f565b505050565b3360f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b81526004016109669190611705565b602060405180830381865afa158015610981573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109a5919061184b565b156109e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109dc90611a16565b60405180910390fd5b6109ef338361130e565b5050565b6001602052805f5260405f205f915090505481565b5f8260f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b8152600401610a449190611705565b602060405180830381865afa158015610a5f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a83919061184b565b15610ac3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aba90611a16565b60405180910390fd5b8260025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610b4a9190611931565b92505081905550610b5b848461130e565b600191505092915050565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60048054610b9690611789565b80601f0160208091040260200160405190810160405280929190818152602001828054610bc290611789565b8015610c0d5780601f10610be457610100808354040283529160200191610c0d565b820191905f5260205f20905b815481529060010190602001808311610bf057829003601f168201915b505050505081565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b8152600401610c519190611705565b602060405180830381865afa158015610c6c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c90919061184b565b15610cd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc7906118e6565b60405180910390fd5b610cdb338585610f34565b600191505092915050565b6002602052815f5260405f20602052805f5260405f205f91509150505481565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d5c575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d93575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ebd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb490611803565b60405180910390fd5b610ec7828261130e565b5050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b8152600401610f6f9190611705565b602060405180830381865afa158015610f8a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fae919061184b565b61102e5760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b8152600401610fec9190611705565b6020604051808303815f875af1158015611008573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061102c919061184b565b505b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461107a9190611931565b925050819055508160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546110cd9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516111319190611603565b60405180910390a350505050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b815260040161117a9190611705565b602060405180830381865afa158015611195573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b9919061184b565b6112395760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b81526004016111f79190611705565b6020604051808303815f875af1158015611213573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611237919061184b565b505b8160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546112859190611a34565b925050819055508160065f82825461129d9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516113019190611603565b60405180910390a3505050565b8060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461135a9190611931565b925050819055508060065f8282546113729190611931565b925050819055505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516113d69190611603565b60405180910390a35050565b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61141a816113e6565b8114611424575f80fd5b50565b5f8135905061143581611411565b92915050565b5f602082840312156114505761144f6113e2565b5b5f61145d84828501611427565b91505092915050565b5f8115159050919050565b61147a81611466565b82525050565b5f6020820190506114935f830184611471565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6114db82611499565b6114e581856114a3565b93506114f58185602086016114b3565b6114fe816114c1565b840191505092915050565b5f6020820190508181035f83015261152181846114d1565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61155282611529565b9050919050565b61156281611548565b811461156c575f80fd5b50565b5f8135905061157d81611559565b92915050565b5f819050919050565b61159581611583565b811461159f575f80fd5b50565b5f813590506115b08161158c565b92915050565b5f80604083850312156115cc576115cb6113e2565b5b5f6115d98582860161156f565b92505060206115ea858286016115a2565b9150509250929050565b6115fd81611583565b82525050565b5f6020820190506116165f8301846115f4565b92915050565b5f805f60608486031215611633576116326113e2565b5b5f6116408682870161156f565b93505060206116518682870161156f565b9250506040611662868287016115a2565b9150509250925092565b5f60ff82169050919050565b6116818161166c565b82525050565b5f60208201905061169a5f830184611678565b92915050565b5f602082840312156116b5576116b46113e2565b5b5f6116c2848285016115a2565b91505092915050565b5f602082840312156116e0576116df6113e2565b5b5f6116ed8482850161156f565b91505092915050565b6116ff81611548565b82525050565b5f6020820190506117185f8301846116f6565b92915050565b5f8060408385031215611734576117336113e2565b5b5f6117418582860161156f565b92505060206117528582860161156f565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806117a057607f821691505b6020821081036117b3576117b261175c565b5b50919050565b7f45524332303a2063616c6c6572206973206e6f742074686520636861696e00005f82015250565b5f6117ed601e836114a3565b91506117f8826117b9565b602082019050919050565b5f6020820190508181035f83015261181a816117e1565b9050919050565b61182a81611466565b8114611834575f80fd5b50565b5f8151905061184581611821565b92915050565b5f602082840312156118605761185f6113e2565b5b5f61186d84828501611837565b91505092915050565b7f45524332303a207472616e7366657220746f20626c6f636b65642061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f6118d06022836114a3565b91506118db82611876565b604082019050919050565b5f6020820190508181035f8301526118fd816118c4565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61193b82611583565b915061194683611583565b925082820390508181111561195e5761195d611904565b5b92915050565b7f45524332303a206d696e7420746f20626c6f636b6564206164647265737300005f82015250565b5f611998601e836114a3565b91506119a382611964565b602082019050919050565b5f6020820190508181035f8301526119c58161198c565b9050919050565b7f45524332303a206275726e2066726f6d206d6f64756c652061646472657373005f82015250565b5f611a00601f836114a3565b9150611a0b826119cc565b602082019050919050565b5f6020820190508181035f830152611a2d816119f4565b9050919050565b5f611a3e82611583565b9150611a4983611583565b9250828201905080821115611a6157611a60611904565b5b9291505056fea2646970667358221220de4043b1adb87162ffc06c0127fc335d705e04b467c9acd7522c8721ebd4c4bb64736f6c63430008190033a26469706673582212201e63799203856c1d9ca3b7a3cc0115f1473f3140b6501abeb6be28bf8ce6324964736f6c63430008190033", } // Erc20WrapperABI is the input ABI used to generate the binding from. diff --git a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol index f6f6178d..345aa1c4 100644 --- a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol +++ b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol @@ -33,6 +33,7 @@ contract ERC20Wrapper is /** * @notice This function wraps the tokens and transfer the tokens by ibc transfer + * @dev A sender requires sender approve to this contract to transfer the tokens. */ function wrap( string memory channel, @@ -42,6 +43,7 @@ contract ERC20Wrapper is uint timeout ) public { _ensureWrappedTokenExists(token); + // lock origin token IERC20(token).transferFrom(msg.sender, address(this), amount); uint wrappedAmt = _convertDecimal( @@ -53,12 +55,14 @@ contract ERC20Wrapper is ERC20(wrappedTokens[token]).mint(address(this), wrappedAmt); callBackId += 1; + // store the callback data ibcCallBack[callBackId] = IbcCallBack({ sender: msg.sender, wrappedTokenDenom: COSMOS_CONTRACT.to_denom(wrappedTokens[token]), wrappedAmt: wrappedAmt }); + // do ibc transfer wrapped token COSMOS_CONTRACT.execute_cosmos( _ibc_transfer( @@ -85,8 +89,10 @@ contract ERC20Wrapper is originTokens[wrappedToken] != address(0), "origin token doesn't exist" ); + // burn wrapped token ERC20(wrappedToken).burnFrom(msg.sender, wrappedAmt); + // unlock origin token and transfer to receiver uint amount = _convertDecimal( wrappedAmt, @@ -108,7 +114,8 @@ contract ERC20Wrapper is _handleFailedIbcTransfer(callback_id); } - // internal function // + // internal functions // + function _handleFailedIbcTransfer(uint64 callback_id) internal { IbcCallBack memory callback = ibcCallBack[callback_id]; unwrap( diff --git a/x/evm/keeper/genesis.go b/x/evm/keeper/genesis.go index f006e47b..3ededd6b 100644 --- a/x/evm/keeper/genesis.go +++ b/x/evm/keeper/genesis.go @@ -50,7 +50,7 @@ func (k Keeper) InitializeWithDecimals(ctx context.Context, decimals uint8) erro } // 3. Deploy and store the wrapper ERC20 factory contract for IBC transfers to the destination chain (not compatible due to 18 decimals). - _, wrapperAddr, _, err := k.EVMCreate2(ctx, types.StdAddress, code, nil, types.ERC20WrapperSalt) + _, wrapperAddr, _, err := k.EVMCreate2(ctx, types.StdAddress, code, nil, types.ERC20WrapperSalt, nil) if err != nil { return err } From 5e5409f7eddee05bf163689d21b8a06ca13e7e0e Mon Sep 17 00:00:00 2001 From: suha jin <89185836+djm07073@users.noreply.github.com> Date: Mon, 21 Oct 2024 14:28:55 +0900 Subject: [PATCH 5/6] fix: deploy with factory addr and add access list in readme --- app/ibc-hooks/README.md | 12 +++++- x/evm/contracts/erc20_wrapper/ERC20Wrapper.go | 39 +++++++++++++++++-- .../contracts/erc20_wrapper/ERC20Wrapper.sol | 21 +++------- x/evm/keeper/genesis.go | 17 ++++++-- x/evm/keeper/genesis_test.go | 24 ++++++++++++ 5 files changed, 89 insertions(+), 24 deletions(-) diff --git a/app/ibc-hooks/README.md b/app/ibc-hooks/README.md index 4f95b1b9..da010411 100644 --- a/app/ibc-hooks/README.md +++ b/app/ibc-hooks/README.md @@ -50,6 +50,8 @@ type MsgCall struct { Input string `protobuf:"bytes,3,opt,name=input,proto3" json:"input,omitempty"` // Value is the amount of fee denom token to transfer to the contract. Value string `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` + // AccessList is a predefined list of Ethereum addresses and their corresponding storage slots that a transaction will interact with during its execution. can be none + AccessList []AccessTuple `protobuf:"bytes,5,rep,name=access_list,json=accessList,proto3" json:"access_list"` } ``` @@ -75,6 +77,8 @@ msg := MsgCall{ Input: packet.data.memo["evm"]["message"]["input"], // Value is the amount of fee denom token to transfer to the contract. Value: packet.data.memo["evm"]["message"]["value"] + // Value is the amount of fee denom token to transfer to the contract. + AccessList: packet.data.memo["evm"]["message"]["access_list"] } ``` @@ -188,8 +192,12 @@ Also when a contract make IBC transfer request, it should provide async callback // execute message on receive packet "message": { "contract_addr": "0xerc20_wrapper_contract", // should query erc20 wrapper contract addr - "input": "pack(unwrap, denom, recipient, amount)", // function selector(fc078758) + abiCoder.encode([string,address,address],denom,amount) ref) https://docs.ethers.org/v6/api/abi/abi-coder/#AbiCoder-encode - "value": "0" + "input": "pack(unwrap, denom, recipient, amount)", // function selector(fc078758) + abiCoder.encode([string,address,address],denom,recipient,amount) ref) https://docs.ethers.org/v6/api/abi/abi-coder/#AbiCoder-encode + "value": "0", + "access_list": { + "address" : "...", // contract address + "storage_keys": ["...","..."] // storage keys of contract + } } } } diff --git a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go index 3e1fe58a..002de85e 100644 --- a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go +++ b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go @@ -31,8 +31,8 @@ var ( // Erc20WrapperMetaData contains all meta data concerning the Erc20Wrapper contract. var Erc20WrapperMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"StringsInsufficientHexLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"erc20\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"ERC20Created\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"name\":\"createERC20\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"ibc_ack\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"}],\"name\":\"ibc_timeout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"originTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"wrappedTokenDenom\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wrappedAmt\",\"type\":\"uint256\"}],\"name\":\"unwrap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"channel\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"receiver\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"wrap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"wrappedTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60806040525f8060146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055503480156036575f80fd5b50335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550615063806100835f395ff3fe608060405234801561000f575f80fd5b506004361061009c575f3560e01c80639a111432116100645780639a11143214610156578063b5ad1fb614610172578063d5c6b504146101a2578063f2fde38b146101d2578063fc078758146101ee5761009c565b806301ffc9a7146100a057806306ef1a86146100d05780630d4f1f9d1461010057806331a503f01461011c5780638da5cb5b14610138575b5f80fd5b6100ba60048036038101906100b59190611aac565b61020a565b6040516100c79190611af1565b60405180910390f35b6100ea60048036038101906100e59190611c7c565b610273565b6040516100f79190611d43565b60405180910390f35b61011a60048036038101906101159190611dc3565b6103f2565b005b61013660048036038101906101319190611e01565b610405565b005b610140610411565b60405161014d9190611d43565b60405180910390f35b610170600480360381019061016b9190611e89565b610434565b005b61018c60048036038101906101879190611f38565b6108da565b6040516101999190611d43565b60405180910390f35b6101bc60048036038101906101b79190611f38565b61090a565b6040516101c99190611d43565b60405180910390f35b6101ec60048036038101906101e79190611f38565b61093a565b005b61020860048036038101906102039190611f63565b610a82565b005b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f8084848460405161028490611a39565b6102909392919061203e565b604051809103905ff0801580156102a9573d5f803e3d5ffd5b50905060f273ffffffffffffffffffffffffffffffffffffffff1663d126274a826040518263ffffffff1660e01b81526004016102e69190611d43565b6020604051808303815f875af1158015610302573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103269190612095565b508073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b336040518263ffffffff1660e01b81526004016103609190611d43565b5f604051808303815f87803b158015610377575f80fd5b505af1158015610389573d5f803e3d5ffd5b505050503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d160405160405180910390a3809150509392505050565b806104015761040082610dfb565b5b5050565b61040e81610dfb565b50565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61043d84610f36565b8373ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b815260040161047a939291906120cf565b6020604051808303815f875af1158015610496573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104ba9190612095565b505f610534838673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610509573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061052d9190612118565b6006611259565b905060015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1930836040518363ffffffff1660e01b81526004016105cd929190612143565b5f604051808303815f87803b1580156105e4575f80fd5b505af11580156105f6573d5f803e3d5ffd5b5050505060015f60148282829054906101000a900467ffffffffffffffff1661061f9190612197565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060405180606001604052803373ffffffffffffffffffffffffffffffffffffffff16815260200160f173ffffffffffffffffffffffffffffffffffffffff166381cf0f6a60015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016107029190611d43565b5f604051808303815f875af115801561071d573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906107459190612240565b81526020018281525060035f8060149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010190816107e19190612481565b506040820151816002015590505060f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e66108758860015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685878a611328565b6040518263ffffffff1660e01b81526004016108919190612550565b6020604051808303815f875af11580156108ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108d19190612095565b50505050505050565b6002602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6001602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610990575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109c7575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60f173ffffffffffffffffffffffffffffffffffffffff16632b3324ce856040518263ffffffff1660e01b8152600401610abd9190612550565b6020604051808303815f875af1158015610ad9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610afd9190612584565b90505f73ffffffffffffffffffffffffffffffffffffffff1660025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610bc9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc0906125f9565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166379cc679033846040518363ffffffff1660e01b8152600401610c04929190612143565b6020604051808303815f875af1158015610c20573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c449190612095565b505f610d1a83600660025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cf1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d159190612118565b611259565b905060025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85836040518363ffffffff1660e01b8152600401610db3929190612143565b6020604051808303815f875af1158015610dcf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610df39190612095565b505050505050565b5f60035f8367ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f206040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182018054610e90906122b4565b80601f0160208091040260200160405190810160405280929190818152602001828054610ebc906122b4565b8015610f075780601f10610ede57610100808354040283529160200191610f07565b820191905f5260205f20905b815481529060010190602001808311610eea57829003601f168201915b505050505081526020016002820154815250509050610f328160200151825f01518360400151610a82565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff1660015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603611256575f61115c6040518060400160405280600781526020017f57726170706564000000000000000000000000000000000000000000000000008152508373ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa158015611047573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061106f9190612240565b604051602001611080929190612651565b6040516020818303038152906040526040518060400160405280600181526020017f57000000000000000000000000000000000000000000000000000000000000008152508473ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa15801561110d573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906111359190612240565b604051602001611146929190612651565b604051602081830303815290604052600661149a565b90508060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505b50565b5f8160ff168360ff16111561129a575f82846112759190612674565b60ff16600a61128491906127d7565b90508085611292919061284e565b9150506112df565b8160ff168360ff1610156112da575f83836112b59190612674565b60ff16600a6112c491906127d7565b905080856112d2919061287e565b9150506112de565b8390505b5b5f8103611321576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131890612909565b60405180910390fd5b9392505050565b60608560f173ffffffffffffffffffffffffffffffffffffffff166381cf0f6a876040518263ffffffff1660e01b81526004016113659190611d43565b5f604051808303815f875af1158015611380573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906113a89190612240565b6113b1866115b3565b60f173ffffffffffffffffffffffffffffffffffffffff16636af32a55306040518263ffffffff1660e01b81526004016113eb9190611d43565b5f604051808303815f875af1158015611406573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061142e9190612240565b85611438886115b3565b6114605f60149054906101000a900467ffffffffffffffff1667ffffffffffffffff166115b3565b6114693061167d565b604051602001611480989796959493929190612def565b604051602081830303815290604052905095945050505050565b5f808484846040516114ab90611a39565b6114b79392919061203e565b604051809103905ff0801580156114d0573d5f803e3d5ffd5b50905060f273ffffffffffffffffffffffffffffffffffffffff1663d126274a826040518263ffffffff1660e01b815260040161150d9190611d43565b6020604051808303815f875af1158015611529573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061154d9190612095565b503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d160405160405180910390a3809150509392505050565b60605f60016115c1846116aa565b0190505f8167ffffffffffffffff8111156115df576115de611b22565b5b6040519080825280601f01601f1916602001820160405280156116115781602001600182028036833780820191505090505b5090505f82602001820190505b600115611672578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161166757611666612821565b5b0494505f850361161e575b819350505050919050565b60606116a38273ffffffffffffffffffffffffffffffffffffffff16601460ff166117fb565b9050919050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611706577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816116fc576116fb612821565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611743576d04ee2d6d415b85acef8100000000838161173957611738612821565b5b0492506020810190505b662386f26fc10000831061177257662386f26fc10000838161176857611767612821565b5b0492506010810190505b6305f5e100831061179b576305f5e100838161179157611790612821565b5b0492506008810190505b61271083106117c05761271083816117b6576117b5612821565b5b0492506004810190505b606483106117e357606483816117d9576117d8612821565b5b0492506002810190505b600a83106117f2576001810190505b80915050919050565b60605f8390505f6002846002611811919061287e565b61181b9190612f3c565b67ffffffffffffffff81111561183457611833611b22565b5b6040519080825280601f01601f1916602001820160405280156118665781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f8151811061189d5761189c612f6f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611900576118ff612f6f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f600185600261193e919061287e565b6119489190612f3c565b90505b60018111156119e7577f3031323334353637383961626364656600000000000000000000000000000000600f84166010811061198a57611989612f6f565b5b1a60f81b8282815181106119a1576119a0612f6f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600483901c9250806119e090612f9c565b905061194b565b505f8214611a2e5784846040517fe22e27eb000000000000000000000000000000000000000000000000000000008152600401611a25929190612fc3565b60405180910390fd5b809250505092915050565b61204380612feb83390190565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611a8b81611a57565b8114611a95575f80fd5b50565b5f81359050611aa681611a82565b92915050565b5f60208284031215611ac157611ac0611a4f565b5b5f611ace84828501611a98565b91505092915050565b5f8115159050919050565b611aeb81611ad7565b82525050565b5f602082019050611b045f830184611ae2565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611b5882611b12565b810181811067ffffffffffffffff82111715611b7757611b76611b22565b5b80604052505050565b5f611b89611a46565b9050611b958282611b4f565b919050565b5f67ffffffffffffffff821115611bb457611bb3611b22565b5b611bbd82611b12565b9050602081019050919050565b828183375f83830152505050565b5f611bea611be584611b9a565b611b80565b905082815260208101848484011115611c0657611c05611b0e565b5b611c11848285611bca565b509392505050565b5f82601f830112611c2d57611c2c611b0a565b5b8135611c3d848260208601611bd8565b91505092915050565b5f60ff82169050919050565b611c5b81611c46565b8114611c65575f80fd5b50565b5f81359050611c7681611c52565b92915050565b5f805f60608486031215611c9357611c92611a4f565b5b5f84013567ffffffffffffffff811115611cb057611caf611a53565b5b611cbc86828701611c19565b935050602084013567ffffffffffffffff811115611cdd57611cdc611a53565b5b611ce986828701611c19565b9250506040611cfa86828701611c68565b9150509250925092565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611d2d82611d04565b9050919050565b611d3d81611d23565b82525050565b5f602082019050611d565f830184611d34565b92915050565b5f67ffffffffffffffff82169050919050565b611d7881611d5c565b8114611d82575f80fd5b50565b5f81359050611d9381611d6f565b92915050565b611da281611ad7565b8114611dac575f80fd5b50565b5f81359050611dbd81611d99565b92915050565b5f8060408385031215611dd957611dd8611a4f565b5b5f611de685828601611d85565b9250506020611df785828601611daf565b9150509250929050565b5f60208284031215611e1657611e15611a4f565b5b5f611e2384828501611d85565b91505092915050565b611e3581611d23565b8114611e3f575f80fd5b50565b5f81359050611e5081611e2c565b92915050565b5f819050919050565b611e6881611e56565b8114611e72575f80fd5b50565b5f81359050611e8381611e5f565b92915050565b5f805f805f60a08688031215611ea257611ea1611a4f565b5b5f86013567ffffffffffffffff811115611ebf57611ebe611a53565b5b611ecb88828901611c19565b9550506020611edc88828901611e42565b945050604086013567ffffffffffffffff811115611efd57611efc611a53565b5b611f0988828901611c19565b9350506060611f1a88828901611e75565b9250506080611f2b88828901611e75565b9150509295509295909350565b5f60208284031215611f4d57611f4c611a4f565b5b5f611f5a84828501611e42565b91505092915050565b5f805f60608486031215611f7a57611f79611a4f565b5b5f84013567ffffffffffffffff811115611f9757611f96611a53565b5b611fa386828701611c19565b9350506020611fb486828701611e42565b9250506040611fc586828701611e75565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61200182611fcf565b61200b8185611fd9565b935061201b818560208601611fe9565b61202481611b12565b840191505092915050565b61203881611c46565b82525050565b5f6060820190508181035f8301526120568186611ff7565b9050818103602083015261206a8185611ff7565b9050612079604083018461202f565b949350505050565b5f8151905061208f81611d99565b92915050565b5f602082840312156120aa576120a9611a4f565b5b5f6120b784828501612081565b91505092915050565b6120c981611e56565b82525050565b5f6060820190506120e25f830186611d34565b6120ef6020830185611d34565b6120fc60408301846120c0565b949350505050565b5f8151905061211281611c52565b92915050565b5f6020828403121561212d5761212c611a4f565b5b5f61213a84828501612104565b91505092915050565b5f6040820190506121565f830185611d34565b61216360208301846120c0565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6121a182611d5c565b91506121ac83611d5c565b9250828201905067ffffffffffffffff8111156121cc576121cb61216a565b5b92915050565b5f6121e46121df84611b9a565b611b80565b905082815260208101848484011115612200576121ff611b0e565b5b61220b848285611fe9565b509392505050565b5f82601f83011261222757612226611b0a565b5b81516122378482602086016121d2565b91505092915050565b5f6020828403121561225557612254611a4f565b5b5f82015167ffffffffffffffff81111561227257612271611a53565b5b61227e84828501612213565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806122cb57607f821691505b6020821081036122de576122dd612287565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026123407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612305565b61234a8683612305565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61238561238061237b84611e56565b612362565b611e56565b9050919050565b5f819050919050565b61239e8361236b565b6123b26123aa8261238c565b848454612311565b825550505050565b5f90565b6123c66123ba565b6123d1818484612395565b505050565b5b818110156123f4576123e95f826123be565b6001810190506123d7565b5050565b601f8211156124395761240a816122e4565b612413846122f6565b81016020851015612422578190505b61243661242e856122f6565b8301826123d6565b50505b505050565b5f82821c905092915050565b5f6124595f198460080261243e565b1980831691505092915050565b5f612471838361244a565b9150826002028217905092915050565b61248a82611fcf565b67ffffffffffffffff8111156124a3576124a2611b22565b5b6124ad82546122b4565b6124b88282856123f8565b5f60209050601f8311600181146124e9575f84156124d7578287015190505b6124e18582612466565b865550612548565b601f1984166124f7866122e4565b5f5b8281101561251e578489015182556001820191506020850194506020810190506124f9565b8683101561253b5784890151612537601f89168261244a565b8355505b6001600288020188555050505b505050505050565b5f6020820190508181035f8301526125688184611ff7565b905092915050565b5f8151905061257e81611e2c565b92915050565b5f6020828403121561259957612598611a4f565b5b5f6125a684828501612570565b91505092915050565b7f6f726967696e20746f6b656e20646f65736e27742065786973740000000000005f82015250565b5f6125e3601a83611fd9565b91506125ee826125af565b602082019050919050565b5f6020820190508181035f830152612610816125d7565b9050919050565b5f81905092915050565b5f61262b82611fcf565b6126358185612617565b9350612645818560208601611fe9565b80840191505092915050565b5f61265c8285612621565b91506126688284612621565b91508190509392505050565b5f61267e82611c46565b915061268983611c46565b9250828203905060ff8111156126a2576126a161216a565b5b92915050565b5f8160011c9050919050565b5f808291508390505b60018511156126fd578086048111156126d9576126d861216a565b5b60018516156126e85780820291505b80810290506126f6856126a8565b94506126bd565b94509492505050565b5f8261271557600190506127d0565b81612722575f90506127d0565b8160018114612738576002811461274257612771565b60019150506127d0565b60ff8411156127545761275361216a565b5b8360020a91508482111561276b5761276a61216a565b5b506127d0565b5060208310610133831016604e8410600b84101617156127a65782820a9050838111156127a1576127a061216a565b5b6127d0565b6127b384848460016126b4565b925090508184048111156127ca576127c961216a565b5b81810290505b9392505050565b5f6127e182611e56565b91506127ec83611e56565b92506128197fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484612706565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61285882611e56565b915061286383611e56565b92508261287357612872612821565b5b828204905092915050565b5f61288882611e56565b915061289383611e56565b92508282026128a181611e56565b915082820484148315176128b8576128b761216a565b5b5092915050565b7f636f6e76657274656420616d6f756e74206973207a65726f00000000000000005f82015250565b5f6128f3601883611fd9565b91506128fe826128bf565b602082019050919050565b5f6020820190508181035f830152612920816128e7565b9050919050565b7f7b224074797065223a20222f6962632e6170706c69636174696f6e732e7472615f8201527f6e736665722e76312e4d73675472616e73666572222c00000000000000000000602082015250565b5f612981603683612617565b915061298c82612927565b603682019050919050565b7f22736f757263655f706f7274223a20227472616e73666572222c0000000000005f82015250565b5f6129cb601a83612617565b91506129d682612997565b601a82019050919050565b7f22736f757263655f6368616e6e656c223a2022000000000000000000000000005f82015250565b5f612a15601383612617565b9150612a20826129e1565b601382019050919050565b7f222c0000000000000000000000000000000000000000000000000000000000005f82015250565b5f612a5f600283612617565b9150612a6a82612a2b565b600282019050919050565b7f22746f6b656e223a207b202264656e6f6d223a202200000000000000000000005f82015250565b5f612aa9601583612617565b9150612ab482612a75565b601582019050919050565b7f22616d6f756e74223a20220000000000000000000000000000000000000000005f82015250565b5f612af3600b83612617565b9150612afe82612abf565b600b82019050919050565b7f227d2c00000000000000000000000000000000000000000000000000000000005f82015250565b5f612b3d600383612617565b9150612b4882612b09565b600382019050919050565b7f2273656e646572223a20220000000000000000000000000000000000000000005f82015250565b5f612b87600b83612617565b9150612b9282612b53565b600b82019050919050565b7f227265636569766572223a2022000000000000000000000000000000000000005f82015250565b5f612bd1600d83612617565b9150612bdc82612b9d565b600d82019050919050565b7f2274696d656f75745f686569676874223a207b227265766973696f6e5f6e756d5f8201527f626572223a202230222c227265766973696f6e5f686569676874223a2022302260208201527f7d2c000000000000000000000000000000000000000000000000000000000000604082015250565b5f612c67604283612617565b9150612c7282612be7565b604282019050919050565b7f2274696d656f75745f74696d657374616d70223a2022000000000000000000005f82015250565b5f612cb1601683612617565b9150612cbc82612c7d565b601682019050919050565b7f226d656d6f223a2022222c0000000000000000000000000000000000000000005f82015250565b5f612cfb600b83612617565b9150612d0682612cc7565b600b82019050919050565b7f226173796e635f63616c6c6261636b223a207b226964223a20220000000000005f82015250565b5f612d45601a83612617565b9150612d5082612d11565b601a82019050919050565b7f22636f6e74726163745f61646472657373223a202200000000000000000000005f82015250565b5f612d8f601583612617565b9150612d9a82612d5b565b601582019050919050565b7f227d7d00000000000000000000000000000000000000000000000000000000005f82015250565b5f612dd9600383612617565b9150612de482612da5565b600382019050919050565b5f612df982612975565b9150612e04826129bf565b9150612e0f82612a09565b9150612e1b828b612621565b9150612e2682612a53565b9150612e3182612a9d565b9150612e3d828a612621565b9150612e4882612a53565b9150612e5382612ae7565b9150612e5f8289612621565b9150612e6a82612b31565b9150612e7582612b7b565b9150612e818288612621565b9150612e8c82612a53565b9150612e9782612bc5565b9150612ea38287612621565b9150612eae82612a53565b9150612eb982612c5b565b9150612ec482612ca5565b9150612ed08286612621565b9150612edb82612a53565b9150612ee682612cef565b9150612ef182612d39565b9150612efd8285612621565b9150612f0882612a53565b9150612f1382612d83565b9150612f1f8284612621565b9150612f2a82612dcd565b91508190509998505050505050505050565b5f612f4682611e56565b9150612f5183611e56565b9250828201905080821115612f6957612f6861216a565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f612fa682611e56565b91505f8203612fb857612fb761216a565b5b600182039050919050565b5f604082019050612fd65f8301856120c0565b612fe360208301846120c0565b939250505056fe608060405234801561000f575f80fd5b5060405161204338038061204383398181016040528101906100319190610235565b335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826003908161007f91906104ca565b50816004908161008f91906104ca565b508060055f6101000a81548160ff021916908360ff160217905550505050610599565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610111826100cb565b810181811067ffffffffffffffff821117156101305761012f6100db565b5b80604052505050565b5f6101426100b2565b905061014e8282610108565b919050565b5f67ffffffffffffffff82111561016d5761016c6100db565b5b610176826100cb565b9050602081019050919050565b8281835e5f83830152505050565b5f6101a361019e84610153565b610139565b9050828152602081018484840111156101bf576101be6100c7565b5b6101ca848285610183565b509392505050565b5f82601f8301126101e6576101e56100c3565b5b81516101f6848260208601610191565b91505092915050565b5f60ff82169050919050565b610214816101ff565b811461021e575f80fd5b50565b5f8151905061022f8161020b565b92915050565b5f805f6060848603121561024c5761024b6100bb565b5b5f84015167ffffffffffffffff811115610269576102686100bf565b5b610275868287016101d2565b935050602084015167ffffffffffffffff811115610296576102956100bf565b5b6102a2868287016101d2565b92505060406102b386828701610221565b9150509250925092565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061030b57607f821691505b60208210810361031e5761031d6102c7565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026103807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610345565b61038a8683610345565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6103ce6103c96103c4846103a2565b6103ab565b6103a2565b9050919050565b5f819050919050565b6103e7836103b4565b6103fb6103f3826103d5565b848454610351565b825550505050565b5f90565b61040f610403565b61041a8184846103de565b505050565b5b8181101561043d576104325f82610407565b600181019050610420565b5050565b601f8211156104825761045381610324565b61045c84610336565b8101602085101561046b578190505b61047f61047785610336565b83018261041f565b50505b505050565b5f82821c905092915050565b5f6104a25f1984600802610487565b1980831691505092915050565b5f6104ba8383610493565b9150826002028217905092915050565b6104d3826102bd565b67ffffffffffffffff8111156104ec576104eb6100db565b5b6104f682546102f4565b610501828285610441565b5f60209050601f831160018114610532575f8415610520578287015190505b61052a85826104af565b865550610591565b601f19841661054086610324565b5f5b8281101561056757848901518255600182019150602085019450602081019050610542565b868310156105845784890151610580601f891682610493565b8355505b6001600288020188555050505b505050505050565b611a9d806105a65f395ff3fe608060405234801561000f575f80fd5b5060043610610114575f3560e01c806342966c68116100a057806395d89b411161006f57806395d89b41146102f0578063a9059cbb1461030e578063dd62ed3e1461033e578063f2fde38b1461036e578063fe1195ec1461038a57610114565b806342966c681461025657806370a082311461027257806379cc6790146102a25780638da5cb5b146102d257610114565b80631988513b116100e75780631988513b146101b457806323b872dd146101d05780632d688ca814610200578063313ce5671461021c57806340c10f191461023a57610114565b806301ffc9a71461011857806306fdde0314610148578063095ea7b31461016657806318160ddd14610196575b5f80fd5b610132600480360381019061012d919061143b565b6103a6565b60405161013f9190611480565b60405180910390f35b61015061041f565b60405161015d9190611509565b60405180910390f35b610180600480360381019061017b91906115b6565b6104ab565b60405161018d9190611480565b60405180910390f35b61019e610598565b6040516101ab9190611603565b60405180910390f35b6101ce60048036038101906101c9919061161c565b61059e565b005b6101ea60048036038101906101e5919061161c565b61061d565b6040516101f79190611480565b60405180910390f35b61021a600480360381019061021591906115b6565b61077d565b005b6102246107fa565b6040516102319190611687565b60405180910390f35b610254600480360381019061024f91906115b6565b61080c565b005b610270600480360381019061026b91906116a0565b61092b565b005b61028c600480360381019061028791906116cb565b6109f3565b6040516102999190611603565b60405180910390f35b6102bc60048036038101906102b791906115b6565b610a08565b6040516102c99190611480565b60405180910390f35b6102da610b66565b6040516102e79190611705565b60405180910390f35b6102f8610b89565b6040516103059190611509565b60405180910390f35b610328600480360381019061032391906115b6565b610c15565b6040516103359190611480565b60405180910390f35b6103586004803603810190610353919061171e565b610ce6565b6040516103659190611603565b60405180910390f35b610388600480360381019061038391906116cb565b610d06565b005b6103a4600480360381019061039f91906115b6565b610e4e565b005b5f7f8da6da19000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610418575061041782610ecb565b5b9050919050565b6003805461042c90611789565b80601f016020809104026020016040519081016040528092919081815260200182805461045890611789565b80156104a35780601f1061047a576101008083540402835291602001916104a3565b820191905f5260205f20905b81548152906001019060200180831161048657829003601f168201915b505050505081565b5f8160025f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516105869190611603565b60405180910390a36001905092915050565b60065481565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461060d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060490611803565b60405180910390fd5b610618838383610f34565b505050565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016106599190611705565b602060405180830381865afa158015610674573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610698919061184b565b156106d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106cf906118e6565b60405180910390fd5b8260025f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461075f9190611931565b92505081905550610771858585610f34565b60019150509392505050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e390611803565b60405180910390fd5b6107f6828261113f565b5050565b60055f9054906101000a900460ff1681565b8160f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016108479190611705565b602060405180830381865afa158015610862573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610886919061184b565b156108c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108bd906119ae565b60405180910390fd5b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461091c575f80fd5b610926838361113f565b505050565b3360f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b81526004016109669190611705565b602060405180830381865afa158015610981573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109a5919061184b565b156109e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109dc90611a16565b60405180910390fd5b6109ef338361130e565b5050565b6001602052805f5260405f205f915090505481565b5f8260f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b8152600401610a449190611705565b602060405180830381865afa158015610a5f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a83919061184b565b15610ac3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aba90611a16565b60405180910390fd5b8260025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610b4a9190611931565b92505081905550610b5b848461130e565b600191505092915050565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60048054610b9690611789565b80601f0160208091040260200160405190810160405280929190818152602001828054610bc290611789565b8015610c0d5780601f10610be457610100808354040283529160200191610c0d565b820191905f5260205f20905b815481529060010190602001808311610bf057829003601f168201915b505050505081565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b8152600401610c519190611705565b602060405180830381865afa158015610c6c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c90919061184b565b15610cd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc7906118e6565b60405180910390fd5b610cdb338585610f34565b600191505092915050565b6002602052815f5260405f20602052805f5260405f205f91509150505481565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d5c575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d93575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ebd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb490611803565b60405180910390fd5b610ec7828261130e565b5050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b8152600401610f6f9190611705565b602060405180830381865afa158015610f8a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fae919061184b565b61102e5760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b8152600401610fec9190611705565b6020604051808303815f875af1158015611008573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061102c919061184b565b505b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461107a9190611931565b925050819055508160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546110cd9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516111319190611603565b60405180910390a350505050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b815260040161117a9190611705565b602060405180830381865afa158015611195573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b9919061184b565b6112395760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b81526004016111f79190611705565b6020604051808303815f875af1158015611213573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611237919061184b565b505b8160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546112859190611a34565b925050819055508160065f82825461129d9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516113019190611603565b60405180910390a3505050565b8060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461135a9190611931565b925050819055508060065f8282546113729190611931565b925050819055505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516113d69190611603565b60405180910390a35050565b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61141a816113e6565b8114611424575f80fd5b50565b5f8135905061143581611411565b92915050565b5f602082840312156114505761144f6113e2565b5b5f61145d84828501611427565b91505092915050565b5f8115159050919050565b61147a81611466565b82525050565b5f6020820190506114935f830184611471565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6114db82611499565b6114e581856114a3565b93506114f58185602086016114b3565b6114fe816114c1565b840191505092915050565b5f6020820190508181035f83015261152181846114d1565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61155282611529565b9050919050565b61156281611548565b811461156c575f80fd5b50565b5f8135905061157d81611559565b92915050565b5f819050919050565b61159581611583565b811461159f575f80fd5b50565b5f813590506115b08161158c565b92915050565b5f80604083850312156115cc576115cb6113e2565b5b5f6115d98582860161156f565b92505060206115ea858286016115a2565b9150509250929050565b6115fd81611583565b82525050565b5f6020820190506116165f8301846115f4565b92915050565b5f805f60608486031215611633576116326113e2565b5b5f6116408682870161156f565b93505060206116518682870161156f565b9250506040611662868287016115a2565b9150509250925092565b5f60ff82169050919050565b6116818161166c565b82525050565b5f60208201905061169a5f830184611678565b92915050565b5f602082840312156116b5576116b46113e2565b5b5f6116c2848285016115a2565b91505092915050565b5f602082840312156116e0576116df6113e2565b5b5f6116ed8482850161156f565b91505092915050565b6116ff81611548565b82525050565b5f6020820190506117185f8301846116f6565b92915050565b5f8060408385031215611734576117336113e2565b5b5f6117418582860161156f565b92505060206117528582860161156f565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806117a057607f821691505b6020821081036117b3576117b261175c565b5b50919050565b7f45524332303a2063616c6c6572206973206e6f742074686520636861696e00005f82015250565b5f6117ed601e836114a3565b91506117f8826117b9565b602082019050919050565b5f6020820190508181035f83015261181a816117e1565b9050919050565b61182a81611466565b8114611834575f80fd5b50565b5f8151905061184581611821565b92915050565b5f602082840312156118605761185f6113e2565b5b5f61186d84828501611837565b91505092915050565b7f45524332303a207472616e7366657220746f20626c6f636b65642061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f6118d06022836114a3565b91506118db82611876565b604082019050919050565b5f6020820190508181035f8301526118fd816118c4565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61193b82611583565b915061194683611583565b925082820390508181111561195e5761195d611904565b5b92915050565b7f45524332303a206d696e7420746f20626c6f636b6564206164647265737300005f82015250565b5f611998601e836114a3565b91506119a382611964565b602082019050919050565b5f6020820190508181035f8301526119c58161198c565b9050919050565b7f45524332303a206275726e2066726f6d206d6f64756c652061646472657373005f82015250565b5f611a00601f836114a3565b9150611a0b826119cc565b602082019050919050565b5f6020820190508181035f830152611a2d816119f4565b9050919050565b5f611a3e82611583565b9150611a4983611583565b9250828201905080821115611a6157611a60611904565b5b9291505056fea2646970667358221220de4043b1adb87162ffc06c0127fc335d705e04b467c9acd7522c8721ebd4c4bb64736f6c63430008190033a26469706673582212201e63799203856c1d9ca3b7a3cc0115f1473f3140b6501abeb6be28bf8ce6324964736f6c63430008190033", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"erc20Factory\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"StringsInsufficientHexLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"erc20\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"ERC20Created\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"name\":\"createERC20\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"factory\",\"outputs\":[{\"internalType\":\"contractERC20Factory\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"ibc_ack\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"}],\"name\":\"ibc_timeout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"originTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"wrappedTokenDenom\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wrappedAmt\",\"type\":\"uint256\"}],\"name\":\"unwrap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"channel\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"receiver\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"wrap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"wrappedTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a06040525f8060146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550348015610037575f80fd5b5060405161520e38038061520e83398181016040528101906100599190610130565b335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505061015b565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100ff826100d6565b9050919050565b61010f816100f5565b8114610119575f80fd5b50565b5f8151905061012a81610106565b92915050565b5f60208284031215610145576101446100d2565b5b5f6101528482850161011c565b91505092915050565b60805161509461017a5f395f8181610935015261101501526150945ff3fe608060405234801561000f575f80fd5b50600436106100a7575f3560e01c80639a1114321161006f5780639a11143214610161578063b5ad1fb61461017d578063c45a0155146101ad578063d5c6b504146101cb578063f2fde38b146101fb578063fc07875814610217576100a7565b806301ffc9a7146100ab57806306ef1a86146100db5780630d4f1f9d1461010b57806331a503f0146101275780638da5cb5b14610143575b5f80fd5b6100c560048036038101906100c09190611a72565b610233565b6040516100d29190611ab7565b60405180910390f35b6100f560048036038101906100f09190611c42565b61029c565b6040516101029190611d09565b60405180910390f35b61012560048036038101906101209190611d89565b61041b565b005b610141600480360381019061013c9190611dc7565b61042e565b005b61014b61043a565b6040516101589190611d09565b60405180910390f35b61017b60048036038101906101769190611e4f565b61045d565b005b61019760048036038101906101929190611efe565b610903565b6040516101a49190611d09565b60405180910390f35b6101b5610933565b6040516101c29190611f84565b60405180910390f35b6101e560048036038101906101e09190611efe565b610957565b6040516101f29190611d09565b60405180910390f35b61021560048036038101906102109190611efe565b610987565b005b610231600480360381019061022c9190611f9d565b610acf565b005b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f808484846040516102ad906119ff565b6102b993929190612078565b604051809103905ff0801580156102d2573d5f803e3d5ffd5b50905060f273ffffffffffffffffffffffffffffffffffffffff1663d126274a826040518263ffffffff1660e01b815260040161030f9190611d09565b6020604051808303815f875af115801561032b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061034f91906120cf565b508073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b336040518263ffffffff1660e01b81526004016103899190611d09565b5f604051808303815f87803b1580156103a0575f80fd5b505af11580156103b2573d5f803e3d5ffd5b505050503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d160405160405180910390a3809150509392505050565b8061042a5761042982610e48565b5b5050565b61043781610e48565b50565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61046684610f83565b8373ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b81526004016104a393929190612109565b6020604051808303815f875af11580156104bf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104e391906120cf565b505f61055d838673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610532573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105569190612152565b6006611338565b905060015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1930836040518363ffffffff1660e01b81526004016105f692919061217d565b5f604051808303815f87803b15801561060d575f80fd5b505af115801561061f573d5f803e3d5ffd5b5050505060015f60148282829054906101000a900467ffffffffffffffff1661064891906121d1565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060405180606001604052803373ffffffffffffffffffffffffffffffffffffffff16815260200160f173ffffffffffffffffffffffffffffffffffffffff166381cf0f6a60015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040161072b9190611d09565b5f604051808303815f875af1158015610746573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061076e919061227a565b81526020018281525060035f8060149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101908161080a91906124b2565b506040820151816002015590505060f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e661089e8860015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685878a611407565b6040518263ffffffff1660e01b81526004016108ba9190612581565b6020604051808303815f875af11580156108d6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108fa91906120cf565b50505050505050565b6002602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b6001602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109dd575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610a14575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60f173ffffffffffffffffffffffffffffffffffffffff16632b3324ce856040518263ffffffff1660e01b8152600401610b0a9190612581565b6020604051808303815f875af1158015610b26573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b4a91906125b5565b90505f73ffffffffffffffffffffffffffffffffffffffff1660025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610c16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0d9061262a565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166379cc679033846040518363ffffffff1660e01b8152600401610c5192919061217d565b6020604051808303815f875af1158015610c6d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9191906120cf565b505f610d6783600660025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d3e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d629190612152565b611338565b905060025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85836040518363ffffffff1660e01b8152600401610e0092919061217d565b6020604051808303815f875af1158015610e1c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e4091906120cf565b505050505050565b5f60035f8367ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f206040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182018054610edd906122ee565b80601f0160208091040260200160405190810160405280929190818152602001828054610f09906122ee565b8015610f545780601f10610f2b57610100808354040283529160200191610f54565b820191905f5260205f20905b815481529060010190602001808311610f3757829003601f168201915b505050505081526020016002820154815250509050610f7f8160200151825f01518360400151610acf565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff1660015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603611335575f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166306ef1a866040518060400160405280600781526020017f57726170706564000000000000000000000000000000000000000000000000008152508473ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa1580156110cd573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906110f5919061227a565b604051602001611106929190612682565b6040516020818303038152906040526040518060400160405280600181526020017f57000000000000000000000000000000000000000000000000000000000000008152508573ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015611193573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906111bb919061227a565b6040516020016111cc929190612682565b60405160208183030381529060405260066040518463ffffffff1660e01b81526004016111fb93929190612078565b6020604051808303815f875af1158015611217573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061123b91906125b5565b90508060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505b50565b5f8160ff168360ff161115611379575f828461135491906126a5565b60ff16600a6113639190612808565b90508085611371919061287f565b9150506113be565b8160ff168360ff1610156113b9575f838361139491906126a5565b60ff16600a6113a39190612808565b905080856113b191906128af565b9150506113bd565b8390505b5b5f8103611400576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f79061293a565b60405180910390fd5b9392505050565b60608560f173ffffffffffffffffffffffffffffffffffffffff166381cf0f6a876040518263ffffffff1660e01b81526004016114449190611d09565b5f604051808303815f875af115801561145f573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190611487919061227a565b61149086611579565b60f173ffffffffffffffffffffffffffffffffffffffff16636af32a55306040518263ffffffff1660e01b81526004016114ca9190611d09565b5f604051808303815f875af11580156114e5573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061150d919061227a565b8561151788611579565b61153f5f60149054906101000a900467ffffffffffffffff1667ffffffffffffffff16611579565b61154830611643565b60405160200161155f989796959493929190612e20565b604051602081830303815290604052905095945050505050565b60605f600161158784611670565b0190505f8167ffffffffffffffff8111156115a5576115a4611ae8565b5b6040519080825280601f01601f1916602001820160405280156115d75781602001600182028036833780820191505090505b5090505f82602001820190505b600115611638578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161162d5761162c612852565b5b0494505f85036115e4575b819350505050919050565b60606116698273ffffffffffffffffffffffffffffffffffffffff16601460ff166117c1565b9050919050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106116cc577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816116c2576116c1612852565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611709576d04ee2d6d415b85acef810000000083816116ff576116fe612852565b5b0492506020810190505b662386f26fc10000831061173857662386f26fc10000838161172e5761172d612852565b5b0492506010810190505b6305f5e1008310611761576305f5e100838161175757611756612852565b5b0492506008810190505b612710831061178657612710838161177c5761177b612852565b5b0492506004810190505b606483106117a9576064838161179f5761179e612852565b5b0492506002810190505b600a83106117b8576001810190505b80915050919050565b60605f8390505f60028460026117d791906128af565b6117e19190612f6d565b67ffffffffffffffff8111156117fa576117f9611ae8565b5b6040519080825280601f01601f19166020018201604052801561182c5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f8151811061186357611862612fa0565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106118c6576118c5612fa0565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f600185600261190491906128af565b61190e9190612f6d565b90505b60018111156119ad577f3031323334353637383961626364656600000000000000000000000000000000600f8416601081106119505761194f612fa0565b5b1a60f81b82828151811061196757611966612fa0565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600483901c9250806119a690612fcd565b9050611911565b505f82146119f45784846040517fe22e27eb0000000000000000000000000000000000000000000000000000000081526004016119eb929190612ff4565b60405180910390fd5b809250505092915050565b6120438061301c83390190565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611a5181611a1d565b8114611a5b575f80fd5b50565b5f81359050611a6c81611a48565b92915050565b5f60208284031215611a8757611a86611a15565b5b5f611a9484828501611a5e565b91505092915050565b5f8115159050919050565b611ab181611a9d565b82525050565b5f602082019050611aca5f830184611aa8565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611b1e82611ad8565b810181811067ffffffffffffffff82111715611b3d57611b3c611ae8565b5b80604052505050565b5f611b4f611a0c565b9050611b5b8282611b15565b919050565b5f67ffffffffffffffff821115611b7a57611b79611ae8565b5b611b8382611ad8565b9050602081019050919050565b828183375f83830152505050565b5f611bb0611bab84611b60565b611b46565b905082815260208101848484011115611bcc57611bcb611ad4565b5b611bd7848285611b90565b509392505050565b5f82601f830112611bf357611bf2611ad0565b5b8135611c03848260208601611b9e565b91505092915050565b5f60ff82169050919050565b611c2181611c0c565b8114611c2b575f80fd5b50565b5f81359050611c3c81611c18565b92915050565b5f805f60608486031215611c5957611c58611a15565b5b5f84013567ffffffffffffffff811115611c7657611c75611a19565b5b611c8286828701611bdf565b935050602084013567ffffffffffffffff811115611ca357611ca2611a19565b5b611caf86828701611bdf565b9250506040611cc086828701611c2e565b9150509250925092565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611cf382611cca565b9050919050565b611d0381611ce9565b82525050565b5f602082019050611d1c5f830184611cfa565b92915050565b5f67ffffffffffffffff82169050919050565b611d3e81611d22565b8114611d48575f80fd5b50565b5f81359050611d5981611d35565b92915050565b611d6881611a9d565b8114611d72575f80fd5b50565b5f81359050611d8381611d5f565b92915050565b5f8060408385031215611d9f57611d9e611a15565b5b5f611dac85828601611d4b565b9250506020611dbd85828601611d75565b9150509250929050565b5f60208284031215611ddc57611ddb611a15565b5b5f611de984828501611d4b565b91505092915050565b611dfb81611ce9565b8114611e05575f80fd5b50565b5f81359050611e1681611df2565b92915050565b5f819050919050565b611e2e81611e1c565b8114611e38575f80fd5b50565b5f81359050611e4981611e25565b92915050565b5f805f805f60a08688031215611e6857611e67611a15565b5b5f86013567ffffffffffffffff811115611e8557611e84611a19565b5b611e9188828901611bdf565b9550506020611ea288828901611e08565b945050604086013567ffffffffffffffff811115611ec357611ec2611a19565b5b611ecf88828901611bdf565b9350506060611ee088828901611e3b565b9250506080611ef188828901611e3b565b9150509295509295909350565b5f60208284031215611f1357611f12611a15565b5b5f611f2084828501611e08565b91505092915050565b5f819050919050565b5f611f4c611f47611f4284611cca565b611f29565b611cca565b9050919050565b5f611f5d82611f32565b9050919050565b5f611f6e82611f53565b9050919050565b611f7e81611f64565b82525050565b5f602082019050611f975f830184611f75565b92915050565b5f805f60608486031215611fb457611fb3611a15565b5b5f84013567ffffffffffffffff811115611fd157611fd0611a19565b5b611fdd86828701611bdf565b9350506020611fee86828701611e08565b9250506040611fff86828701611e3b565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61203b82612009565b6120458185612013565b9350612055818560208601612023565b61205e81611ad8565b840191505092915050565b61207281611c0c565b82525050565b5f6060820190508181035f8301526120908186612031565b905081810360208301526120a48185612031565b90506120b36040830184612069565b949350505050565b5f815190506120c981611d5f565b92915050565b5f602082840312156120e4576120e3611a15565b5b5f6120f1848285016120bb565b91505092915050565b61210381611e1c565b82525050565b5f60608201905061211c5f830186611cfa565b6121296020830185611cfa565b61213660408301846120fa565b949350505050565b5f8151905061214c81611c18565b92915050565b5f6020828403121561216757612166611a15565b5b5f6121748482850161213e565b91505092915050565b5f6040820190506121905f830185611cfa565b61219d60208301846120fa565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6121db82611d22565b91506121e683611d22565b9250828201905067ffffffffffffffff811115612206576122056121a4565b5b92915050565b5f61221e61221984611b60565b611b46565b90508281526020810184848401111561223a57612239611ad4565b5b612245848285612023565b509392505050565b5f82601f83011261226157612260611ad0565b5b815161227184826020860161220c565b91505092915050565b5f6020828403121561228f5761228e611a15565b5b5f82015167ffffffffffffffff8111156122ac576122ab611a19565b5b6122b88482850161224d565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061230557607f821691505b602082108103612318576123176122c1565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261237a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261233f565b612384868361233f565b95508019841693508086168417925050509392505050565b5f6123b66123b16123ac84611e1c565b611f29565b611e1c565b9050919050565b5f819050919050565b6123cf8361239c565b6123e36123db826123bd565b84845461234b565b825550505050565b5f90565b6123f76123eb565b6124028184846123c6565b505050565b5b818110156124255761241a5f826123ef565b600181019050612408565b5050565b601f82111561246a5761243b8161231e565b61244484612330565b81016020851015612453578190505b61246761245f85612330565b830182612407565b50505b505050565b5f82821c905092915050565b5f61248a5f198460080261246f565b1980831691505092915050565b5f6124a2838361247b565b9150826002028217905092915050565b6124bb82612009565b67ffffffffffffffff8111156124d4576124d3611ae8565b5b6124de82546122ee565b6124e9828285612429565b5f60209050601f83116001811461251a575f8415612508578287015190505b6125128582612497565b865550612579565b601f1984166125288661231e565b5f5b8281101561254f5784890151825560018201915060208501945060208101905061252a565b8683101561256c5784890151612568601f89168261247b565b8355505b6001600288020188555050505b505050505050565b5f6020820190508181035f8301526125998184612031565b905092915050565b5f815190506125af81611df2565b92915050565b5f602082840312156125ca576125c9611a15565b5b5f6125d7848285016125a1565b91505092915050565b7f6f726967696e20746f6b656e20646f65736e27742065786973740000000000005f82015250565b5f612614601a83612013565b915061261f826125e0565b602082019050919050565b5f6020820190508181035f83015261264181612608565b9050919050565b5f81905092915050565b5f61265c82612009565b6126668185612648565b9350612676818560208601612023565b80840191505092915050565b5f61268d8285612652565b91506126998284612652565b91508190509392505050565b5f6126af82611c0c565b91506126ba83611c0c565b9250828203905060ff8111156126d3576126d26121a4565b5b92915050565b5f8160011c9050919050565b5f808291508390505b600185111561272e5780860481111561270a576127096121a4565b5b60018516156127195780820291505b8081029050612727856126d9565b94506126ee565b94509492505050565b5f826127465760019050612801565b81612753575f9050612801565b81600181146127695760028114612773576127a2565b6001915050612801565b60ff841115612785576127846121a4565b5b8360020a91508482111561279c5761279b6121a4565b5b50612801565b5060208310610133831016604e8410600b84101617156127d75782820a9050838111156127d2576127d16121a4565b5b612801565b6127e484848460016126e5565b925090508184048111156127fb576127fa6121a4565b5b81810290505b9392505050565b5f61281282611e1c565b915061281d83611e1c565b925061284a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484612737565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61288982611e1c565b915061289483611e1c565b9250826128a4576128a3612852565b5b828204905092915050565b5f6128b982611e1c565b91506128c483611e1c565b92508282026128d281611e1c565b915082820484148315176128e9576128e86121a4565b5b5092915050565b7f636f6e76657274656420616d6f756e74206973207a65726f00000000000000005f82015250565b5f612924601883612013565b915061292f826128f0565b602082019050919050565b5f6020820190508181035f83015261295181612918565b9050919050565b7f7b224074797065223a20222f6962632e6170706c69636174696f6e732e7472615f8201527f6e736665722e76312e4d73675472616e73666572222c00000000000000000000602082015250565b5f6129b2603683612648565b91506129bd82612958565b603682019050919050565b7f22736f757263655f706f7274223a20227472616e73666572222c0000000000005f82015250565b5f6129fc601a83612648565b9150612a07826129c8565b601a82019050919050565b7f22736f757263655f6368616e6e656c223a2022000000000000000000000000005f82015250565b5f612a46601383612648565b9150612a5182612a12565b601382019050919050565b7f222c0000000000000000000000000000000000000000000000000000000000005f82015250565b5f612a90600283612648565b9150612a9b82612a5c565b600282019050919050565b7f22746f6b656e223a207b202264656e6f6d223a202200000000000000000000005f82015250565b5f612ada601583612648565b9150612ae582612aa6565b601582019050919050565b7f22616d6f756e74223a20220000000000000000000000000000000000000000005f82015250565b5f612b24600b83612648565b9150612b2f82612af0565b600b82019050919050565b7f227d2c00000000000000000000000000000000000000000000000000000000005f82015250565b5f612b6e600383612648565b9150612b7982612b3a565b600382019050919050565b7f2273656e646572223a20220000000000000000000000000000000000000000005f82015250565b5f612bb8600b83612648565b9150612bc382612b84565b600b82019050919050565b7f227265636569766572223a2022000000000000000000000000000000000000005f82015250565b5f612c02600d83612648565b9150612c0d82612bce565b600d82019050919050565b7f2274696d656f75745f686569676874223a207b227265766973696f6e5f6e756d5f8201527f626572223a202230222c227265766973696f6e5f686569676874223a2022302260208201527f7d2c000000000000000000000000000000000000000000000000000000000000604082015250565b5f612c98604283612648565b9150612ca382612c18565b604282019050919050565b7f2274696d656f75745f74696d657374616d70223a2022000000000000000000005f82015250565b5f612ce2601683612648565b9150612ced82612cae565b601682019050919050565b7f226d656d6f223a2022222c0000000000000000000000000000000000000000005f82015250565b5f612d2c600b83612648565b9150612d3782612cf8565b600b82019050919050565b7f226173796e635f63616c6c6261636b223a207b226964223a20220000000000005f82015250565b5f612d76601a83612648565b9150612d8182612d42565b601a82019050919050565b7f22636f6e74726163745f61646472657373223a202200000000000000000000005f82015250565b5f612dc0601583612648565b9150612dcb82612d8c565b601582019050919050565b7f227d7d00000000000000000000000000000000000000000000000000000000005f82015250565b5f612e0a600383612648565b9150612e1582612dd6565b600382019050919050565b5f612e2a826129a6565b9150612e35826129f0565b9150612e4082612a3a565b9150612e4c828b612652565b9150612e5782612a84565b9150612e6282612ace565b9150612e6e828a612652565b9150612e7982612a84565b9150612e8482612b18565b9150612e908289612652565b9150612e9b82612b62565b9150612ea682612bac565b9150612eb28288612652565b9150612ebd82612a84565b9150612ec882612bf6565b9150612ed48287612652565b9150612edf82612a84565b9150612eea82612c8c565b9150612ef582612cd6565b9150612f018286612652565b9150612f0c82612a84565b9150612f1782612d20565b9150612f2282612d6a565b9150612f2e8285612652565b9150612f3982612a84565b9150612f4482612db4565b9150612f508284612652565b9150612f5b82612dfe565b91508190509998505050505050505050565b5f612f7782611e1c565b9150612f8283611e1c565b9250828201905080821115612f9a57612f996121a4565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f612fd782611e1c565b91505f8203612fe957612fe86121a4565b5b600182039050919050565b5f6040820190506130075f8301856120fa565b61301460208301846120fa565b939250505056fe608060405234801561000f575f80fd5b5060405161204338038061204383398181016040528101906100319190610235565b335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826003908161007f91906104ca565b50816004908161008f91906104ca565b508060055f6101000a81548160ff021916908360ff160217905550505050610599565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610111826100cb565b810181811067ffffffffffffffff821117156101305761012f6100db565b5b80604052505050565b5f6101426100b2565b905061014e8282610108565b919050565b5f67ffffffffffffffff82111561016d5761016c6100db565b5b610176826100cb565b9050602081019050919050565b8281835e5f83830152505050565b5f6101a361019e84610153565b610139565b9050828152602081018484840111156101bf576101be6100c7565b5b6101ca848285610183565b509392505050565b5f82601f8301126101e6576101e56100c3565b5b81516101f6848260208601610191565b91505092915050565b5f60ff82169050919050565b610214816101ff565b811461021e575f80fd5b50565b5f8151905061022f8161020b565b92915050565b5f805f6060848603121561024c5761024b6100bb565b5b5f84015167ffffffffffffffff811115610269576102686100bf565b5b610275868287016101d2565b935050602084015167ffffffffffffffff811115610296576102956100bf565b5b6102a2868287016101d2565b92505060406102b386828701610221565b9150509250925092565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061030b57607f821691505b60208210810361031e5761031d6102c7565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026103807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610345565b61038a8683610345565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6103ce6103c96103c4846103a2565b6103ab565b6103a2565b9050919050565b5f819050919050565b6103e7836103b4565b6103fb6103f3826103d5565b848454610351565b825550505050565b5f90565b61040f610403565b61041a8184846103de565b505050565b5b8181101561043d576104325f82610407565b600181019050610420565b5050565b601f8211156104825761045381610324565b61045c84610336565b8101602085101561046b578190505b61047f61047785610336565b83018261041f565b50505b505050565b5f82821c905092915050565b5f6104a25f1984600802610487565b1980831691505092915050565b5f6104ba8383610493565b9150826002028217905092915050565b6104d3826102bd565b67ffffffffffffffff8111156104ec576104eb6100db565b5b6104f682546102f4565b610501828285610441565b5f60209050601f831160018114610532575f8415610520578287015190505b61052a85826104af565b865550610591565b601f19841661054086610324565b5f5b8281101561056757848901518255600182019150602085019450602081019050610542565b868310156105845784890151610580601f891682610493565b8355505b6001600288020188555050505b505050505050565b611a9d806105a65f395ff3fe608060405234801561000f575f80fd5b5060043610610114575f3560e01c806342966c68116100a057806395d89b411161006f57806395d89b41146102f0578063a9059cbb1461030e578063dd62ed3e1461033e578063f2fde38b1461036e578063fe1195ec1461038a57610114565b806342966c681461025657806370a082311461027257806379cc6790146102a25780638da5cb5b146102d257610114565b80631988513b116100e75780631988513b146101b457806323b872dd146101d05780632d688ca814610200578063313ce5671461021c57806340c10f191461023a57610114565b806301ffc9a71461011857806306fdde0314610148578063095ea7b31461016657806318160ddd14610196575b5f80fd5b610132600480360381019061012d919061143b565b6103a6565b60405161013f9190611480565b60405180910390f35b61015061041f565b60405161015d9190611509565b60405180910390f35b610180600480360381019061017b91906115b6565b6104ab565b60405161018d9190611480565b60405180910390f35b61019e610598565b6040516101ab9190611603565b60405180910390f35b6101ce60048036038101906101c9919061161c565b61059e565b005b6101ea60048036038101906101e5919061161c565b61061d565b6040516101f79190611480565b60405180910390f35b61021a600480360381019061021591906115b6565b61077d565b005b6102246107fa565b6040516102319190611687565b60405180910390f35b610254600480360381019061024f91906115b6565b61080c565b005b610270600480360381019061026b91906116a0565b61092b565b005b61028c600480360381019061028791906116cb565b6109f3565b6040516102999190611603565b60405180910390f35b6102bc60048036038101906102b791906115b6565b610a08565b6040516102c99190611480565b60405180910390f35b6102da610b66565b6040516102e79190611705565b60405180910390f35b6102f8610b89565b6040516103059190611509565b60405180910390f35b610328600480360381019061032391906115b6565b610c15565b6040516103359190611480565b60405180910390f35b6103586004803603810190610353919061171e565b610ce6565b6040516103659190611603565b60405180910390f35b610388600480360381019061038391906116cb565b610d06565b005b6103a4600480360381019061039f91906115b6565b610e4e565b005b5f7f8da6da19000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610418575061041782610ecb565b5b9050919050565b6003805461042c90611789565b80601f016020809104026020016040519081016040528092919081815260200182805461045890611789565b80156104a35780601f1061047a576101008083540402835291602001916104a3565b820191905f5260205f20905b81548152906001019060200180831161048657829003601f168201915b505050505081565b5f8160025f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516105869190611603565b60405180910390a36001905092915050565b60065481565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461060d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060490611803565b60405180910390fd5b610618838383610f34565b505050565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016106599190611705565b602060405180830381865afa158015610674573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610698919061184b565b156106d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106cf906118e6565b60405180910390fd5b8260025f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461075f9190611931565b92505081905550610771858585610f34565b60019150509392505050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e390611803565b60405180910390fd5b6107f6828261113f565b5050565b60055f9054906101000a900460ff1681565b8160f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016108479190611705565b602060405180830381865afa158015610862573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610886919061184b565b156108c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108bd906119ae565b60405180910390fd5b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461091c575f80fd5b610926838361113f565b505050565b3360f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b81526004016109669190611705565b602060405180830381865afa158015610981573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109a5919061184b565b156109e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109dc90611a16565b60405180910390fd5b6109ef338361130e565b5050565b6001602052805f5260405f205f915090505481565b5f8260f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b8152600401610a449190611705565b602060405180830381865afa158015610a5f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a83919061184b565b15610ac3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aba90611a16565b60405180910390fd5b8260025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610b4a9190611931565b92505081905550610b5b848461130e565b600191505092915050565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60048054610b9690611789565b80601f0160208091040260200160405190810160405280929190818152602001828054610bc290611789565b8015610c0d5780601f10610be457610100808354040283529160200191610c0d565b820191905f5260205f20905b815481529060010190602001808311610bf057829003601f168201915b505050505081565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b8152600401610c519190611705565b602060405180830381865afa158015610c6c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c90919061184b565b15610cd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc7906118e6565b60405180910390fd5b610cdb338585610f34565b600191505092915050565b6002602052815f5260405f20602052805f5260405f205f91509150505481565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d5c575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d93575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ebd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb490611803565b60405180910390fd5b610ec7828261130e565b5050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b8152600401610f6f9190611705565b602060405180830381865afa158015610f8a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fae919061184b565b61102e5760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b8152600401610fec9190611705565b6020604051808303815f875af1158015611008573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061102c919061184b565b505b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461107a9190611931565b925050819055508160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546110cd9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516111319190611603565b60405180910390a350505050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b815260040161117a9190611705565b602060405180830381865afa158015611195573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b9919061184b565b6112395760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b81526004016111f79190611705565b6020604051808303815f875af1158015611213573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611237919061184b565b505b8160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546112859190611a34565b925050819055508160065f82825461129d9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516113019190611603565b60405180910390a3505050565b8060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461135a9190611931565b925050819055508060065f8282546113729190611931565b925050819055505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516113d69190611603565b60405180910390a35050565b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61141a816113e6565b8114611424575f80fd5b50565b5f8135905061143581611411565b92915050565b5f602082840312156114505761144f6113e2565b5b5f61145d84828501611427565b91505092915050565b5f8115159050919050565b61147a81611466565b82525050565b5f6020820190506114935f830184611471565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6114db82611499565b6114e581856114a3565b93506114f58185602086016114b3565b6114fe816114c1565b840191505092915050565b5f6020820190508181035f83015261152181846114d1565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61155282611529565b9050919050565b61156281611548565b811461156c575f80fd5b50565b5f8135905061157d81611559565b92915050565b5f819050919050565b61159581611583565b811461159f575f80fd5b50565b5f813590506115b08161158c565b92915050565b5f80604083850312156115cc576115cb6113e2565b5b5f6115d98582860161156f565b92505060206115ea858286016115a2565b9150509250929050565b6115fd81611583565b82525050565b5f6020820190506116165f8301846115f4565b92915050565b5f805f60608486031215611633576116326113e2565b5b5f6116408682870161156f565b93505060206116518682870161156f565b9250506040611662868287016115a2565b9150509250925092565b5f60ff82169050919050565b6116818161166c565b82525050565b5f60208201905061169a5f830184611678565b92915050565b5f602082840312156116b5576116b46113e2565b5b5f6116c2848285016115a2565b91505092915050565b5f602082840312156116e0576116df6113e2565b5b5f6116ed8482850161156f565b91505092915050565b6116ff81611548565b82525050565b5f6020820190506117185f8301846116f6565b92915050565b5f8060408385031215611734576117336113e2565b5b5f6117418582860161156f565b92505060206117528582860161156f565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806117a057607f821691505b6020821081036117b3576117b261175c565b5b50919050565b7f45524332303a2063616c6c6572206973206e6f742074686520636861696e00005f82015250565b5f6117ed601e836114a3565b91506117f8826117b9565b602082019050919050565b5f6020820190508181035f83015261181a816117e1565b9050919050565b61182a81611466565b8114611834575f80fd5b50565b5f8151905061184581611821565b92915050565b5f602082840312156118605761185f6113e2565b5b5f61186d84828501611837565b91505092915050565b7f45524332303a207472616e7366657220746f20626c6f636b65642061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f6118d06022836114a3565b91506118db82611876565b604082019050919050565b5f6020820190508181035f8301526118fd816118c4565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61193b82611583565b915061194683611583565b925082820390508181111561195e5761195d611904565b5b92915050565b7f45524332303a206d696e7420746f20626c6f636b6564206164647265737300005f82015250565b5f611998601e836114a3565b91506119a382611964565b602082019050919050565b5f6020820190508181035f8301526119c58161198c565b9050919050565b7f45524332303a206275726e2066726f6d206d6f64756c652061646472657373005f82015250565b5f611a00601f836114a3565b9150611a0b826119cc565b602082019050919050565b5f6020820190508181035f830152611a2d816119f4565b9050919050565b5f611a3e82611583565b9150611a4983611583565b9250828201905080821115611a6157611a60611904565b5b9291505056fea2646970667358221220de4043b1adb87162ffc06c0127fc335d705e04b467c9acd7522c8721ebd4c4bb64736f6c63430008190033a2646970667358221220b60b16dbb873bc70c6d83f4f9c9822c78b2d692f5c12918ad733994c055bb7b664736f6c63430008190033", } // Erc20WrapperABI is the input ABI used to generate the binding from. @@ -44,7 +44,7 @@ var Erc20WrapperABI = Erc20WrapperMetaData.ABI var Erc20WrapperBin = Erc20WrapperMetaData.Bin // DeployErc20Wrapper deploys a new Ethereum contract, binding an instance of Erc20Wrapper to it. -func DeployErc20Wrapper(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Erc20Wrapper, error) { +func DeployErc20Wrapper(auth *bind.TransactOpts, backend bind.ContractBackend, erc20Factory common.Address) (common.Address, *types.Transaction, *Erc20Wrapper, error) { parsed, err := Erc20WrapperMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -53,7 +53,7 @@ func DeployErc20Wrapper(auth *bind.TransactOpts, backend bind.ContractBackend) ( return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(Erc20WrapperBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(Erc20WrapperBin), backend, erc20Factory) if err != nil { return common.Address{}, nil, nil, err } @@ -202,6 +202,37 @@ func (_Erc20Wrapper *Erc20WrapperTransactorRaw) Transact(opts *bind.TransactOpts return _Erc20Wrapper.Contract.contract.Transact(opts, method, params...) } +// Factory is a free data retrieval call binding the contract method 0xc45a0155. +// +// Solidity: function factory() view returns(address) +func (_Erc20Wrapper *Erc20WrapperCaller) Factory(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Erc20Wrapper.contract.Call(opts, &out, "factory") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Factory is a free data retrieval call binding the contract method 0xc45a0155. +// +// Solidity: function factory() view returns(address) +func (_Erc20Wrapper *Erc20WrapperSession) Factory() (common.Address, error) { + return _Erc20Wrapper.Contract.Factory(&_Erc20Wrapper.CallOpts) +} + +// Factory is a free data retrieval call binding the contract method 0xc45a0155. +// +// Solidity: function factory() view returns(address) +func (_Erc20Wrapper *Erc20WrapperCallerSession) Factory() (common.Address, error) { + return _Erc20Wrapper.Contract.Factory(&_Erc20Wrapper.CallOpts) +} + // OriginTokens is a free data retrieval call binding the contract method 0xb5ad1fb6. // // Solidity: function originTokens(address ) view returns(address) diff --git a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol index 345aa1c4..106a8bad 100644 --- a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol +++ b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol @@ -27,10 +27,15 @@ contract ERC20Wrapper is string constant NAME_PREFIX = "Wrapped"; string constant SYMBOL_PREFIX = "W"; uint64 callBackId = 0; + ERC20Factory public immutable factory; mapping(address => address) public wrappedTokens; // origin -> wrapped mapping(address => address) public originTokens; // wrapped -> origin mapping(uint64 => IbcCallBack) private ibcCallBack; // id -> CallBackInfo + constructor(address erc20Factory) { + factory = ERC20Factory(erc20Factory); + } + /** * @notice This function wraps the tokens and transfer the tokens by ibc transfer * @dev A sender requires sender approve to this contract to transfer the tokens. @@ -125,23 +130,9 @@ contract ERC20Wrapper is ); } - function _createERC20( - string memory name, - string memory symbol, - uint8 decimals - ) internal returns (address) { - ERC20 erc20 = new ERC20(name, symbol, decimals); - - // register the ERC20 contract with the ERC20 registry - ERC20_REGISTRY_CONTRACT.register_erc20_from_factory(address(erc20)); - - emit ERC20Created(address(erc20), address(this)); - return address(erc20); - } - function _ensureWrappedTokenExists(address token) internal { if (wrappedTokens[token] == address(0)) { - address wrappedToken = _createERC20( + address wrappedToken = factory.createERC20( string.concat(NAME_PREFIX, IERC20(token).name()), string.concat(SYMBOL_PREFIX, IERC20(token).symbol()), WRAPPED_DECIMAL diff --git a/x/evm/keeper/genesis.go b/x/evm/keeper/genesis.go index 3ededd6b..bfc7ac0a 100644 --- a/x/evm/keeper/genesis.go +++ b/x/evm/keeper/genesis.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/initia-labs/minievm/x/evm/contracts/erc20_factory" + "github.com/initia-labs/minievm/x/evm/contracts/erc20_wrapper" "github.com/initia-labs/minievm/x/evm/types" ) @@ -23,12 +24,12 @@ func (k Keeper) Initialize(ctx context.Context) error { // InitializeWithDecimals initializes the EVM state at genesis with the given decimals func (k Keeper) InitializeWithDecimals(ctx context.Context, decimals uint8) error { // 1. Deploy and store the ERC20 factory contract. - code, err := hexutil.Decode(erc20_factory.Erc20FactoryBin) + factoryCode, err := hexutil.Decode(erc20_factory.Erc20FactoryBin) if err != nil { return err } - _, factoryAddr, _, err := k.EVMCreate2(ctx, types.StdAddress, code, nil, types.ERC20FactorySalt, nil) + _, factoryAddr, _, err := k.EVMCreate2(ctx, types.StdAddress, factoryCode, nil, types.ERC20FactorySalt, nil) if err != nil { return err } @@ -50,7 +51,17 @@ func (k Keeper) InitializeWithDecimals(ctx context.Context, decimals uint8) erro } // 3. Deploy and store the wrapper ERC20 factory contract for IBC transfers to the destination chain (not compatible due to 18 decimals). - _, wrapperAddr, _, err := k.EVMCreate2(ctx, types.StdAddress, code, nil, types.ERC20WrapperSalt, nil) + wrapperCode, err := hexutil.Decode(erc20_wrapper.Erc20WrapperBin) + if err != nil { + return err + } + abi, _ := erc20_wrapper.Erc20WrapperMetaData.GetAbi() + wrapperConstructorArg, err := abi.Constructor.Inputs.Pack(factoryAddr) + if err != nil { + return err + } + + _, wrapperAddr, _, err := k.EVMCreate2(ctx, types.StdAddress, append(wrapperCode, wrapperConstructorArg...), nil, types.ERC20WrapperSalt, nil) if err != nil { return err } diff --git a/x/evm/keeper/genesis_test.go b/x/evm/keeper/genesis_test.go index 94985518..54f4c2b4 100644 --- a/x/evm/keeper/genesis_test.go +++ b/x/evm/keeper/genesis_test.go @@ -3,6 +3,8 @@ package keeper_test import ( "testing" + "github.com/ethereum/go-ethereum/common" + "github.com/initia-labs/minievm/x/evm/contracts/erc20_wrapper" "github.com/initia-labs/minievm/x/evm/types" "github.com/stretchr/testify/require" ) @@ -79,3 +81,25 @@ func Test_Genesis(t *testing.T) { _genState := input.EVMKeeper.ExportGenesis(ctx) require.Equal(t, genState, _genState) } + +func Test_Initialize(t *testing.T) { + ctx, input := createTestInput(t, false, true) + wrapperAddr, err := input.EVMKeeper.GetERC20WrapperAddr(ctx) + require.NoError(t, err) + + caller := common.HexToAddress("0x0") + abi, err := erc20_wrapper.Erc20WrapperMetaData.GetAbi() + require.NoError(t, err) + + viewArg, err := abi.Pack("factory") + require.NoError(t, err) + + factoryAddrBytes, err := input.EVMKeeper.EVMStaticCall(ctx, caller, wrapperAddr, viewArg, nil) + require.NoError(t, err) + + factoryAddr := common.BytesToAddress(factoryAddrBytes) + expectedFactoryAddr, err := input.EVMKeeper.GetERC20FactoryAddr(ctx) + require.NoError(t, err) + + require.Equal(t, expectedFactoryAddr, factoryAddr) +} From 66530aaf7baeb7e539220c61d56075c81ad60e3b Mon Sep 17 00:00:00 2001 From: beer-1 Date: Tue, 22 Oct 2024 10:10:22 +0900 Subject: [PATCH 6/6] add missing readme --- app/ibc-hooks/README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/ibc-hooks/README.md b/app/ibc-hooks/README.md index da010411..a355b335 100644 --- a/app/ibc-hooks/README.md +++ b/app/ibc-hooks/README.md @@ -53,6 +53,14 @@ type MsgCall struct { // AccessList is a predefined list of Ethereum addresses and their corresponding storage slots that a transaction will interact with during its execution. can be none AccessList []AccessTuple `protobuf:"bytes,5,rep,name=access_list,json=accessList,proto3" json:"access_list"` } + +type AccessTuple struct { + // Address of the contract that will be accessed during the transaction execution. + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + // A list of storage keys that the transaction will interact with within the specified contract. + // These keys represent specific storage slots in the contract's storage that are accessed or modified. + StorageKeys []string `protobuf:"bytes,2,rep,name=storage_keys,json=storageKeys,proto3" json:"storage_keys,omitempty"` +} ``` So we detail where we want to get each of these fields from: @@ -101,7 +109,11 @@ ICS20 is JSON native, so we use JSON for the memo format. "message": { "contract_addr": "0x1", "input": "hex encoded byte string", - "value": "0" + "value": "0", + "access_list": { + "address" : "0x1", // contract address + "storage_keys": ["0xabc","0xdef"] // storage keys of contract + } }, // optional field to get async callback (ack and timeout) "async_callback": { @@ -119,7 +131,7 @@ An ICS20 packet is formatted correctly for evmhooks iff the following all hold: - `memo` is not blank - `memo` is valid JSON - `memo` has at least one key, with value `"evm"` -- `memo["evm"]["message"]` has exactly 3 entries, `"contract_addr"`, `"input"`, `"value"` +- `memo["evm"]["message"]` has exactly 4 entries, `"contract_addr"`, `"input"`, `"value"`, `"access_list"` - `receiver` == "" || `receiver` == "module_address::module_name::function_name" We consider an ICS20 packet as directed towards evmhooks iff all of the following hold: