diff --git a/contracts/orderbook/hts/ExchangeHTS.sol b/contracts/orderbook/hts/ExchangeHTS.sol index 38cf0ca..d3e0a3b 100644 --- a/contracts/orderbook/hts/ExchangeHTS.sol +++ b/contracts/orderbook/hts/ExchangeHTS.sol @@ -38,7 +38,7 @@ contract ExchangeHTS is OrderBookHTS, ReentrancyGuard { _insertBuyOrder(msg.sender, price, remainVolume); } - return 0; + return currentOrderId; } /** diff --git a/contracts/orderbook/hts/OrderBookHTS.sol b/contracts/orderbook/hts/OrderBookHTS.sol index ea06415..603af9b 100644 --- a/contracts/orderbook/hts/OrderBookHTS.sol +++ b/contracts/orderbook/hts/OrderBookHTS.sol @@ -17,9 +17,9 @@ abstract contract OrderBookHTS { event Trade(int64 tradedVolume, int64 price, address buyer, address seller); event NewOrder(bool isBuy, uint256 orderId, address trader, int64 price, int64 volume); - event Deposit(address indexed trader, address token, int64 amount); + event Deposit(address trader, address token, int64 amount); event Withdraw(address trader, address token, int64 amount); - event OrderCanceled(bool isBuy, uint256 indexed orderId, address indexed trader); + event OrderCanceled(bool isBuy, uint256 orderId, address trader); struct Order { uint256 id; @@ -93,8 +93,10 @@ abstract contract OrderBookHTS { int64 sellVolume ) internal returns (int64) { uint256 currentBuyId = firstBuyOrderId; + uint256 maxIterations = 10; // Define a maximum number of iterations per call + uint256 iterations = 0; - while (currentBuyId != 0 && sellVolume > 0) { + while (currentBuyId != 0 && sellVolume > 0 && iterations < maxIterations) { Order storage buyOrder = buyOrders[currentBuyId]; if (sellPrice <= buyOrder.price) { @@ -118,6 +120,7 @@ abstract contract OrderBookHTS { } else { break; } + iterations++; } firstBuyOrderId = currentBuyId; // Update the first buy order ID @@ -130,8 +133,10 @@ abstract contract OrderBookHTS { int64 buyVolume ) internal returns (int64) { uint256 currentSellId = firstSellOrderId; + uint256 maxIterations = 10; // Define a maximum number of iterations per call + uint256 iterations = 0; - while (currentSellId != 0 && buyVolume > 0) { + while (currentSellId != 0 && buyVolume > 0 && iterations < maxIterations) { Order storage sellOrder = sellOrders[currentSellId]; if (buyPrice >= sellOrder.price) { @@ -155,6 +160,7 @@ abstract contract OrderBookHTS { } else { break; } + iterations++; } firstSellOrderId = currentSellId; // Update the first sell order ID diff --git a/data/abis/ExchangeFactory.json b/data/abis/ExchangeFactory.json new file mode 100644 index 0000000..2aae3f8 --- /dev/null +++ b/data/abis/ExchangeFactory.json @@ -0,0 +1,123 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ExchangeFactory", + "sourceName": "contracts/orderbook/ExchangeFactory.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "exchange", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "deployer", + "type": "address" + } + ], + "name": "ExchangeDeployed", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "exchange", + "type": "address" + } + ], + "name": "availableExchanges", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + } + ], + "name": "deployExchange", + "outputs": [ + { + "internalType": "address", + "name": "exchange", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeDeployed", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "exchange", + "type": "address" + } + ], + "name": "isExchangeAvailable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50611e52806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063443bc94a146100515780636b35ea281461009757806378c39d5f146100aa578063a397c073146100e6575b600080fd5b61007a61005f366004610321565b6001602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61007a6100a5366004610356565b610109565b6100d66100b8366004610389565b6001600160a01b031660009081526020819052604090205460ff1690565b604051901515815260200161008e565b6100d66100f4366004610389565b60006020819052908152604090205460ff1681565b6040516bffffffffffffffffffffffff1933606090811b8216602084015284811b8216603484015283901b1660488201526000908190605c0160408051601f198184030181529181528151602092830120600081815260019093529120549091506001600160a01b0316156101c45760405162461bcd60e51b815260206004820152601960248201527f45786368616e676520616c7265616479206465706c6f79656400000000000000604482015260640160405180910390fd5b6101cf818585610266565b600082815260016020818152604080842080546001600160a01b0319166001600160a01b0387811691821790925580865285845294829020805460ff1916909417909355805193845288831691840191909152908616908201523360608201529092507fa5b803b77d28e977c1af94d97267f3615377386271d1d18976e7d87309e04b0d9060800160405180910390a15092915050565b6000806040518060200161027990610314565b601f1982820381018352601f9091011660408181526001600160a01b038781166020840152861681830152805180830382018152606083019091529192506000906102ca90849084906080016103d4565b60405160208183030381529060405290506102e587826102f0565b979650505050505050565b60008082602001835185818334f592505050803b61030d57600080fd5b9392505050565b611a2b806103f283390190565b60006020828403121561033357600080fd5b5035919050565b80356001600160a01b038116811461035157600080fd5b919050565b6000806040838503121561036957600080fd5b6103728361033a565b91506103806020840161033a565b90509250929050565b60006020828403121561039b57600080fd5b61030d8261033a565b6000815160005b818110156103c557602081850181015186830152016103ab565b50600093019283525090919050565b60006103e96103e383866103a4565b846103a4565b94935050505056fe60806040523480156200001157600080fd5b5060405162001a2b38038062001a2b833981016040819052620000349162000087565b60016008819055600080546001600160a01b03199081166001600160a01b039586161790915581541691909216179055620000bf565b80516001600160a01b03811681146200008257600080fd5b919050565b600080604083850312156200009b57600080fd5b620000a6836200006a565b9150620000b6602084016200006a565b90509250929050565b61195c80620000cf6000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063925931fc1161008c578063ee36d4ab11610066578063ee36d4ab1461022c578063f3fef3a31461023f578063f7888aec14610252578063f88d20471461027d57600080fd5b8063925931fc14610207578063a4406bcd14610210578063bb110bf91461022357600080fd5b80630fc63d10146100d457806335cea2881461010457806347e7ef241461017e5780634a8393f3146101935780635f64b55b146101dd57806372fb0777146101f0575b600080fd5b6000546100e7906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61014d610112366004611631565b60026020819052600091825260409091208054600182015492820154600383015460049093015491939290916001600160a01b039091169085565b604080519586526020860194909452928401919091526001600160a01b03166060830152608082015260a0016100fb565b61019161018c366004611666565b610290565b005b61014d6101a1366004611631565b6003602081905260009182526040909120805460018201546002830154938301546004909301549193909290916001600160a01b039091169085565b6001546100e7906001600160a01b031681565b6101f960065481565b6040519081526020016100fb565b6101f960075481565b6101f961021e366004611690565b61035c565b6101f960055481565b6101f961023a366004611690565b610460565b61019161024d366004611666565b6105e3565b6101f96102603660046116b2565b600460209081526000928352604080842090915290825290205481565b61019161028b3660046116f6565b6106df565b61029861085b565b6000546001600160a01b03838116911614806102c157506001546001600160a01b038381169116145b6103025760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b60448201526064015b60405180910390fd5b600081116103435760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b60448201526064016102f9565b61034e338383610885565b6103586001600855565b5050565b600061036661085b565b600083116103a65760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b60448201526064016102f9565b600082116103e75760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b60448201526064016102f9565b33600090815260046020908152604080832083546001600160a01b0316845290915290205482111561042b5760405162461bcd60e51b81526004016102f990611726565b6000610438338585610987565b9050801561044b5761044b338583610c11565b505060075461045a6001600855565b92915050565b600061046a61085b565b600083116104aa5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b60448201526064016102f9565b600082116104eb5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b60448201526064016102f9565b60008054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561053c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105609190611752565b61056b90600a611876565b6105759083611885565b61057f90846118a7565b3360009081526004602090815260408083206001546001600160a01b0316845290915290205410156105c35760405162461bcd60e51b81526004016102f990611726565b60006105d0338585610d97565b9050801561044b5761044b338583611047565b6105eb61085b565b6000546001600160a01b038381169116148061061457506001546001600160a01b038381169116145b6106505760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b60448201526064016102f9565b600081116106915760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b60448201526064016102f9565b3360009081526004602090815260408083206001600160a01b03861684529091529020548111156106d45760405162461bcd60e51b81526004016102f990611726565b61034e33838361125b565b6106e761085b565b600081610701576000838152600360205260409020610710565b60008381526002602052604090205b60038101549091506001600160a01b03166107635760405162461bcd60e51b81526020600482015260136024820152724f7264657220646f206e6f742065786973747360681b60448201526064016102f9565b60038101546001600160a01b031633146107d45760405162461bcd60e51b815260206004820152602c60248201527f4f6e6c7920746865206f726465722063726561746f722063616e2063616e636560448201526b36103a3434b99037b93232b960a11b60648201526084016102f9565b60008160020154116108345760405162461bcd60e51b8152602060048201526024808201527f4f7264657220616c72656164792063616e63656c6c6564206f722066756c66696044820152631b1b195960e21b60648201526084016102f9565b81610847576108428161134e565b610850565b61085081611476565b506103586001600855565b60026008540361087e57604051633ee5aeb560e01b815260040160405180910390fd5b6002600855565b6040516323b872dd60e01b81526001600160a01b038481166004830152306024830152604482018390528316906323b872dd906064016020604051808303816000875af11580156108da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fe91906118be565b506001600160a01b038084166000908152600460209081526040808320938616835292905290812080548392906109369084906118db565b9091555050604080516001600160a01b038481168252602082018490528516917f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f6291015b60405180910390a2505050565b600554600080546040805163313ce56760e01b8152905192939284926001600160a01b03169163313ce5679160048083019260209291908290030181865afa1580156109d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fb9190611752565b60ff1690505b8115801590610a105750600084115b15610c0657600082815260026020526040902060018101548611610bfa57600085826002015410610a415785610a47565b81600201545b905086610a5584600a6118ee565b610a5f9083611885565b610a6990826118a7565b6001600160a01b03808b16600090815260046020908152604080832060015490941683529290529081208054909190610aa39084906118db565b90915550506001600160a01b03808a166000908152600460209081526040808320835490941683529290529081208054849290610ae19084906118fa565b909155505060038301546001600160a01b039081166000908152600460209081526040808320835490941683529290529081208054849290610b249084906118db565b90915550610b34905082886118fa565b965081836002016000828254610b4a91906118fa565b9091555050600183015460038401546040805185815260208101939093526001600160a01b03918216908301528a16907f83cc6330e30db670fe04b07b602bd9cba4da39e5037267131b5d60cecba29f619060600160405180910390a28260020154600003610bf35760048084015460009687526002602081905260408820888155600181018990559081018890556003810180546001600160a01b0319169055909101959095555b5050610c00565b50610c06565b50610a01565b506005555092915050565b60078054906000610c218361190d565b909155505060065460005b8115801590610c4b575060008281526003602052604090206001015484115b15610c69575060008181526003602052604090206004015490610c2c565b6040805160a08101825260075480825260208083018881528385018881526001600160a01b038b811660608701818152608088018b8152600097885260038088528a892099518a55955160018a0155935160028901555193870180546001600160a01b03191694831694909417909355905160049586015590835292815283822082549093168252919091529081208054859290610d089084906118fa565b9091555050600754604080516000815260208101929092526001600160a01b038716828201526060820186905260808201859052517f286a2d7a29403e4e0f090c310eeb9b565090f3731608308fe263443ca910e9d59181900360a00190a180600003610d7a57600754600655610d90565b6007546000828152600360205260409020600401555b5050505050565b600654600080546040805163313ce56760e01b8152905192939284926001600160a01b03169163313ce5679160048083019260209291908290030181865afa158015610de7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0b9190611752565b60ff1690505b8115801590610e205750600084115b1561103c5760008281526003602052604090206001810154861061103057600085826002015410610e515785610e57565b81600201545b6001830154909150610e6a84600a6118ee565b610e749083611885565b610e7e90826118a7565b6001600160a01b03808b16600090815260046020908152604080832060015490941683529290529081208054909190610eb89084906118fa565b90915550506001600160a01b03808a166000908152600460209081526040808320835490941683529290529081208054849290610ef69084906118db565b90915550610f07905084600a6118ee565b610f119083611885565b610f1b90826118a7565b60038401546001600160a01b03908116600090815260046020908152604080832060015490941683529290529081208054909190610f5a9084906118db565b90915550610f6a905082886118fa565b965081836002016000828254610f8091906118fa565b9091555050600183015460038401546040805185815260208101939093526001600160a01b03918216908301528a16907f83cc6330e30db670fe04b07b602bd9cba4da39e5037267131b5d60cecba29f619060600160405180910390a282600201546000036110295760048084015460009687526003602081905260408820888155600181018990556002810189905590810180546001600160a01b0319169055909101959095555b5050611036565b5061103c565b50610e11565b506006555092915050565b600780549060006110578361190d565b909155505060055460005b8115801590611081575060008281526002602052604090206001015484105b1561109f575060008181526002602052604090206004015490611062565b6040805160a08101825260075480825260208083018881528385018881526001600160a01b038b811660608701908152608087018a815260009687526002808752898820985189559451600189015592519387019390935591516003860180546001600160a01b031916918416919091179055516004948501559154845163313ce56760e01b8152945192169363313ce5679381810193918290030181865afa158015611150573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111749190611752565b61117f90600a611876565b6111899084611885565b61119390856118a7565b6001600160a01b038087166000908152600460209081526040808320600154909416835292905290812080549091906111cd9084906118fa565b9091555050600754604080516001815260208101929092526001600160a01b038716828201526060820186905260808201859052517f286a2d7a29403e4e0f090c310eeb9b565090f3731608308fe263443ca910e9d59181900360a00190a18060000361123f57600754600555610d90565b6007546000828152600260205260409020600401555050505050565b6001600160a01b038084166000908152600460209081526040808320938616835292905290812080548392906112929084906118fa565b909155505060405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb906044016020604051808303816000875af11580156112e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130a91906118be565b50604080516001600160a01b038481168252602082018490528516917f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb910161097a565b6006548154036113655760048101546006556113ea565b60065460009081526003602052604090205b81546004820154146113e05780600401546000036113c95760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b60448201526064016102f9565b600401546000908152600360205260409020611377565b6004808301549101555b600281015460038201546001600160a01b03908116600090815260046020908152604080832083549094168352929052908120805490919061142d9084906118db565b9091555050600060028201819055815460405191825233917fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a4906020015b60405180910390a350565b60055481540361148d576004810154600555611512565b60055460009081526002602052604090205b81546004820154146115085780600401546000036114f15760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b60448201526064016102f9565b60040154600090815260026020526040902061149f565b6004808301549101555b60008054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611563573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115879190611752565b61159290600a611876565b81600201546115a19190611885565b81600101546115b091906118a7565b60038201546001600160a01b039081166000908152600460209081526040808320600154909416835292905290812080549091906115ef9084906118db565b9091555050600060028201558054604051600181523391907fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a49060200161146b565b60006020828403121561164357600080fd5b5035919050565b80356001600160a01b038116811461166157600080fd5b919050565b6000806040838503121561167957600080fd5b6116828361164a565b946020939093013593505050565b600080604083850312156116a357600080fd5b50508035926020909101359150565b600080604083850312156116c557600080fd5b6116ce8361164a565b91506116dc6020840161164a565b90509250929050565b80151581146116f357600080fd5b50565b6000806040838503121561170957600080fd5b82359150602083013561171b816116e5565b809150509250929050565b6020808252601290820152714e6f7420656e6f7567682062616c616e636560701b604082015260600190565b60006020828403121561176457600080fd5b815160ff8116811461177557600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b600181815b808511156117cd5781600019048211156117b3576117b361177c565b808516156117c057918102915b93841c9390800290611797565b509250929050565b6000826117e45750600161045a565b816117f15750600061045a565b816001811461180757600281146118115761182d565b600191505061045a565b60ff8411156118225761182261177c565b50506001821b61045a565b5060208310610133831016604e8410600b8410161715611850575081810a61045a565b61185a8383611792565b806000190482111561186e5761186e61177c565b029392505050565b600061177560ff8416836117d5565b6000826118a257634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761045a5761045a61177c565b6000602082840312156118d057600080fd5b8151611775816116e5565b8082018082111561045a5761045a61177c565b600061177583836117d5565b8181038181111561045a5761045a61177c565b60006001820161191f5761191f61177c565b506001019056fea2646970667358221220257d0fcef9327e72e8c9d83d65d26bfb381402b318dc782e8f9f11345f4aabe764736f6c63430008180033a2646970667358221220817748b9071ca0de2b2e4ba4c31d8939f545702220a86007e85c4ccef8af4d0c64736f6c63430008180033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063443bc94a146100515780636b35ea281461009757806378c39d5f146100aa578063a397c073146100e6575b600080fd5b61007a61005f366004610321565b6001602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61007a6100a5366004610356565b610109565b6100d66100b8366004610389565b6001600160a01b031660009081526020819052604090205460ff1690565b604051901515815260200161008e565b6100d66100f4366004610389565b60006020819052908152604090205460ff1681565b6040516bffffffffffffffffffffffff1933606090811b8216602084015284811b8216603484015283901b1660488201526000908190605c0160408051601f198184030181529181528151602092830120600081815260019093529120549091506001600160a01b0316156101c45760405162461bcd60e51b815260206004820152601960248201527f45786368616e676520616c7265616479206465706c6f79656400000000000000604482015260640160405180910390fd5b6101cf818585610266565b600082815260016020818152604080842080546001600160a01b0319166001600160a01b0387811691821790925580865285845294829020805460ff1916909417909355805193845288831691840191909152908616908201523360608201529092507fa5b803b77d28e977c1af94d97267f3615377386271d1d18976e7d87309e04b0d9060800160405180910390a15092915050565b6000806040518060200161027990610314565b601f1982820381018352601f9091011660408181526001600160a01b038781166020840152861681830152805180830382018152606083019091529192506000906102ca90849084906080016103d4565b60405160208183030381529060405290506102e587826102f0565b979650505050505050565b60008082602001835185818334f592505050803b61030d57600080fd5b9392505050565b611a2b806103f283390190565b60006020828403121561033357600080fd5b5035919050565b80356001600160a01b038116811461035157600080fd5b919050565b6000806040838503121561036957600080fd5b6103728361033a565b91506103806020840161033a565b90509250929050565b60006020828403121561039b57600080fd5b61030d8261033a565b6000815160005b818110156103c557602081850181015186830152016103ab565b50600093019283525090919050565b60006103e96103e383866103a4565b846103a4565b94935050505056fe60806040523480156200001157600080fd5b5060405162001a2b38038062001a2b833981016040819052620000349162000087565b60016008819055600080546001600160a01b03199081166001600160a01b039586161790915581541691909216179055620000bf565b80516001600160a01b03811681146200008257600080fd5b919050565b600080604083850312156200009b57600080fd5b620000a6836200006a565b9150620000b6602084016200006a565b90509250929050565b61195c80620000cf6000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063925931fc1161008c578063ee36d4ab11610066578063ee36d4ab1461022c578063f3fef3a31461023f578063f7888aec14610252578063f88d20471461027d57600080fd5b8063925931fc14610207578063a4406bcd14610210578063bb110bf91461022357600080fd5b80630fc63d10146100d457806335cea2881461010457806347e7ef241461017e5780634a8393f3146101935780635f64b55b146101dd57806372fb0777146101f0575b600080fd5b6000546100e7906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61014d610112366004611631565b60026020819052600091825260409091208054600182015492820154600383015460049093015491939290916001600160a01b039091169085565b604080519586526020860194909452928401919091526001600160a01b03166060830152608082015260a0016100fb565b61019161018c366004611666565b610290565b005b61014d6101a1366004611631565b6003602081905260009182526040909120805460018201546002830154938301546004909301549193909290916001600160a01b039091169085565b6001546100e7906001600160a01b031681565b6101f960065481565b6040519081526020016100fb565b6101f960075481565b6101f961021e366004611690565b61035c565b6101f960055481565b6101f961023a366004611690565b610460565b61019161024d366004611666565b6105e3565b6101f96102603660046116b2565b600460209081526000928352604080842090915290825290205481565b61019161028b3660046116f6565b6106df565b61029861085b565b6000546001600160a01b03838116911614806102c157506001546001600160a01b038381169116145b6103025760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b60448201526064015b60405180910390fd5b600081116103435760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b60448201526064016102f9565b61034e338383610885565b6103586001600855565b5050565b600061036661085b565b600083116103a65760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b60448201526064016102f9565b600082116103e75760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b60448201526064016102f9565b33600090815260046020908152604080832083546001600160a01b0316845290915290205482111561042b5760405162461bcd60e51b81526004016102f990611726565b6000610438338585610987565b9050801561044b5761044b338583610c11565b505060075461045a6001600855565b92915050565b600061046a61085b565b600083116104aa5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b60448201526064016102f9565b600082116104eb5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b60448201526064016102f9565b60008054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561053c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105609190611752565b61056b90600a611876565b6105759083611885565b61057f90846118a7565b3360009081526004602090815260408083206001546001600160a01b0316845290915290205410156105c35760405162461bcd60e51b81526004016102f990611726565b60006105d0338585610d97565b9050801561044b5761044b338583611047565b6105eb61085b565b6000546001600160a01b038381169116148061061457506001546001600160a01b038381169116145b6106505760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b60448201526064016102f9565b600081116106915760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b60448201526064016102f9565b3360009081526004602090815260408083206001600160a01b03861684529091529020548111156106d45760405162461bcd60e51b81526004016102f990611726565b61034e33838361125b565b6106e761085b565b600081610701576000838152600360205260409020610710565b60008381526002602052604090205b60038101549091506001600160a01b03166107635760405162461bcd60e51b81526020600482015260136024820152724f7264657220646f206e6f742065786973747360681b60448201526064016102f9565b60038101546001600160a01b031633146107d45760405162461bcd60e51b815260206004820152602c60248201527f4f6e6c7920746865206f726465722063726561746f722063616e2063616e636560448201526b36103a3434b99037b93232b960a11b60648201526084016102f9565b60008160020154116108345760405162461bcd60e51b8152602060048201526024808201527f4f7264657220616c72656164792063616e63656c6c6564206f722066756c66696044820152631b1b195960e21b60648201526084016102f9565b81610847576108428161134e565b610850565b61085081611476565b506103586001600855565b60026008540361087e57604051633ee5aeb560e01b815260040160405180910390fd5b6002600855565b6040516323b872dd60e01b81526001600160a01b038481166004830152306024830152604482018390528316906323b872dd906064016020604051808303816000875af11580156108da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fe91906118be565b506001600160a01b038084166000908152600460209081526040808320938616835292905290812080548392906109369084906118db565b9091555050604080516001600160a01b038481168252602082018490528516917f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f6291015b60405180910390a2505050565b600554600080546040805163313ce56760e01b8152905192939284926001600160a01b03169163313ce5679160048083019260209291908290030181865afa1580156109d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fb9190611752565b60ff1690505b8115801590610a105750600084115b15610c0657600082815260026020526040902060018101548611610bfa57600085826002015410610a415785610a47565b81600201545b905086610a5584600a6118ee565b610a5f9083611885565b610a6990826118a7565b6001600160a01b03808b16600090815260046020908152604080832060015490941683529290529081208054909190610aa39084906118db565b90915550506001600160a01b03808a166000908152600460209081526040808320835490941683529290529081208054849290610ae19084906118fa565b909155505060038301546001600160a01b039081166000908152600460209081526040808320835490941683529290529081208054849290610b249084906118db565b90915550610b34905082886118fa565b965081836002016000828254610b4a91906118fa565b9091555050600183015460038401546040805185815260208101939093526001600160a01b03918216908301528a16907f83cc6330e30db670fe04b07b602bd9cba4da39e5037267131b5d60cecba29f619060600160405180910390a28260020154600003610bf35760048084015460009687526002602081905260408820888155600181018990559081018890556003810180546001600160a01b0319169055909101959095555b5050610c00565b50610c06565b50610a01565b506005555092915050565b60078054906000610c218361190d565b909155505060065460005b8115801590610c4b575060008281526003602052604090206001015484115b15610c69575060008181526003602052604090206004015490610c2c565b6040805160a08101825260075480825260208083018881528385018881526001600160a01b038b811660608701818152608088018b8152600097885260038088528a892099518a55955160018a0155935160028901555193870180546001600160a01b03191694831694909417909355905160049586015590835292815283822082549093168252919091529081208054859290610d089084906118fa565b9091555050600754604080516000815260208101929092526001600160a01b038716828201526060820186905260808201859052517f286a2d7a29403e4e0f090c310eeb9b565090f3731608308fe263443ca910e9d59181900360a00190a180600003610d7a57600754600655610d90565b6007546000828152600360205260409020600401555b5050505050565b600654600080546040805163313ce56760e01b8152905192939284926001600160a01b03169163313ce5679160048083019260209291908290030181865afa158015610de7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0b9190611752565b60ff1690505b8115801590610e205750600084115b1561103c5760008281526003602052604090206001810154861061103057600085826002015410610e515785610e57565b81600201545b6001830154909150610e6a84600a6118ee565b610e749083611885565b610e7e90826118a7565b6001600160a01b03808b16600090815260046020908152604080832060015490941683529290529081208054909190610eb89084906118fa565b90915550506001600160a01b03808a166000908152600460209081526040808320835490941683529290529081208054849290610ef69084906118db565b90915550610f07905084600a6118ee565b610f119083611885565b610f1b90826118a7565b60038401546001600160a01b03908116600090815260046020908152604080832060015490941683529290529081208054909190610f5a9084906118db565b90915550610f6a905082886118fa565b965081836002016000828254610f8091906118fa565b9091555050600183015460038401546040805185815260208101939093526001600160a01b03918216908301528a16907f83cc6330e30db670fe04b07b602bd9cba4da39e5037267131b5d60cecba29f619060600160405180910390a282600201546000036110295760048084015460009687526003602081905260408820888155600181018990556002810189905590810180546001600160a01b0319169055909101959095555b5050611036565b5061103c565b50610e11565b506006555092915050565b600780549060006110578361190d565b909155505060055460005b8115801590611081575060008281526002602052604090206001015484105b1561109f575060008181526002602052604090206004015490611062565b6040805160a08101825260075480825260208083018881528385018881526001600160a01b038b811660608701908152608087018a815260009687526002808752898820985189559451600189015592519387019390935591516003860180546001600160a01b031916918416919091179055516004948501559154845163313ce56760e01b8152945192169363313ce5679381810193918290030181865afa158015611150573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111749190611752565b61117f90600a611876565b6111899084611885565b61119390856118a7565b6001600160a01b038087166000908152600460209081526040808320600154909416835292905290812080549091906111cd9084906118fa565b9091555050600754604080516001815260208101929092526001600160a01b038716828201526060820186905260808201859052517f286a2d7a29403e4e0f090c310eeb9b565090f3731608308fe263443ca910e9d59181900360a00190a18060000361123f57600754600555610d90565b6007546000828152600260205260409020600401555050505050565b6001600160a01b038084166000908152600460209081526040808320938616835292905290812080548392906112929084906118fa565b909155505060405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb906044016020604051808303816000875af11580156112e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130a91906118be565b50604080516001600160a01b038481168252602082018490528516917f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb910161097a565b6006548154036113655760048101546006556113ea565b60065460009081526003602052604090205b81546004820154146113e05780600401546000036113c95760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b60448201526064016102f9565b600401546000908152600360205260409020611377565b6004808301549101555b600281015460038201546001600160a01b03908116600090815260046020908152604080832083549094168352929052908120805490919061142d9084906118db565b9091555050600060028201819055815460405191825233917fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a4906020015b60405180910390a350565b60055481540361148d576004810154600555611512565b60055460009081526002602052604090205b81546004820154146115085780600401546000036114f15760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b60448201526064016102f9565b60040154600090815260026020526040902061149f565b6004808301549101555b60008054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611563573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115879190611752565b61159290600a611876565b81600201546115a19190611885565b81600101546115b091906118a7565b60038201546001600160a01b039081166000908152600460209081526040808320600154909416835292905290812080549091906115ef9084906118db565b9091555050600060028201558054604051600181523391907fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a49060200161146b565b60006020828403121561164357600080fd5b5035919050565b80356001600160a01b038116811461166157600080fd5b919050565b6000806040838503121561167957600080fd5b6116828361164a565b946020939093013593505050565b600080604083850312156116a357600080fd5b50508035926020909101359150565b600080604083850312156116c557600080fd5b6116ce8361164a565b91506116dc6020840161164a565b90509250929050565b80151581146116f357600080fd5b50565b6000806040838503121561170957600080fd5b82359150602083013561171b816116e5565b809150509250929050565b6020808252601290820152714e6f7420656e6f7567682062616c616e636560701b604082015260600190565b60006020828403121561176457600080fd5b815160ff8116811461177557600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b600181815b808511156117cd5781600019048211156117b3576117b361177c565b808516156117c057918102915b93841c9390800290611797565b509250929050565b6000826117e45750600161045a565b816117f15750600061045a565b816001811461180757600281146118115761182d565b600191505061045a565b60ff8411156118225761182261177c565b50506001821b61045a565b5060208310610133831016604e8410600b8410161715611850575081810a61045a565b61185a8383611792565b806000190482111561186e5761186e61177c565b029392505050565b600061177560ff8416836117d5565b6000826118a257634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761045a5761045a61177c565b6000602082840312156118d057600080fd5b8151611775816116e5565b8082018082111561045a5761045a61177c565b600061177583836117d5565b8181038181111561045a5761045a61177c565b60006001820161191f5761191f61177c565b506001019056fea2646970667358221220257d0fcef9327e72e8c9d83d65d26bfb381402b318dc782e8f9f11345f4aabe764736f6c63430008180033a2646970667358221220817748b9071ca0de2b2e4ba4c31d8939f545702220a86007e85c4ccef8af4d0c64736f6c63430008180033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/data/abis/ExchangeFactoryHTS.json b/data/abis/ExchangeFactoryHTS.json new file mode 100644 index 0000000..707a35b --- /dev/null +++ b/data/abis/ExchangeFactoryHTS.json @@ -0,0 +1,123 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ExchangeFactoryHTS", + "sourceName": "contracts/orderbook/hts/ExchangeFactoryHTS.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "exchange", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "deployer", + "type": "address" + } + ], + "name": "ExchangeDeployed", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "exchange", + "type": "address" + } + ], + "name": "availableExchanges", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + } + ], + "name": "deployExchange", + "outputs": [ + { + "internalType": "address", + "name": "exchange", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "exchangeDeployed", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "exchange", + "type": "address" + } + ], + "name": "isExchangeAvailable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50612194806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063443bc94a146100515780636b35ea281461009757806378c39d5f146100aa578063a397c073146100e6575b600080fd5b61007a61005f366004610321565b6001602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61007a6100a5366004610356565b610109565b6100d66100b8366004610389565b6001600160a01b031660009081526020819052604090205460ff1690565b604051901515815260200161008e565b6100d66100f4366004610389565b60006020819052908152604090205460ff1681565b6040516bffffffffffffffffffffffff1933606090811b8216602084015284811b8216603484015283901b1660488201526000908190605c0160408051601f198184030181529181528151602092830120600081815260019093529120549091506001600160a01b0316156101c45760405162461bcd60e51b815260206004820152601960248201527f45786368616e676520616c7265616479206465706c6f79656400000000000000604482015260640160405180910390fd5b6101cf818585610266565b600082815260016020818152604080842080546001600160a01b0319166001600160a01b0387811691821790925580865285845294829020805460ff1916909417909355805193845288831691840191909152908616908201523360608201529092507fa5b803b77d28e977c1af94d97267f3615377386271d1d18976e7d87309e04b0d9060800160405180910390a15092915050565b6000806040518060200161027990610314565b601f1982820381018352601f9091011660408181526001600160a01b038781166020840152861681830152805180830382018152606083019091529192506000906102ca90849084906080016103d4565b60405160208183030381529060405290506102e587826102f0565b979650505050505050565b60008082602001835185818334f592505050803b61030d57600080fd5b9392505050565b611d6d806103f283390190565b60006020828403121561033357600080fd5b5035919050565b80356001600160a01b038116811461035157600080fd5b919050565b6000806040838503121561036957600080fd5b6103728361033a565b91506103806020840161033a565b90509250929050565b60006020828403121561039b57600080fd5b61030d8261033a565b6000815160005b818110156103c557602081850181015186830152016103ab565b50600093019283525090919050565b60006103e96103e383866103a4565b846103a4565b94935050505056fe60806040523480156200001157600080fd5b5060405162001d6d38038062001d6d8339810160408190526200003491620001e1565b60016008819055600080546001600160a01b038086166001600160a01b03199283168117909355835490851691161790915562000072903062000092565b6001546200008a906001600160a01b03163062000092565b505062000276565b604080516001600160a01b038381166024830152841660448083019190915282518083039091018152606490910182526020810180516001600160e01b031663248a35ef60e11b17905290516000918291829161016791620000f5919062000219565b6000604051808303816000865af19150503d806000811462000134576040519150601f19603f3d011682016040523d82523d6000602084013e62000139565b606091505b5091509150816200014c57601562000162565b808060200190518101906200016291906200024a565b9250600383900b601614620001bd5760405162461bcd60e51b815260206004820152601f60248201527f536166652073696e676c65206173736f63696174696f6e206661696c65642100604482015260640160405180910390fd5b5050505050565b80516001600160a01b0381168114620001dc57600080fd5b919050565b60008060408385031215620001f557600080fd5b6200020083620001c4565b91506200021060208401620001c4565b90509250929050565b6000825160005b818110156200023c576020818601810151858301520162000220565b506000920191825250919050565b6000602082840312156200025d57600080fd5b81518060030b81146200026f57600080fd5b9392505050565b611ae780620002866000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c806372fb07771161008c578063bb110bf911610066578063bb110bf91461024d578063dd5813ee14610256578063f7888aec14610269578063f88d2047146102aa57600080fd5b806372fb077714610226578063925931fc1461022f57806392c029911461023857600080fd5b806303c4c2e1146100d45780630fc63d10146100fa5780632ec2add71461012557806335cea288146101385780634a8393f3146101c15780635f64b55b14610213575b600080fd5b6100e76100e236600461184d565b6102bd565b6040519081526020015b60405180910390f35b60005461010d906001600160a01b031681565b6040516001600160a01b0390911681526020016100f1565b6100e761013336600461184d565b6103f1565b61018a610146366004611880565b600260208190526000918252604090912080546001820154928201546003909201549092600781810b93600160401b909204900b916001600160a01b039091169085565b60408051958652600794850b60208701529290930b918401919091526001600160a01b03166060830152608082015260a0016100f1565b61018a6101cf366004611880565b600360208190526000918252604090912080546001820154600283015492909301549092600781810b93600160401b909204900b916001600160a01b039091169085565b60015461010d906001600160a01b031681565b6100e760065481565b6100e760075481565b61024b6102463660046118b0565b6104f3565b005b6100e760055481565b61024b6102643660046118b0565b610607565b6102976102773660046118cc565b600460209081526000928352604080842090915290825290205460070b81565b60405160079190910b81526020016100f1565b61024b6102b83660046118f6565b6106c3565b60006102c761084c565b60008360070b1361030f5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b60448201526064015b60405180910390fd5b60008260070b136103535760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b6044820152606401610306565b6103616305f5e10083611941565b61036b908461198e565b3360009081526004602090815260408083206001546001600160a01b03168452909152902054600791820b910b12156103b65760405162461bcd60e51b8152600401610306906119b5565b60006103c3338585610876565b905060008160070b13156103dc576103dc338583610b96565b50506007546103eb6001600855565b92915050565b60006103fb61084c565b60008360070b1361043e5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b6044820152606401610306565b60008260070b136104825760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b6044820152606401610306565b33600090815260046020908152604080832083546001600160a01b03168452909152902054600783810b91900b12156104cd5760405162461bcd60e51b8152600401610306906119b5565b60006104da338585610da7565b905060008160070b13156103dc576103dc3385836110a1565b6104fb61084c565b6000546001600160a01b038381169116148061052457506001546001600160a01b038381169116145b6105605760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606401610306565b60008160070b136105a45760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610306565b3360009081526004602090815260408083206001600160a01b0386168452909152902054600782810b91900b12156105ee5760405162461bcd60e51b8152600401610306906119b5565b6105f9338383611287565b6106036001600855565b5050565b61060f61084c565b6000546001600160a01b038381169116148061063857506001546001600160a01b038381169116145b6106745760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606401610306565b60008160070b136106b85760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610306565b6105f933838361134b565b6106cb61084c565b6000816106e55760008381526003602052604090206106f4565b60008381526002602052604090205b60028101549091506001600160a01b03166107485760405162461bcd60e51b815260206004820152601460248201527313dc99195c88191bd95cc81b9bdd08195e1a5cdd60621b6044820152606401610306565b60028101546001600160a01b031633146107b95760405162461bcd60e51b815260206004820152602c60248201527f4f6e6c7920746865206f726465722063726561746f722063616e2063616e636560448201526b36103a3434b99037b93232b960a11b6064820152608401610306565b60018101546000600160401b90910460070b136108245760405162461bcd60e51b8152602060048201526024808201527f4f7264657220616c72656164792063616e63656c6c6564206f722066756c66696044820152631b1b195960e21b6064820152608401610306565b81156108385761083381611402565b610841565b61084181611591565b506106036001600855565b60026008540361086f57604051633ee5aeb560e01b815260040160405180910390fd5b6002600855565b600654600090600a825b8215801590610892575060008560070b135b801561089d57508181105b15610b8a5760008381526003602052604090206001810154600790810b9088900b12610b71576001810154600090600788810b600160401b909204900b126108e557866108f5565b6001820154600160401b900460070b5b600183015490915060070b61090e6305f5e10083611941565b610918908261198e565b6001600160a01b03808c1660009081526004602090815260408083206001549094168352929052908120805490919061095590849060070b6119e1565b82546001600160401b039182166101009390930a9283029190920219909116179055506001600160a01b03808b1660009081526004602090815260408083208354909416835292905290812080548492906109b490849060070b611a10565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055506305f5e100826109eb9190611941565b6109f5908261198e565b60028401546001600160a01b03908116600090815260046020908152604080832060015490941683529290529081208054909190610a3790849060070b611a10565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055508188610a6a91906119e1565b6001840180549199508391600890610a8d908490600160401b900460070b6119e1565b82546101009290920a6001600160401b03818102199093169190921691909102179055506001830154600284015460408051600786810b82529390930b60208401526001600160a01b038d8116848301529091166060830152517f3811c688c91a2195acbf84f4d5e7adc8d2f17ba048f1051955046e511411fd7d9181900360800190a16001830154600160401b900460070b600003610b6a5760038084015460009788526020829052604088208881556001810180546001600160801b03191690556002810180546001600160a01b0319169055909101969096555b5050610b77565b50610b8a565b81610b8181611a3f565b92505050610880565b50506006555092915050565b60078054906000610ba683611a3f565b909155505060055460005b8115801590610bd75750600082815260026020526040902060010154600785810b91900b135b15610bf5575060008181526002602052604090206003015490610bb1565b6040805160a0810182526007805480835287820b60208085019182529288900b8486019081526001600160a01b03808c1660608701908152608087018a815260009586526002968790529790942095518655915160018601805492516001600160401b03908116600160401b026001600160801b031990941692169190911791909117905590519183018054929091166001600160a01b03199092169190911790559051600390910155610cad6305f5e10084611941565b610cb7908561198e565b6001600160a01b03808716600090815260046020908152604080832060015490941683529290529081208054909190610cf490849060070b6119e1565b82546001600160401b039182166101009390930a92830291909202199091161790555060078054604080516001815260208101929092526001600160a01b0388169082015285820b60608201529084900b60808201527fddca83c332d5b33951e90d550eefc003b7a1efae1cdf8c4d684d4ccdf2cd8d599060a00160405180910390a180600003610d8a57600754600555610da0565b6007546000828152600260205260409020600301555b5050505050565b600554600090600a825b8215801590610dc3575060008560070b135b8015610dce57508181105b156110955760008381526002602052604090206001810154600790810b9088900b1361107c576001810154600090600788810b600160401b909204900b12610e165786610e26565b6001820154600160401b900460070b5b905087610e376305f5e10083611941565b610e41908261198e565b6001600160a01b03808c16600090815260046020908152604080832060015490941683529290529081208054909190610e7e90849060070b611a10565b82546001600160401b039182166101009390930a9283029190920219909116179055506001600160a01b03808b166000908152600460209081526040808320835490941683529290529081208054849290610edd90849060070b6119e1565b82546001600160401b039182166101009390930a92830291909202199091161790555060028301546001600160a01b039081166000908152600460209081526040808320835490941683529290529081208054849290610f4190849060070b611a10565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055508188610f7491906119e1565b6001840180549199508391600890610f97908490600160401b900460070b6119e1565b82546101009290920a6001600160401b03818102199093169190921691909102179055506001830154600284015460408051600786810b82529390930b60208401526001600160a01b038d8116848301529091166060830152517f3811c688c91a2195acbf84f4d5e7adc8d2f17ba048f1051955046e511411fd7d9181900360800190a16001830154600160401b900460070b60000361107557600380840154600097885260026020819052604089208981556001810180546001600160801b031916905590810180546001600160a01b0319169055909101969096555b5050611082565b50611095565b8161108c81611a3f565b92505050610db1565b50506005555092915050565b600780549060006110b183611a3f565b909155505060065460005b81158015906110e25750600082815260036020526040902060010154600785810b91900b125b15611101575060008181526003602081905260409091200154906110bc565b6040805160a0810182526007805480835287820b602080850191825288840b8587019081526001600160a01b03808d1660608801818152608089018c8152600097885260038087528b89209a518b55965160018b01805496516001600160401b03908116600160401b026001600160801b031990981692169190911795909517909455516002890180549184166001600160a01b0319909216919091179055915196909301959095559382526004845284822082549091168252909252918120805486939192916111d49185910b6119e1565b82546001600160401b039182166101009390930a92830291909202199091161790555060078054604080516000815260208101929092526001600160a01b0388169082015285820b60608201529084900b60808201527fddca83c332d5b33951e90d550eefc003b7a1efae1cdf8c4d684d4ccdf2cd8d599060a00160405180910390a18060000361126a57600754600655610da0565b600754600082815260036020819052604090912001555050505050565b6001600160a01b038084166000908152600460209081526040808320938616835292905290812080548392906112c190849060070b6119e1565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055506112f4823085846116fd565b604080516001600160a01b03808616825284166020820152600783900b918101919091527fd09be44e70d8a46d3b3b8da9701595dcaec29d75930065918923c7d9fd73eb58906060015b60405180910390a1505050565b611357828430846116fd565b6001600160a01b0380841660009081526004602090815260408083209386168352929052908120805483929061139190849060070b611a10565b82546001600160401b039182166101009390930a928302919092021990911617905550604080516001600160a01b03808616825284166020820152600783900b918101919091527f64e3b56a34ae45fe7d1f33e3d3da391a671e6043606ac9c811a6c1243023841d9060600161133e565b60055481540361141957600381015460055561149e565b60055460009081526002602052604090205b815460038201541461149457806003015460000361147d5760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b6044820152606401610306565b60030154600090815260026020526040902061142b565b6003808301549101555b60018101546114bc906305f5e10090600160401b900460070b611941565b60018201546114ce919060070b61198e565b60028201546001600160a01b0390811660009081526004602090815260408083206001549094168352929052908120805490919061151090849060070b611a10565b82546001600160401b039182166101009390930a9283029190920219909116179055506001818101805467ffffffffffffffff60401b19169055815460408051928352602083019190915233908201527fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a4906060015b60405180910390a150565b6006548154036115a8576003810154600655611630565b60065460009081526003602052604090205b815460038201541461162657806003015460000361160c5760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b6044820152606401610306565b6003908101546000908152602091909152604090206115ba565b6003808301549101555b600181015460028201546001600160a01b039081166000908152600460209081526040808320835490941683529290529081208054600160401b909304600790810b93919291611683918591900b611a10565b82546001600160401b039182166101009390930a92830291909202199091161790555060018101805467ffffffffffffffff60401b1916905580546040805160008152602081019290925233908201527fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a490606001611586565b604080516001600160a01b038681166024830152858116604483015284166064820152600783900b6084808301919091528251808303909101815260a490910182526020810180516001600160e01b031663eca3691760e01b179052905160009182918291610167916117709190611a58565b6000604051808303816000865af19150503d80600081146117ad576040519150601f19603f3d011682016040523d82523d6000602084013e6117b2565b606091505b5091509150816117c35760156117d7565b808060200190518101906117d79190611a87565b9250600383900b60161461182d5760405162461bcd60e51b815260206004820152601b60248201527f5361666520746f6b656e207472616e73666572206661696c65642100000000006044820152606401610306565b50505050505050565b8035600781900b811461184857600080fd5b919050565b6000806040838503121561186057600080fd5b61186983611836565b915061187760208401611836565b90509250929050565b60006020828403121561189257600080fd5b5035919050565b80356001600160a01b038116811461184857600080fd5b600080604083850312156118c357600080fd5b61186983611899565b600080604083850312156118df57600080fd5b6118e883611899565b915061187760208401611899565b6000806040838503121561190957600080fd5b823591506020830135801515811461192057600080fd5b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b60008160070b8360070b8061196657634e487b7160e01b600052601260045260246000fd5b677fffffffffffffff198214600019821416156119855761198561192b565b90059392505050565b60008260070b8260070b028060070b91508082146119ae576119ae61192b565b5092915050565b6020808252601290820152714e6f7420656e6f7567682062616c616e636560701b604082015260600190565b600782810b9082900b03677fffffffffffffff198112677fffffffffffffff821317156103eb576103eb61192b565b600781810b9083900b01677fffffffffffffff8113677fffffffffffffff19821217156103eb576103eb61192b565b600060018201611a5157611a5161192b565b5060010190565b6000825160005b81811015611a795760208186018101518583015201611a5f565b506000920191825250919050565b600060208284031215611a9957600080fd5b81518060030b8114611aaa57600080fd5b939250505056fea26469706673582212205aa48bb78bfafd55a1384ef36fe88a0c230cf3807ce8924547abd90a0159119064736f6c63430008180033a2646970667358221220ee260359a878572e79fea58191e64d978b62ba0101ca875e8e46a04f026576ea64736f6c63430008180033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063443bc94a146100515780636b35ea281461009757806378c39d5f146100aa578063a397c073146100e6575b600080fd5b61007a61005f366004610321565b6001602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61007a6100a5366004610356565b610109565b6100d66100b8366004610389565b6001600160a01b031660009081526020819052604090205460ff1690565b604051901515815260200161008e565b6100d66100f4366004610389565b60006020819052908152604090205460ff1681565b6040516bffffffffffffffffffffffff1933606090811b8216602084015284811b8216603484015283901b1660488201526000908190605c0160408051601f198184030181529181528151602092830120600081815260019093529120549091506001600160a01b0316156101c45760405162461bcd60e51b815260206004820152601960248201527f45786368616e676520616c7265616479206465706c6f79656400000000000000604482015260640160405180910390fd5b6101cf818585610266565b600082815260016020818152604080842080546001600160a01b0319166001600160a01b0387811691821790925580865285845294829020805460ff1916909417909355805193845288831691840191909152908616908201523360608201529092507fa5b803b77d28e977c1af94d97267f3615377386271d1d18976e7d87309e04b0d9060800160405180910390a15092915050565b6000806040518060200161027990610314565b601f1982820381018352601f9091011660408181526001600160a01b038781166020840152861681830152805180830382018152606083019091529192506000906102ca90849084906080016103d4565b60405160208183030381529060405290506102e587826102f0565b979650505050505050565b60008082602001835185818334f592505050803b61030d57600080fd5b9392505050565b611d6d806103f283390190565b60006020828403121561033357600080fd5b5035919050565b80356001600160a01b038116811461035157600080fd5b919050565b6000806040838503121561036957600080fd5b6103728361033a565b91506103806020840161033a565b90509250929050565b60006020828403121561039b57600080fd5b61030d8261033a565b6000815160005b818110156103c557602081850181015186830152016103ab565b50600093019283525090919050565b60006103e96103e383866103a4565b846103a4565b94935050505056fe60806040523480156200001157600080fd5b5060405162001d6d38038062001d6d8339810160408190526200003491620001e1565b60016008819055600080546001600160a01b038086166001600160a01b03199283168117909355835490851691161790915562000072903062000092565b6001546200008a906001600160a01b03163062000092565b505062000276565b604080516001600160a01b038381166024830152841660448083019190915282518083039091018152606490910182526020810180516001600160e01b031663248a35ef60e11b17905290516000918291829161016791620000f5919062000219565b6000604051808303816000865af19150503d806000811462000134576040519150601f19603f3d011682016040523d82523d6000602084013e62000139565b606091505b5091509150816200014c57601562000162565b808060200190518101906200016291906200024a565b9250600383900b601614620001bd5760405162461bcd60e51b815260206004820152601f60248201527f536166652073696e676c65206173736f63696174696f6e206661696c65642100604482015260640160405180910390fd5b5050505050565b80516001600160a01b0381168114620001dc57600080fd5b919050565b60008060408385031215620001f557600080fd5b6200020083620001c4565b91506200021060208401620001c4565b90509250929050565b6000825160005b818110156200023c576020818601810151858301520162000220565b506000920191825250919050565b6000602082840312156200025d57600080fd5b81518060030b81146200026f57600080fd5b9392505050565b611ae780620002866000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c806372fb07771161008c578063bb110bf911610066578063bb110bf91461024d578063dd5813ee14610256578063f7888aec14610269578063f88d2047146102aa57600080fd5b806372fb077714610226578063925931fc1461022f57806392c029911461023857600080fd5b806303c4c2e1146100d45780630fc63d10146100fa5780632ec2add71461012557806335cea288146101385780634a8393f3146101c15780635f64b55b14610213575b600080fd5b6100e76100e236600461184d565b6102bd565b6040519081526020015b60405180910390f35b60005461010d906001600160a01b031681565b6040516001600160a01b0390911681526020016100f1565b6100e761013336600461184d565b6103f1565b61018a610146366004611880565b600260208190526000918252604090912080546001820154928201546003909201549092600781810b93600160401b909204900b916001600160a01b039091169085565b60408051958652600794850b60208701529290930b918401919091526001600160a01b03166060830152608082015260a0016100f1565b61018a6101cf366004611880565b600360208190526000918252604090912080546001820154600283015492909301549092600781810b93600160401b909204900b916001600160a01b039091169085565b60015461010d906001600160a01b031681565b6100e760065481565b6100e760075481565b61024b6102463660046118b0565b6104f3565b005b6100e760055481565b61024b6102643660046118b0565b610607565b6102976102773660046118cc565b600460209081526000928352604080842090915290825290205460070b81565b60405160079190910b81526020016100f1565b61024b6102b83660046118f6565b6106c3565b60006102c761084c565b60008360070b1361030f5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b60448201526064015b60405180910390fd5b60008260070b136103535760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b6044820152606401610306565b6103616305f5e10083611941565b61036b908461198e565b3360009081526004602090815260408083206001546001600160a01b03168452909152902054600791820b910b12156103b65760405162461bcd60e51b8152600401610306906119b5565b60006103c3338585610876565b905060008160070b13156103dc576103dc338583610b96565b50506007546103eb6001600855565b92915050565b60006103fb61084c565b60008360070b1361043e5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b6044820152606401610306565b60008260070b136104825760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b6044820152606401610306565b33600090815260046020908152604080832083546001600160a01b03168452909152902054600783810b91900b12156104cd5760405162461bcd60e51b8152600401610306906119b5565b60006104da338585610da7565b905060008160070b13156103dc576103dc3385836110a1565b6104fb61084c565b6000546001600160a01b038381169116148061052457506001546001600160a01b038381169116145b6105605760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606401610306565b60008160070b136105a45760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610306565b3360009081526004602090815260408083206001600160a01b0386168452909152902054600782810b91900b12156105ee5760405162461bcd60e51b8152600401610306906119b5565b6105f9338383611287565b6106036001600855565b5050565b61060f61084c565b6000546001600160a01b038381169116148061063857506001546001600160a01b038381169116145b6106745760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606401610306565b60008160070b136106b85760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610306565b6105f933838361134b565b6106cb61084c565b6000816106e55760008381526003602052604090206106f4565b60008381526002602052604090205b60028101549091506001600160a01b03166107485760405162461bcd60e51b815260206004820152601460248201527313dc99195c88191bd95cc81b9bdd08195e1a5cdd60621b6044820152606401610306565b60028101546001600160a01b031633146107b95760405162461bcd60e51b815260206004820152602c60248201527f4f6e6c7920746865206f726465722063726561746f722063616e2063616e636560448201526b36103a3434b99037b93232b960a11b6064820152608401610306565b60018101546000600160401b90910460070b136108245760405162461bcd60e51b8152602060048201526024808201527f4f7264657220616c72656164792063616e63656c6c6564206f722066756c66696044820152631b1b195960e21b6064820152608401610306565b81156108385761083381611402565b610841565b61084181611591565b506106036001600855565b60026008540361086f57604051633ee5aeb560e01b815260040160405180910390fd5b6002600855565b600654600090600a825b8215801590610892575060008560070b135b801561089d57508181105b15610b8a5760008381526003602052604090206001810154600790810b9088900b12610b71576001810154600090600788810b600160401b909204900b126108e557866108f5565b6001820154600160401b900460070b5b600183015490915060070b61090e6305f5e10083611941565b610918908261198e565b6001600160a01b03808c1660009081526004602090815260408083206001549094168352929052908120805490919061095590849060070b6119e1565b82546001600160401b039182166101009390930a9283029190920219909116179055506001600160a01b03808b1660009081526004602090815260408083208354909416835292905290812080548492906109b490849060070b611a10565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055506305f5e100826109eb9190611941565b6109f5908261198e565b60028401546001600160a01b03908116600090815260046020908152604080832060015490941683529290529081208054909190610a3790849060070b611a10565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055508188610a6a91906119e1565b6001840180549199508391600890610a8d908490600160401b900460070b6119e1565b82546101009290920a6001600160401b03818102199093169190921691909102179055506001830154600284015460408051600786810b82529390930b60208401526001600160a01b038d8116848301529091166060830152517f3811c688c91a2195acbf84f4d5e7adc8d2f17ba048f1051955046e511411fd7d9181900360800190a16001830154600160401b900460070b600003610b6a5760038084015460009788526020829052604088208881556001810180546001600160801b03191690556002810180546001600160a01b0319169055909101969096555b5050610b77565b50610b8a565b81610b8181611a3f565b92505050610880565b50506006555092915050565b60078054906000610ba683611a3f565b909155505060055460005b8115801590610bd75750600082815260026020526040902060010154600785810b91900b135b15610bf5575060008181526002602052604090206003015490610bb1565b6040805160a0810182526007805480835287820b60208085019182529288900b8486019081526001600160a01b03808c1660608701908152608087018a815260009586526002968790529790942095518655915160018601805492516001600160401b03908116600160401b026001600160801b031990941692169190911791909117905590519183018054929091166001600160a01b03199092169190911790559051600390910155610cad6305f5e10084611941565b610cb7908561198e565b6001600160a01b03808716600090815260046020908152604080832060015490941683529290529081208054909190610cf490849060070b6119e1565b82546001600160401b039182166101009390930a92830291909202199091161790555060078054604080516001815260208101929092526001600160a01b0388169082015285820b60608201529084900b60808201527fddca83c332d5b33951e90d550eefc003b7a1efae1cdf8c4d684d4ccdf2cd8d599060a00160405180910390a180600003610d8a57600754600555610da0565b6007546000828152600260205260409020600301555b5050505050565b600554600090600a825b8215801590610dc3575060008560070b135b8015610dce57508181105b156110955760008381526002602052604090206001810154600790810b9088900b1361107c576001810154600090600788810b600160401b909204900b12610e165786610e26565b6001820154600160401b900460070b5b905087610e376305f5e10083611941565b610e41908261198e565b6001600160a01b03808c16600090815260046020908152604080832060015490941683529290529081208054909190610e7e90849060070b611a10565b82546001600160401b039182166101009390930a9283029190920219909116179055506001600160a01b03808b166000908152600460209081526040808320835490941683529290529081208054849290610edd90849060070b6119e1565b82546001600160401b039182166101009390930a92830291909202199091161790555060028301546001600160a01b039081166000908152600460209081526040808320835490941683529290529081208054849290610f4190849060070b611a10565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055508188610f7491906119e1565b6001840180549199508391600890610f97908490600160401b900460070b6119e1565b82546101009290920a6001600160401b03818102199093169190921691909102179055506001830154600284015460408051600786810b82529390930b60208401526001600160a01b038d8116848301529091166060830152517f3811c688c91a2195acbf84f4d5e7adc8d2f17ba048f1051955046e511411fd7d9181900360800190a16001830154600160401b900460070b60000361107557600380840154600097885260026020819052604089208981556001810180546001600160801b031916905590810180546001600160a01b0319169055909101969096555b5050611082565b50611095565b8161108c81611a3f565b92505050610db1565b50506005555092915050565b600780549060006110b183611a3f565b909155505060065460005b81158015906110e25750600082815260036020526040902060010154600785810b91900b125b15611101575060008181526003602081905260409091200154906110bc565b6040805160a0810182526007805480835287820b602080850191825288840b8587019081526001600160a01b03808d1660608801818152608089018c8152600097885260038087528b89209a518b55965160018b01805496516001600160401b03908116600160401b026001600160801b031990981692169190911795909517909455516002890180549184166001600160a01b0319909216919091179055915196909301959095559382526004845284822082549091168252909252918120805486939192916111d49185910b6119e1565b82546001600160401b039182166101009390930a92830291909202199091161790555060078054604080516000815260208101929092526001600160a01b0388169082015285820b60608201529084900b60808201527fddca83c332d5b33951e90d550eefc003b7a1efae1cdf8c4d684d4ccdf2cd8d599060a00160405180910390a18060000361126a57600754600655610da0565b600754600082815260036020819052604090912001555050505050565b6001600160a01b038084166000908152600460209081526040808320938616835292905290812080548392906112c190849060070b6119e1565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055506112f4823085846116fd565b604080516001600160a01b03808616825284166020820152600783900b918101919091527fd09be44e70d8a46d3b3b8da9701595dcaec29d75930065918923c7d9fd73eb58906060015b60405180910390a1505050565b611357828430846116fd565b6001600160a01b0380841660009081526004602090815260408083209386168352929052908120805483929061139190849060070b611a10565b82546001600160401b039182166101009390930a928302919092021990911617905550604080516001600160a01b03808616825284166020820152600783900b918101919091527f64e3b56a34ae45fe7d1f33e3d3da391a671e6043606ac9c811a6c1243023841d9060600161133e565b60055481540361141957600381015460055561149e565b60055460009081526002602052604090205b815460038201541461149457806003015460000361147d5760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b6044820152606401610306565b60030154600090815260026020526040902061142b565b6003808301549101555b60018101546114bc906305f5e10090600160401b900460070b611941565b60018201546114ce919060070b61198e565b60028201546001600160a01b0390811660009081526004602090815260408083206001549094168352929052908120805490919061151090849060070b611a10565b82546001600160401b039182166101009390930a9283029190920219909116179055506001818101805467ffffffffffffffff60401b19169055815460408051928352602083019190915233908201527fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a4906060015b60405180910390a150565b6006548154036115a8576003810154600655611630565b60065460009081526003602052604090205b815460038201541461162657806003015460000361160c5760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b6044820152606401610306565b6003908101546000908152602091909152604090206115ba565b6003808301549101555b600181015460028201546001600160a01b039081166000908152600460209081526040808320835490941683529290529081208054600160401b909304600790810b93919291611683918591900b611a10565b82546001600160401b039182166101009390930a92830291909202199091161790555060018101805467ffffffffffffffff60401b1916905580546040805160008152602081019290925233908201527fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a490606001611586565b604080516001600160a01b038681166024830152858116604483015284166064820152600783900b6084808301919091528251808303909101815260a490910182526020810180516001600160e01b031663eca3691760e01b179052905160009182918291610167916117709190611a58565b6000604051808303816000865af19150503d80600081146117ad576040519150601f19603f3d011682016040523d82523d6000602084013e6117b2565b606091505b5091509150816117c35760156117d7565b808060200190518101906117d79190611a87565b9250600383900b60161461182d5760405162461bcd60e51b815260206004820152601b60248201527f5361666520746f6b656e207472616e73666572206661696c65642100000000006044820152606401610306565b50505050505050565b8035600781900b811461184857600080fd5b919050565b6000806040838503121561186057600080fd5b61186983611836565b915061187760208401611836565b90509250929050565b60006020828403121561189257600080fd5b5035919050565b80356001600160a01b038116811461184857600080fd5b600080604083850312156118c357600080fd5b61186983611899565b600080604083850312156118df57600080fd5b6118e883611899565b915061187760208401611899565b6000806040838503121561190957600080fd5b823591506020830135801515811461192057600080fd5b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b60008160070b8360070b8061196657634e487b7160e01b600052601260045260246000fd5b677fffffffffffffff198214600019821416156119855761198561192b565b90059392505050565b60008260070b8260070b028060070b91508082146119ae576119ae61192b565b5092915050565b6020808252601290820152714e6f7420656e6f7567682062616c616e636560701b604082015260600190565b600782810b9082900b03677fffffffffffffff198112677fffffffffffffff821317156103eb576103eb61192b565b600781810b9083900b01677fffffffffffffff8113677fffffffffffffff19821217156103eb576103eb61192b565b600060018201611a5157611a5161192b565b5060010190565b6000825160005b81811015611a795760208186018101518583015201611a5f565b506000920191825250919050565b600060208284031215611a9957600080fd5b81518060030b8114611aaa57600080fd5b939250505056fea26469706673582212205aa48bb78bfafd55a1384ef36fe88a0c230cf3807ce8924547abd90a0159119064736f6c63430008180033a2646970667358221220ee260359a878572e79fea58191e64d978b62ba0101ca875e8e46a04f026576ea64736f6c63430008180033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/data/abis/ExchangeHTS.json b/data/abis/ExchangeHTS.json index b724cd4..cd56238 100644 --- a/data/abis/ExchangeHTS.json +++ b/data/abis/ExchangeHTS.json @@ -28,7 +28,7 @@ "anonymous": false, "inputs": [ { - "indexed": true, + "indexed": false, "internalType": "address", "name": "trader", "type": "address" @@ -96,13 +96,13 @@ "type": "bool" }, { - "indexed": true, + "indexed": false, "internalType": "uint256", "name": "orderId", "type": "uint256" }, { - "indexed": true, + "indexed": false, "internalType": "address", "name": "trader", "type": "address" @@ -437,8 +437,8 @@ "type": "function" } ], - "bytecode": "0x60806040523480156200001157600080fd5b5060405162001d3638038062001d368339810160408190526200003491620001e1565b60016008819055600080546001600160a01b038086166001600160a01b03199283168117909355835490851691161790915562000072903062000092565b6001546200008a906001600160a01b03163062000092565b505062000276565b604080516001600160a01b038381166024830152841660448083019190915282518083039091018152606490910182526020810180516001600160e01b031663248a35ef60e11b17905290516000918291829161016791620000f5919062000219565b6000604051808303816000865af19150503d806000811462000134576040519150601f19603f3d011682016040523d82523d6000602084013e62000139565b606091505b5091509150816200014c57601562000162565b808060200190518101906200016291906200024a565b9250600383900b601614620001bd5760405162461bcd60e51b815260206004820152601f60248201527f536166652073696e676c65206173736f63696174696f6e206661696c65642100604482015260640160405180910390fd5b5050505050565b80516001600160a01b0381168114620001dc57600080fd5b919050565b60008060408385031215620001f557600080fd5b6200020083620001c4565b91506200021060208401620001c4565b90509250929050565b6000825160005b818110156200023c576020818601810151858301520162000220565b506000920191825250919050565b6000602082840312156200025d57600080fd5b81518060030b81146200026f57600080fd5b9392505050565b611ab080620002866000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c806372fb07771161008c578063bb110bf911610066578063bb110bf91461024d578063dd5813ee14610256578063f7888aec14610269578063f88d2047146102aa57600080fd5b806372fb077714610226578063925931fc1461022f57806392c029911461023857600080fd5b806303c4c2e1146100d45780630fc63d10146100fa5780632ec2add71461012557806335cea288146101385780634a8393f3146101c15780635f64b55b14610213575b600080fd5b6100e76100e2366004611816565b6102bd565b6040519081526020015b60405180910390f35b60005461010d906001600160a01b031681565b6040516001600160a01b0390911681526020016100f1565b6100e7610133366004611816565b6103ec565b61018a610146366004611849565b600260208190526000918252604090912080546001820154928201546003909201549092600781810b93600160401b909204900b916001600160a01b039091169085565b60408051958652600794850b60208701529290930b918401919091526001600160a01b03166060830152608082015260a0016100f1565b61018a6101cf366004611849565b600360208190526000918252604090912080546001820154600283015492909301549092600781810b93600160401b909204900b916001600160a01b039091169085565b60015461010d906001600160a01b031681565b6100e760065481565b6100e760075481565b61024b610246366004611879565b6104fd565b005b6100e760055481565b61024b610264366004611879565b610611565b610297610277366004611895565b600460209081526000928352604080842090915290825290205460070b81565b60405160079190910b81526020016100f1565b61024b6102b83660046118bf565b6106cd565b60006102c7610856565b60008360070b1361030f5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b60448201526064015b60405180910390fd5b60008260070b136103535760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b6044820152606401610306565b6103616305f5e1008361190a565b61036b9084611957565b3360009081526004602090815260408083206001546001600160a01b03168452909152902054600791820b910b12156103b65760405162461bcd60e51b81526004016103069061197e565b60006103c3338585610880565b905060008160070b13156103dc576103dc338583610b83565b5050600160085560005b92915050565b60006103f6610856565b60008360070b136104395760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b6044820152606401610306565b60008260070b1361047d5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b6044820152606401610306565b33600090815260046020908152604080832083546001600160a01b03168452909152902054600783810b91900b12156104c85760405162461bcd60e51b81526004016103069061197e565b60006104d5338585610d94565b905060008160070b13156104ee576104ee338583611071565b50506007546103e66001600855565b610505610856565b6000546001600160a01b038381169116148061052e57506001546001600160a01b038381169116145b61056a5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606401610306565b60008160070b136105ae5760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610306565b3360009081526004602090815260408083206001600160a01b0386168452909152902054600782810b91900b12156105f85760405162461bcd60e51b81526004016103069061197e565b610603338383611257565b61060d6001600855565b5050565b610619610856565b6000546001600160a01b038381169116148061064257506001546001600160a01b038381169116145b61067e5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606401610306565b60008160070b136106c25760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610306565b610603338383611316565b6106d5610856565b6000816106ef5760008381526003602052604090206106fe565b60008381526002602052604090205b60028101549091506001600160a01b03166107525760405162461bcd60e51b815260206004820152601460248201527313dc99195c88191bd95cc81b9bdd08195e1a5cdd60621b6044820152606401610306565b60028101546001600160a01b031633146107c35760405162461bcd60e51b815260206004820152602c60248201527f4f6e6c7920746865206f726465722063726561746f722063616e2063616e636560448201526b36103a3434b99037b93232b960a11b6064820152608401610306565b60018101546000600160401b90910460070b1361082e5760405162461bcd60e51b8152602060048201526024808201527f4f7264657220616c72656164792063616e63656c6c6564206f722066756c66696044820152631b1b195960e21b6064820152608401610306565b81156108425761083d816113e2565b61084b565b61084b81611565565b5061060d6001600855565b60026008540361087957604051633ee5aeb560e01b815260040160405180910390fd5b6002600855565b6006546000905b8015801590610899575060008360070b135b15610b795760008181526003602052604090206001810154600790810b9086900b12610b6d576001810154600090600786810b600160401b909204900b126108e157846108f1565b6001820154600160401b900460070b5b600183015490915060070b61090a6305f5e1008361190a565b6109149082611957565b6001600160a01b03808a1660009081526004602090815260408083206001549094168352929052908120805490919061095190849060070b6119aa565b82546001600160401b039182166101009390930a9283029190920219909116179055506001600160a01b0380891660009081526004602090815260408083208354909416835292905290812080548492906109b090849060070b6119d9565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055506305f5e100826109e7919061190a565b6109f19082611957565b60028401546001600160a01b03908116600090815260046020908152604080832060015490941683529290529081208054909190610a3390849060070b6119d9565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055508186610a6691906119aa565b6001840180549197508391600890610a89908490600160401b900460070b6119aa565b82546101009290920a6001600160401b03818102199093169190921691909102179055506001830154600284015460408051600786810b82529390930b60208401526001600160a01b038b8116848301529091166060830152517f3811c688c91a2195acbf84f4d5e7adc8d2f17ba048f1051955046e511411fd7d9181900360800190a16001830154600160401b900460070b600003610b665760038084015460009586526020829052604086208681556001810180546001600160801b03191690556002810180546001600160a01b0319169055909101949094555b5050610b73565b50610b79565b50610887565b6006555092915050565b60078054906000610b9383611a08565b909155505060055460005b8115801590610bc45750600082815260026020526040902060010154600785810b91900b135b15610be2575060008181526002602052604090206003015490610b9e565b6040805160a0810182526007805480835287820b60208085019182529288900b8486019081526001600160a01b03808c1660608701908152608087018a815260009586526002968790529790942095518655915160018601805492516001600160401b03908116600160401b026001600160801b031990941692169190911791909117905590519183018054929091166001600160a01b03199092169190911790559051600390910155610c9a6305f5e1008461190a565b610ca49085611957565b6001600160a01b03808716600090815260046020908152604080832060015490941683529290529081208054909190610ce190849060070b6119aa565b82546001600160401b039182166101009390930a92830291909202199091161790555060078054604080516001815260208101929092526001600160a01b0388169082015285820b60608201529084900b60808201527fddca83c332d5b33951e90d550eefc003b7a1efae1cdf8c4d684d4ccdf2cd8d599060a00160405180910390a180600003610d7757600754600555610d8d565b6007546000828152600260205260409020600301555b5050505050565b6005546000905b8015801590610dad575060008360070b135b156110675760008181526002602052604090206001810154600790810b9086900b1361105b576001810154600090600786810b600160401b909204900b12610df55784610e05565b6001820154600160401b900460070b5b905085610e166305f5e1008361190a565b610e209082611957565b6001600160a01b03808a16600090815260046020908152604080832060015490941683529290529081208054909190610e5d90849060070b6119d9565b82546001600160401b039182166101009390930a9283029190920219909116179055506001600160a01b038089166000908152600460209081526040808320835490941683529290529081208054849290610ebc90849060070b6119aa565b82546001600160401b039182166101009390930a92830291909202199091161790555060028301546001600160a01b039081166000908152600460209081526040808320835490941683529290529081208054849290610f2090849060070b6119d9565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055508186610f5391906119aa565b6001840180549197508391600890610f76908490600160401b900460070b6119aa565b82546101009290920a6001600160401b03818102199093169190921691909102179055506001830154600284015460408051600786810b82529390930b60208401526001600160a01b038b8116848301529091166060830152517f3811c688c91a2195acbf84f4d5e7adc8d2f17ba048f1051955046e511411fd7d9181900360800190a16001830154600160401b900460070b60000361105457600380840154600095865260026020819052604087208781556001810180546001600160801b031916905590810180546001600160a01b0319169055909101949094555b5050611061565b50611067565b50610d9b565b6005555092915050565b6007805490600061108183611a08565b909155505060065460005b81158015906110b25750600082815260036020526040902060010154600785810b91900b125b156110d15750600081815260036020819052604090912001549061108c565b6040805160a0810182526007805480835287820b602080850191825288840b8587019081526001600160a01b03808d1660608801818152608089018c8152600097885260038087528b89209a518b55965160018b01805496516001600160401b03908116600160401b026001600160801b031990981692169190911795909517909455516002890180549184166001600160a01b0319909216919091179055915196909301959095559382526004845284822082549091168252909252918120805486939192916111a49185910b6119aa565b82546001600160401b039182166101009390930a92830291909202199091161790555060078054604080516000815260208101929092526001600160a01b0388169082015285820b60608201529084900b60808201527fddca83c332d5b33951e90d550eefc003b7a1efae1cdf8c4d684d4ccdf2cd8d599060a00160405180910390a18060000361123a57600754600655610d8d565b600754600082815260036020819052604090912001555050505050565b6001600160a01b0380841660009081526004602090815260408083209386168352929052908120805483929061129190849060070b6119aa565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055506112c4823085846116c6565b604080516001600160a01b03858116825284166020820152600783900b8183015290517fd09be44e70d8a46d3b3b8da9701595dcaec29d75930065918923c7d9fd73eb589181900360600190a1505050565b611322828430846116c6565b6001600160a01b0380841660009081526004602090815260408083209386168352929052908120805483929061135c90849060070b6119d9565b92506101000a8154816001600160401b03021916908360070b6001600160401b03160217905550826001600160a01b03167f64e3b56a34ae45fe7d1f33e3d3da391a671e6043606ac9c811a6c1243023841d83836040516113d59291906001600160a01b0392909216825260070b602082015260400190565b60405180910390a2505050565b6005548154036113f957600381015460055561147e565b60055460009081526002602052604090205b815460038201541461147457806003015460000361145d5760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b6044820152606401610306565b60030154600090815260026020526040902061140b565b6003808301549101555b600181015461149c906305f5e10090600160401b900460070b61190a565b60018201546114ae919060070b611957565b60028201546001600160a01b039081166000908152600460209081526040808320600154909416835292905290812080549091906114f090849060070b6119d9565b82546001600160401b039182166101009390930a9283029190920219909116179055506001818101805467ffffffffffffffff60401b19169055815460405191825233917fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a4906020015b60405180910390a350565b60065481540361157c576003810154600655611604565b60065460009081526003602052604090205b81546003820154146115fa5780600301546000036115e05760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b6044820152606401610306565b60039081015460009081526020919091526040902061158e565b6003808301549101555b600181015460028201546001600160a01b039081166000908152600460209081526040808320835490941683529290529081208054600160401b909304600790810b93919291611657918591900b6119d9565b82546001600160401b039182166101009390930a92830291909202199091161790555060018101805467ffffffffffffffff60401b191690558054604051600081523391907fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a49060200161155a565b604080516001600160a01b038681166024830152858116604483015284166064820152600783900b6084808301919091528251808303909101815260a490910182526020810180516001600160e01b031663eca3691760e01b179052905160009182918291610167916117399190611a21565b6000604051808303816000865af19150503d8060008114611776576040519150601f19603f3d011682016040523d82523d6000602084013e61177b565b606091505b50915091508161178c5760156117a0565b808060200190518101906117a09190611a50565b9250600383900b6016146117f65760405162461bcd60e51b815260206004820152601b60248201527f5361666520746f6b656e207472616e73666572206661696c65642100000000006044820152606401610306565b50505050505050565b8035600781900b811461181157600080fd5b919050565b6000806040838503121561182957600080fd5b611832836117ff565b9150611840602084016117ff565b90509250929050565b60006020828403121561185b57600080fd5b5035919050565b80356001600160a01b038116811461181157600080fd5b6000806040838503121561188c57600080fd5b61183283611862565b600080604083850312156118a857600080fd5b6118b183611862565b915061184060208401611862565b600080604083850312156118d257600080fd5b82359150602083013580151581146118e957600080fd5b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b60008160070b8360070b8061192f57634e487b7160e01b600052601260045260246000fd5b677fffffffffffffff1982146000198214161561194e5761194e6118f4565b90059392505050565b60008260070b8260070b028060070b9150808214611977576119776118f4565b5092915050565b6020808252601290820152714e6f7420656e6f7567682062616c616e636560701b604082015260600190565b600782810b9082900b03677fffffffffffffff198112677fffffffffffffff821317156103e6576103e66118f4565b600781810b9083900b01677fffffffffffffff8113677fffffffffffffff19821217156103e6576103e66118f4565b600060018201611a1a57611a1a6118f4565b5060010190565b6000825160005b81811015611a425760208186018101518583015201611a28565b506000920191825250919050565b600060208284031215611a6257600080fd5b81518060030b8114611a7357600080fd5b939250505056fea264697066735822122039cddb2ffbf3e0c16f10101b7d4c5da6a08ab02dc04d102283b79a6a6fce4e2f64736f6c63430008180033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c806372fb07771161008c578063bb110bf911610066578063bb110bf91461024d578063dd5813ee14610256578063f7888aec14610269578063f88d2047146102aa57600080fd5b806372fb077714610226578063925931fc1461022f57806392c029911461023857600080fd5b806303c4c2e1146100d45780630fc63d10146100fa5780632ec2add71461012557806335cea288146101385780634a8393f3146101c15780635f64b55b14610213575b600080fd5b6100e76100e2366004611816565b6102bd565b6040519081526020015b60405180910390f35b60005461010d906001600160a01b031681565b6040516001600160a01b0390911681526020016100f1565b6100e7610133366004611816565b6103ec565b61018a610146366004611849565b600260208190526000918252604090912080546001820154928201546003909201549092600781810b93600160401b909204900b916001600160a01b039091169085565b60408051958652600794850b60208701529290930b918401919091526001600160a01b03166060830152608082015260a0016100f1565b61018a6101cf366004611849565b600360208190526000918252604090912080546001820154600283015492909301549092600781810b93600160401b909204900b916001600160a01b039091169085565b60015461010d906001600160a01b031681565b6100e760065481565b6100e760075481565b61024b610246366004611879565b6104fd565b005b6100e760055481565b61024b610264366004611879565b610611565b610297610277366004611895565b600460209081526000928352604080842090915290825290205460070b81565b60405160079190910b81526020016100f1565b61024b6102b83660046118bf565b6106cd565b60006102c7610856565b60008360070b1361030f5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b60448201526064015b60405180910390fd5b60008260070b136103535760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b6044820152606401610306565b6103616305f5e1008361190a565b61036b9084611957565b3360009081526004602090815260408083206001546001600160a01b03168452909152902054600791820b910b12156103b65760405162461bcd60e51b81526004016103069061197e565b60006103c3338585610880565b905060008160070b13156103dc576103dc338583610b83565b5050600160085560005b92915050565b60006103f6610856565b60008360070b136104395760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b6044820152606401610306565b60008260070b1361047d5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b6044820152606401610306565b33600090815260046020908152604080832083546001600160a01b03168452909152902054600783810b91900b12156104c85760405162461bcd60e51b81526004016103069061197e565b60006104d5338585610d94565b905060008160070b13156104ee576104ee338583611071565b50506007546103e66001600855565b610505610856565b6000546001600160a01b038381169116148061052e57506001546001600160a01b038381169116145b61056a5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606401610306565b60008160070b136105ae5760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610306565b3360009081526004602090815260408083206001600160a01b0386168452909152902054600782810b91900b12156105f85760405162461bcd60e51b81526004016103069061197e565b610603338383611257565b61060d6001600855565b5050565b610619610856565b6000546001600160a01b038381169116148061064257506001546001600160a01b038381169116145b61067e5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606401610306565b60008160070b136106c25760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610306565b610603338383611316565b6106d5610856565b6000816106ef5760008381526003602052604090206106fe565b60008381526002602052604090205b60028101549091506001600160a01b03166107525760405162461bcd60e51b815260206004820152601460248201527313dc99195c88191bd95cc81b9bdd08195e1a5cdd60621b6044820152606401610306565b60028101546001600160a01b031633146107c35760405162461bcd60e51b815260206004820152602c60248201527f4f6e6c7920746865206f726465722063726561746f722063616e2063616e636560448201526b36103a3434b99037b93232b960a11b6064820152608401610306565b60018101546000600160401b90910460070b1361082e5760405162461bcd60e51b8152602060048201526024808201527f4f7264657220616c72656164792063616e63656c6c6564206f722066756c66696044820152631b1b195960e21b6064820152608401610306565b81156108425761083d816113e2565b61084b565b61084b81611565565b5061060d6001600855565b60026008540361087957604051633ee5aeb560e01b815260040160405180910390fd5b6002600855565b6006546000905b8015801590610899575060008360070b135b15610b795760008181526003602052604090206001810154600790810b9086900b12610b6d576001810154600090600786810b600160401b909204900b126108e157846108f1565b6001820154600160401b900460070b5b600183015490915060070b61090a6305f5e1008361190a565b6109149082611957565b6001600160a01b03808a1660009081526004602090815260408083206001549094168352929052908120805490919061095190849060070b6119aa565b82546001600160401b039182166101009390930a9283029190920219909116179055506001600160a01b0380891660009081526004602090815260408083208354909416835292905290812080548492906109b090849060070b6119d9565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055506305f5e100826109e7919061190a565b6109f19082611957565b60028401546001600160a01b03908116600090815260046020908152604080832060015490941683529290529081208054909190610a3390849060070b6119d9565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055508186610a6691906119aa565b6001840180549197508391600890610a89908490600160401b900460070b6119aa565b82546101009290920a6001600160401b03818102199093169190921691909102179055506001830154600284015460408051600786810b82529390930b60208401526001600160a01b038b8116848301529091166060830152517f3811c688c91a2195acbf84f4d5e7adc8d2f17ba048f1051955046e511411fd7d9181900360800190a16001830154600160401b900460070b600003610b665760038084015460009586526020829052604086208681556001810180546001600160801b03191690556002810180546001600160a01b0319169055909101949094555b5050610b73565b50610b79565b50610887565b6006555092915050565b60078054906000610b9383611a08565b909155505060055460005b8115801590610bc45750600082815260026020526040902060010154600785810b91900b135b15610be2575060008181526002602052604090206003015490610b9e565b6040805160a0810182526007805480835287820b60208085019182529288900b8486019081526001600160a01b03808c1660608701908152608087018a815260009586526002968790529790942095518655915160018601805492516001600160401b03908116600160401b026001600160801b031990941692169190911791909117905590519183018054929091166001600160a01b03199092169190911790559051600390910155610c9a6305f5e1008461190a565b610ca49085611957565b6001600160a01b03808716600090815260046020908152604080832060015490941683529290529081208054909190610ce190849060070b6119aa565b82546001600160401b039182166101009390930a92830291909202199091161790555060078054604080516001815260208101929092526001600160a01b0388169082015285820b60608201529084900b60808201527fddca83c332d5b33951e90d550eefc003b7a1efae1cdf8c4d684d4ccdf2cd8d599060a00160405180910390a180600003610d7757600754600555610d8d565b6007546000828152600260205260409020600301555b5050505050565b6005546000905b8015801590610dad575060008360070b135b156110675760008181526002602052604090206001810154600790810b9086900b1361105b576001810154600090600786810b600160401b909204900b12610df55784610e05565b6001820154600160401b900460070b5b905085610e166305f5e1008361190a565b610e209082611957565b6001600160a01b03808a16600090815260046020908152604080832060015490941683529290529081208054909190610e5d90849060070b6119d9565b82546001600160401b039182166101009390930a9283029190920219909116179055506001600160a01b038089166000908152600460209081526040808320835490941683529290529081208054849290610ebc90849060070b6119aa565b82546001600160401b039182166101009390930a92830291909202199091161790555060028301546001600160a01b039081166000908152600460209081526040808320835490941683529290529081208054849290610f2090849060070b6119d9565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055508186610f5391906119aa565b6001840180549197508391600890610f76908490600160401b900460070b6119aa565b82546101009290920a6001600160401b03818102199093169190921691909102179055506001830154600284015460408051600786810b82529390930b60208401526001600160a01b038b8116848301529091166060830152517f3811c688c91a2195acbf84f4d5e7adc8d2f17ba048f1051955046e511411fd7d9181900360800190a16001830154600160401b900460070b60000361105457600380840154600095865260026020819052604087208781556001810180546001600160801b031916905590810180546001600160a01b0319169055909101949094555b5050611061565b50611067565b50610d9b565b6005555092915050565b6007805490600061108183611a08565b909155505060065460005b81158015906110b25750600082815260036020526040902060010154600785810b91900b125b156110d15750600081815260036020819052604090912001549061108c565b6040805160a0810182526007805480835287820b602080850191825288840b8587019081526001600160a01b03808d1660608801818152608089018c8152600097885260038087528b89209a518b55965160018b01805496516001600160401b03908116600160401b026001600160801b031990981692169190911795909517909455516002890180549184166001600160a01b0319909216919091179055915196909301959095559382526004845284822082549091168252909252918120805486939192916111a49185910b6119aa565b82546001600160401b039182166101009390930a92830291909202199091161790555060078054604080516000815260208101929092526001600160a01b0388169082015285820b60608201529084900b60808201527fddca83c332d5b33951e90d550eefc003b7a1efae1cdf8c4d684d4ccdf2cd8d599060a00160405180910390a18060000361123a57600754600655610d8d565b600754600082815260036020819052604090912001555050505050565b6001600160a01b0380841660009081526004602090815260408083209386168352929052908120805483929061129190849060070b6119aa565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055506112c4823085846116c6565b604080516001600160a01b03858116825284166020820152600783900b8183015290517fd09be44e70d8a46d3b3b8da9701595dcaec29d75930065918923c7d9fd73eb589181900360600190a1505050565b611322828430846116c6565b6001600160a01b0380841660009081526004602090815260408083209386168352929052908120805483929061135c90849060070b6119d9565b92506101000a8154816001600160401b03021916908360070b6001600160401b03160217905550826001600160a01b03167f64e3b56a34ae45fe7d1f33e3d3da391a671e6043606ac9c811a6c1243023841d83836040516113d59291906001600160a01b0392909216825260070b602082015260400190565b60405180910390a2505050565b6005548154036113f957600381015460055561147e565b60055460009081526002602052604090205b815460038201541461147457806003015460000361145d5760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b6044820152606401610306565b60030154600090815260026020526040902061140b565b6003808301549101555b600181015461149c906305f5e10090600160401b900460070b61190a565b60018201546114ae919060070b611957565b60028201546001600160a01b039081166000908152600460209081526040808320600154909416835292905290812080549091906114f090849060070b6119d9565b82546001600160401b039182166101009390930a9283029190920219909116179055506001818101805467ffffffffffffffff60401b19169055815460405191825233917fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a4906020015b60405180910390a350565b60065481540361157c576003810154600655611604565b60065460009081526003602052604090205b81546003820154146115fa5780600301546000036115e05760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b6044820152606401610306565b60039081015460009081526020919091526040902061158e565b6003808301549101555b600181015460028201546001600160a01b039081166000908152600460209081526040808320835490941683529290529081208054600160401b909304600790810b93919291611657918591900b6119d9565b82546001600160401b039182166101009390930a92830291909202199091161790555060018101805467ffffffffffffffff60401b191690558054604051600081523391907fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a49060200161155a565b604080516001600160a01b038681166024830152858116604483015284166064820152600783900b6084808301919091528251808303909101815260a490910182526020810180516001600160e01b031663eca3691760e01b179052905160009182918291610167916117399190611a21565b6000604051808303816000865af19150503d8060008114611776576040519150601f19603f3d011682016040523d82523d6000602084013e61177b565b606091505b50915091508161178c5760156117a0565b808060200190518101906117a09190611a50565b9250600383900b6016146117f65760405162461bcd60e51b815260206004820152601b60248201527f5361666520746f6b656e207472616e73666572206661696c65642100000000006044820152606401610306565b50505050505050565b8035600781900b811461181157600080fd5b919050565b6000806040838503121561182957600080fd5b611832836117ff565b9150611840602084016117ff565b90509250929050565b60006020828403121561185b57600080fd5b5035919050565b80356001600160a01b038116811461181157600080fd5b6000806040838503121561188c57600080fd5b61183283611862565b600080604083850312156118a857600080fd5b6118b183611862565b915061184060208401611862565b600080604083850312156118d257600080fd5b82359150602083013580151581146118e957600080fd5b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b60008160070b8360070b8061192f57634e487b7160e01b600052601260045260246000fd5b677fffffffffffffff1982146000198214161561194e5761194e6118f4565b90059392505050565b60008260070b8260070b028060070b9150808214611977576119776118f4565b5092915050565b6020808252601290820152714e6f7420656e6f7567682062616c616e636560701b604082015260600190565b600782810b9082900b03677fffffffffffffff198112677fffffffffffffff821317156103e6576103e66118f4565b600781810b9083900b01677fffffffffffffff8113677fffffffffffffff19821217156103e6576103e66118f4565b600060018201611a1a57611a1a6118f4565b5060010190565b6000825160005b81811015611a425760208186018101518583015201611a28565b506000920191825250919050565b600060208284031215611a6257600080fd5b81518060030b8114611a7357600080fd5b939250505056fea264697066735822122039cddb2ffbf3e0c16f10101b7d4c5da6a08ab02dc04d102283b79a6a6fce4e2f64736f6c63430008180033", + "bytecode": "0x60806040523480156200001157600080fd5b5060405162001d6d38038062001d6d8339810160408190526200003491620001e1565b60016008819055600080546001600160a01b038086166001600160a01b03199283168117909355835490851691161790915562000072903062000092565b6001546200008a906001600160a01b03163062000092565b505062000276565b604080516001600160a01b038381166024830152841660448083019190915282518083039091018152606490910182526020810180516001600160e01b031663248a35ef60e11b17905290516000918291829161016791620000f5919062000219565b6000604051808303816000865af19150503d806000811462000134576040519150601f19603f3d011682016040523d82523d6000602084013e62000139565b606091505b5091509150816200014c57601562000162565b808060200190518101906200016291906200024a565b9250600383900b601614620001bd5760405162461bcd60e51b815260206004820152601f60248201527f536166652073696e676c65206173736f63696174696f6e206661696c65642100604482015260640160405180910390fd5b5050505050565b80516001600160a01b0381168114620001dc57600080fd5b919050565b60008060408385031215620001f557600080fd5b6200020083620001c4565b91506200021060208401620001c4565b90509250929050565b6000825160005b818110156200023c576020818601810151858301520162000220565b506000920191825250919050565b6000602082840312156200025d57600080fd5b81518060030b81146200026f57600080fd5b9392505050565b611ae780620002866000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c806372fb07771161008c578063bb110bf911610066578063bb110bf91461024d578063dd5813ee14610256578063f7888aec14610269578063f88d2047146102aa57600080fd5b806372fb077714610226578063925931fc1461022f57806392c029911461023857600080fd5b806303c4c2e1146100d45780630fc63d10146100fa5780632ec2add71461012557806335cea288146101385780634a8393f3146101c15780635f64b55b14610213575b600080fd5b6100e76100e236600461184d565b6102bd565b6040519081526020015b60405180910390f35b60005461010d906001600160a01b031681565b6040516001600160a01b0390911681526020016100f1565b6100e761013336600461184d565b6103f1565b61018a610146366004611880565b600260208190526000918252604090912080546001820154928201546003909201549092600781810b93600160401b909204900b916001600160a01b039091169085565b60408051958652600794850b60208701529290930b918401919091526001600160a01b03166060830152608082015260a0016100f1565b61018a6101cf366004611880565b600360208190526000918252604090912080546001820154600283015492909301549092600781810b93600160401b909204900b916001600160a01b039091169085565b60015461010d906001600160a01b031681565b6100e760065481565b6100e760075481565b61024b6102463660046118b0565b6104f3565b005b6100e760055481565b61024b6102643660046118b0565b610607565b6102976102773660046118cc565b600460209081526000928352604080842090915290825290205460070b81565b60405160079190910b81526020016100f1565b61024b6102b83660046118f6565b6106c3565b60006102c761084c565b60008360070b1361030f5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b60448201526064015b60405180910390fd5b60008260070b136103535760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b6044820152606401610306565b6103616305f5e10083611941565b61036b908461198e565b3360009081526004602090815260408083206001546001600160a01b03168452909152902054600791820b910b12156103b65760405162461bcd60e51b8152600401610306906119b5565b60006103c3338585610876565b905060008160070b13156103dc576103dc338583610b96565b50506007546103eb6001600855565b92915050565b60006103fb61084c565b60008360070b1361043e5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b6044820152606401610306565b60008260070b136104825760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b6044820152606401610306565b33600090815260046020908152604080832083546001600160a01b03168452909152902054600783810b91900b12156104cd5760405162461bcd60e51b8152600401610306906119b5565b60006104da338585610da7565b905060008160070b13156103dc576103dc3385836110a1565b6104fb61084c565b6000546001600160a01b038381169116148061052457506001546001600160a01b038381169116145b6105605760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606401610306565b60008160070b136105a45760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610306565b3360009081526004602090815260408083206001600160a01b0386168452909152902054600782810b91900b12156105ee5760405162461bcd60e51b8152600401610306906119b5565b6105f9338383611287565b6106036001600855565b5050565b61060f61084c565b6000546001600160a01b038381169116148061063857506001546001600160a01b038381169116145b6106745760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606401610306565b60008160070b136106b85760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610306565b6105f933838361134b565b6106cb61084c565b6000816106e55760008381526003602052604090206106f4565b60008381526002602052604090205b60028101549091506001600160a01b03166107485760405162461bcd60e51b815260206004820152601460248201527313dc99195c88191bd95cc81b9bdd08195e1a5cdd60621b6044820152606401610306565b60028101546001600160a01b031633146107b95760405162461bcd60e51b815260206004820152602c60248201527f4f6e6c7920746865206f726465722063726561746f722063616e2063616e636560448201526b36103a3434b99037b93232b960a11b6064820152608401610306565b60018101546000600160401b90910460070b136108245760405162461bcd60e51b8152602060048201526024808201527f4f7264657220616c72656164792063616e63656c6c6564206f722066756c66696044820152631b1b195960e21b6064820152608401610306565b81156108385761083381611402565b610841565b61084181611591565b506106036001600855565b60026008540361086f57604051633ee5aeb560e01b815260040160405180910390fd5b6002600855565b600654600090600a825b8215801590610892575060008560070b135b801561089d57508181105b15610b8a5760008381526003602052604090206001810154600790810b9088900b12610b71576001810154600090600788810b600160401b909204900b126108e557866108f5565b6001820154600160401b900460070b5b600183015490915060070b61090e6305f5e10083611941565b610918908261198e565b6001600160a01b03808c1660009081526004602090815260408083206001549094168352929052908120805490919061095590849060070b6119e1565b82546001600160401b039182166101009390930a9283029190920219909116179055506001600160a01b03808b1660009081526004602090815260408083208354909416835292905290812080548492906109b490849060070b611a10565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055506305f5e100826109eb9190611941565b6109f5908261198e565b60028401546001600160a01b03908116600090815260046020908152604080832060015490941683529290529081208054909190610a3790849060070b611a10565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055508188610a6a91906119e1565b6001840180549199508391600890610a8d908490600160401b900460070b6119e1565b82546101009290920a6001600160401b03818102199093169190921691909102179055506001830154600284015460408051600786810b82529390930b60208401526001600160a01b038d8116848301529091166060830152517f3811c688c91a2195acbf84f4d5e7adc8d2f17ba048f1051955046e511411fd7d9181900360800190a16001830154600160401b900460070b600003610b6a5760038084015460009788526020829052604088208881556001810180546001600160801b03191690556002810180546001600160a01b0319169055909101969096555b5050610b77565b50610b8a565b81610b8181611a3f565b92505050610880565b50506006555092915050565b60078054906000610ba683611a3f565b909155505060055460005b8115801590610bd75750600082815260026020526040902060010154600785810b91900b135b15610bf5575060008181526002602052604090206003015490610bb1565b6040805160a0810182526007805480835287820b60208085019182529288900b8486019081526001600160a01b03808c1660608701908152608087018a815260009586526002968790529790942095518655915160018601805492516001600160401b03908116600160401b026001600160801b031990941692169190911791909117905590519183018054929091166001600160a01b03199092169190911790559051600390910155610cad6305f5e10084611941565b610cb7908561198e565b6001600160a01b03808716600090815260046020908152604080832060015490941683529290529081208054909190610cf490849060070b6119e1565b82546001600160401b039182166101009390930a92830291909202199091161790555060078054604080516001815260208101929092526001600160a01b0388169082015285820b60608201529084900b60808201527fddca83c332d5b33951e90d550eefc003b7a1efae1cdf8c4d684d4ccdf2cd8d599060a00160405180910390a180600003610d8a57600754600555610da0565b6007546000828152600260205260409020600301555b5050505050565b600554600090600a825b8215801590610dc3575060008560070b135b8015610dce57508181105b156110955760008381526002602052604090206001810154600790810b9088900b1361107c576001810154600090600788810b600160401b909204900b12610e165786610e26565b6001820154600160401b900460070b5b905087610e376305f5e10083611941565b610e41908261198e565b6001600160a01b03808c16600090815260046020908152604080832060015490941683529290529081208054909190610e7e90849060070b611a10565b82546001600160401b039182166101009390930a9283029190920219909116179055506001600160a01b03808b166000908152600460209081526040808320835490941683529290529081208054849290610edd90849060070b6119e1565b82546001600160401b039182166101009390930a92830291909202199091161790555060028301546001600160a01b039081166000908152600460209081526040808320835490941683529290529081208054849290610f4190849060070b611a10565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055508188610f7491906119e1565b6001840180549199508391600890610f97908490600160401b900460070b6119e1565b82546101009290920a6001600160401b03818102199093169190921691909102179055506001830154600284015460408051600786810b82529390930b60208401526001600160a01b038d8116848301529091166060830152517f3811c688c91a2195acbf84f4d5e7adc8d2f17ba048f1051955046e511411fd7d9181900360800190a16001830154600160401b900460070b60000361107557600380840154600097885260026020819052604089208981556001810180546001600160801b031916905590810180546001600160a01b0319169055909101969096555b5050611082565b50611095565b8161108c81611a3f565b92505050610db1565b50506005555092915050565b600780549060006110b183611a3f565b909155505060065460005b81158015906110e25750600082815260036020526040902060010154600785810b91900b125b15611101575060008181526003602081905260409091200154906110bc565b6040805160a0810182526007805480835287820b602080850191825288840b8587019081526001600160a01b03808d1660608801818152608089018c8152600097885260038087528b89209a518b55965160018b01805496516001600160401b03908116600160401b026001600160801b031990981692169190911795909517909455516002890180549184166001600160a01b0319909216919091179055915196909301959095559382526004845284822082549091168252909252918120805486939192916111d49185910b6119e1565b82546001600160401b039182166101009390930a92830291909202199091161790555060078054604080516000815260208101929092526001600160a01b0388169082015285820b60608201529084900b60808201527fddca83c332d5b33951e90d550eefc003b7a1efae1cdf8c4d684d4ccdf2cd8d599060a00160405180910390a18060000361126a57600754600655610da0565b600754600082815260036020819052604090912001555050505050565b6001600160a01b038084166000908152600460209081526040808320938616835292905290812080548392906112c190849060070b6119e1565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055506112f4823085846116fd565b604080516001600160a01b03808616825284166020820152600783900b918101919091527fd09be44e70d8a46d3b3b8da9701595dcaec29d75930065918923c7d9fd73eb58906060015b60405180910390a1505050565b611357828430846116fd565b6001600160a01b0380841660009081526004602090815260408083209386168352929052908120805483929061139190849060070b611a10565b82546001600160401b039182166101009390930a928302919092021990911617905550604080516001600160a01b03808616825284166020820152600783900b918101919091527f64e3b56a34ae45fe7d1f33e3d3da391a671e6043606ac9c811a6c1243023841d9060600161133e565b60055481540361141957600381015460055561149e565b60055460009081526002602052604090205b815460038201541461149457806003015460000361147d5760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b6044820152606401610306565b60030154600090815260026020526040902061142b565b6003808301549101555b60018101546114bc906305f5e10090600160401b900460070b611941565b60018201546114ce919060070b61198e565b60028201546001600160a01b0390811660009081526004602090815260408083206001549094168352929052908120805490919061151090849060070b611a10565b82546001600160401b039182166101009390930a9283029190920219909116179055506001818101805467ffffffffffffffff60401b19169055815460408051928352602083019190915233908201527fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a4906060015b60405180910390a150565b6006548154036115a8576003810154600655611630565b60065460009081526003602052604090205b815460038201541461162657806003015460000361160c5760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b6044820152606401610306565b6003908101546000908152602091909152604090206115ba565b6003808301549101555b600181015460028201546001600160a01b039081166000908152600460209081526040808320835490941683529290529081208054600160401b909304600790810b93919291611683918591900b611a10565b82546001600160401b039182166101009390930a92830291909202199091161790555060018101805467ffffffffffffffff60401b1916905580546040805160008152602081019290925233908201527fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a490606001611586565b604080516001600160a01b038681166024830152858116604483015284166064820152600783900b6084808301919091528251808303909101815260a490910182526020810180516001600160e01b031663eca3691760e01b179052905160009182918291610167916117709190611a58565b6000604051808303816000865af19150503d80600081146117ad576040519150601f19603f3d011682016040523d82523d6000602084013e6117b2565b606091505b5091509150816117c35760156117d7565b808060200190518101906117d79190611a87565b9250600383900b60161461182d5760405162461bcd60e51b815260206004820152601b60248201527f5361666520746f6b656e207472616e73666572206661696c65642100000000006044820152606401610306565b50505050505050565b8035600781900b811461184857600080fd5b919050565b6000806040838503121561186057600080fd5b61186983611836565b915061187760208401611836565b90509250929050565b60006020828403121561189257600080fd5b5035919050565b80356001600160a01b038116811461184857600080fd5b600080604083850312156118c357600080fd5b61186983611899565b600080604083850312156118df57600080fd5b6118e883611899565b915061187760208401611899565b6000806040838503121561190957600080fd5b823591506020830135801515811461192057600080fd5b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b60008160070b8360070b8061196657634e487b7160e01b600052601260045260246000fd5b677fffffffffffffff198214600019821416156119855761198561192b565b90059392505050565b60008260070b8260070b028060070b91508082146119ae576119ae61192b565b5092915050565b6020808252601290820152714e6f7420656e6f7567682062616c616e636560701b604082015260600190565b600782810b9082900b03677fffffffffffffff198112677fffffffffffffff821317156103eb576103eb61192b565b600781810b9083900b01677fffffffffffffff8113677fffffffffffffff19821217156103eb576103eb61192b565b600060018201611a5157611a5161192b565b5060010190565b6000825160005b81811015611a795760208186018101518583015201611a5f565b506000920191825250919050565b600060208284031215611a9957600080fd5b81518060030b8114611aaa57600080fd5b939250505056fea26469706673582212205aa48bb78bfafd55a1384ef36fe88a0c230cf3807ce8924547abd90a0159119064736f6c63430008180033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c806372fb07771161008c578063bb110bf911610066578063bb110bf91461024d578063dd5813ee14610256578063f7888aec14610269578063f88d2047146102aa57600080fd5b806372fb077714610226578063925931fc1461022f57806392c029911461023857600080fd5b806303c4c2e1146100d45780630fc63d10146100fa5780632ec2add71461012557806335cea288146101385780634a8393f3146101c15780635f64b55b14610213575b600080fd5b6100e76100e236600461184d565b6102bd565b6040519081526020015b60405180910390f35b60005461010d906001600160a01b031681565b6040516001600160a01b0390911681526020016100f1565b6100e761013336600461184d565b6103f1565b61018a610146366004611880565b600260208190526000918252604090912080546001820154928201546003909201549092600781810b93600160401b909204900b916001600160a01b039091169085565b60408051958652600794850b60208701529290930b918401919091526001600160a01b03166060830152608082015260a0016100f1565b61018a6101cf366004611880565b600360208190526000918252604090912080546001820154600283015492909301549092600781810b93600160401b909204900b916001600160a01b039091169085565b60015461010d906001600160a01b031681565b6100e760065481565b6100e760075481565b61024b6102463660046118b0565b6104f3565b005b6100e760055481565b61024b6102643660046118b0565b610607565b6102976102773660046118cc565b600460209081526000928352604080842090915290825290205460070b81565b60405160079190910b81526020016100f1565b61024b6102b83660046118f6565b6106c3565b60006102c761084c565b60008360070b1361030f5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b60448201526064015b60405180910390fd5b60008260070b136103535760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b6044820152606401610306565b6103616305f5e10083611941565b61036b908461198e565b3360009081526004602090815260408083206001546001600160a01b03168452909152902054600791820b910b12156103b65760405162461bcd60e51b8152600401610306906119b5565b60006103c3338585610876565b905060008160070b13156103dc576103dc338583610b96565b50506007546103eb6001600855565b92915050565b60006103fb61084c565b60008360070b1361043e5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420507269636560981b6044820152606401610306565b60008260070b136104825760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420566f6c756d6560901b6044820152606401610306565b33600090815260046020908152604080832083546001600160a01b03168452909152902054600783810b91900b12156104cd5760405162461bcd60e51b8152600401610306906119b5565b60006104da338585610da7565b905060008160070b13156103dc576103dc3385836110a1565b6104fb61084c565b6000546001600160a01b038381169116148061052457506001546001600160a01b038381169116145b6105605760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606401610306565b60008160070b136105a45760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610306565b3360009081526004602090815260408083206001600160a01b0386168452909152902054600782810b91900b12156105ee5760405162461bcd60e51b8152600401610306906119b5565b6105f9338383611287565b6106036001600855565b5050565b61060f61084c565b6000546001600160a01b038381169116148061063857506001546001600160a01b038381169116145b6106745760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606401610306565b60008160070b136106b85760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610306565b6105f933838361134b565b6106cb61084c565b6000816106e55760008381526003602052604090206106f4565b60008381526002602052604090205b60028101549091506001600160a01b03166107485760405162461bcd60e51b815260206004820152601460248201527313dc99195c88191bd95cc81b9bdd08195e1a5cdd60621b6044820152606401610306565b60028101546001600160a01b031633146107b95760405162461bcd60e51b815260206004820152602c60248201527f4f6e6c7920746865206f726465722063726561746f722063616e2063616e636560448201526b36103a3434b99037b93232b960a11b6064820152608401610306565b60018101546000600160401b90910460070b136108245760405162461bcd60e51b8152602060048201526024808201527f4f7264657220616c72656164792063616e63656c6c6564206f722066756c66696044820152631b1b195960e21b6064820152608401610306565b81156108385761083381611402565b610841565b61084181611591565b506106036001600855565b60026008540361086f57604051633ee5aeb560e01b815260040160405180910390fd5b6002600855565b600654600090600a825b8215801590610892575060008560070b135b801561089d57508181105b15610b8a5760008381526003602052604090206001810154600790810b9088900b12610b71576001810154600090600788810b600160401b909204900b126108e557866108f5565b6001820154600160401b900460070b5b600183015490915060070b61090e6305f5e10083611941565b610918908261198e565b6001600160a01b03808c1660009081526004602090815260408083206001549094168352929052908120805490919061095590849060070b6119e1565b82546001600160401b039182166101009390930a9283029190920219909116179055506001600160a01b03808b1660009081526004602090815260408083208354909416835292905290812080548492906109b490849060070b611a10565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055506305f5e100826109eb9190611941565b6109f5908261198e565b60028401546001600160a01b03908116600090815260046020908152604080832060015490941683529290529081208054909190610a3790849060070b611a10565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055508188610a6a91906119e1565b6001840180549199508391600890610a8d908490600160401b900460070b6119e1565b82546101009290920a6001600160401b03818102199093169190921691909102179055506001830154600284015460408051600786810b82529390930b60208401526001600160a01b038d8116848301529091166060830152517f3811c688c91a2195acbf84f4d5e7adc8d2f17ba048f1051955046e511411fd7d9181900360800190a16001830154600160401b900460070b600003610b6a5760038084015460009788526020829052604088208881556001810180546001600160801b03191690556002810180546001600160a01b0319169055909101969096555b5050610b77565b50610b8a565b81610b8181611a3f565b92505050610880565b50506006555092915050565b60078054906000610ba683611a3f565b909155505060055460005b8115801590610bd75750600082815260026020526040902060010154600785810b91900b135b15610bf5575060008181526002602052604090206003015490610bb1565b6040805160a0810182526007805480835287820b60208085019182529288900b8486019081526001600160a01b03808c1660608701908152608087018a815260009586526002968790529790942095518655915160018601805492516001600160401b03908116600160401b026001600160801b031990941692169190911791909117905590519183018054929091166001600160a01b03199092169190911790559051600390910155610cad6305f5e10084611941565b610cb7908561198e565b6001600160a01b03808716600090815260046020908152604080832060015490941683529290529081208054909190610cf490849060070b6119e1565b82546001600160401b039182166101009390930a92830291909202199091161790555060078054604080516001815260208101929092526001600160a01b0388169082015285820b60608201529084900b60808201527fddca83c332d5b33951e90d550eefc003b7a1efae1cdf8c4d684d4ccdf2cd8d599060a00160405180910390a180600003610d8a57600754600555610da0565b6007546000828152600260205260409020600301555b5050505050565b600554600090600a825b8215801590610dc3575060008560070b135b8015610dce57508181105b156110955760008381526002602052604090206001810154600790810b9088900b1361107c576001810154600090600788810b600160401b909204900b12610e165786610e26565b6001820154600160401b900460070b5b905087610e376305f5e10083611941565b610e41908261198e565b6001600160a01b03808c16600090815260046020908152604080832060015490941683529290529081208054909190610e7e90849060070b611a10565b82546001600160401b039182166101009390930a9283029190920219909116179055506001600160a01b03808b166000908152600460209081526040808320835490941683529290529081208054849290610edd90849060070b6119e1565b82546001600160401b039182166101009390930a92830291909202199091161790555060028301546001600160a01b039081166000908152600460209081526040808320835490941683529290529081208054849290610f4190849060070b611a10565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055508188610f7491906119e1565b6001840180549199508391600890610f97908490600160401b900460070b6119e1565b82546101009290920a6001600160401b03818102199093169190921691909102179055506001830154600284015460408051600786810b82529390930b60208401526001600160a01b038d8116848301529091166060830152517f3811c688c91a2195acbf84f4d5e7adc8d2f17ba048f1051955046e511411fd7d9181900360800190a16001830154600160401b900460070b60000361107557600380840154600097885260026020819052604089208981556001810180546001600160801b031916905590810180546001600160a01b0319169055909101969096555b5050611082565b50611095565b8161108c81611a3f565b92505050610db1565b50506005555092915050565b600780549060006110b183611a3f565b909155505060065460005b81158015906110e25750600082815260036020526040902060010154600785810b91900b125b15611101575060008181526003602081905260409091200154906110bc565b6040805160a0810182526007805480835287820b602080850191825288840b8587019081526001600160a01b03808d1660608801818152608089018c8152600097885260038087528b89209a518b55965160018b01805496516001600160401b03908116600160401b026001600160801b031990981692169190911795909517909455516002890180549184166001600160a01b0319909216919091179055915196909301959095559382526004845284822082549091168252909252918120805486939192916111d49185910b6119e1565b82546001600160401b039182166101009390930a92830291909202199091161790555060078054604080516000815260208101929092526001600160a01b0388169082015285820b60608201529084900b60808201527fddca83c332d5b33951e90d550eefc003b7a1efae1cdf8c4d684d4ccdf2cd8d599060a00160405180910390a18060000361126a57600754600655610da0565b600754600082815260036020819052604090912001555050505050565b6001600160a01b038084166000908152600460209081526040808320938616835292905290812080548392906112c190849060070b6119e1565b92506101000a8154816001600160401b03021916908360070b6001600160401b031602179055506112f4823085846116fd565b604080516001600160a01b03808616825284166020820152600783900b918101919091527fd09be44e70d8a46d3b3b8da9701595dcaec29d75930065918923c7d9fd73eb58906060015b60405180910390a1505050565b611357828430846116fd565b6001600160a01b0380841660009081526004602090815260408083209386168352929052908120805483929061139190849060070b611a10565b82546001600160401b039182166101009390930a928302919092021990911617905550604080516001600160a01b03808616825284166020820152600783900b918101919091527f64e3b56a34ae45fe7d1f33e3d3da391a671e6043606ac9c811a6c1243023841d9060600161133e565b60055481540361141957600381015460055561149e565b60055460009081526002602052604090205b815460038201541461149457806003015460000361147d5760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b6044820152606401610306565b60030154600090815260026020526040902061142b565b6003808301549101555b60018101546114bc906305f5e10090600160401b900460070b611941565b60018201546114ce919060070b61198e565b60028201546001600160a01b0390811660009081526004602090815260408083206001549094168352929052908120805490919061151090849060070b611a10565b82546001600160401b039182166101009390930a9283029190920219909116179055506001818101805467ffffffffffffffff60401b19169055815460408051928352602083019190915233908201527fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a4906060015b60405180910390a150565b6006548154036115a8576003810154600655611630565b60065460009081526003602052604090205b815460038201541461162657806003015460000361160c5760405162461bcd60e51b815260206004820152600f60248201526e13dc99195c881b9bdd08199bdd5b99608a1b6044820152606401610306565b6003908101546000908152602091909152604090206115ba565b6003808301549101555b600181015460028201546001600160a01b039081166000908152600460209081526040808320835490941683529290529081208054600160401b909304600790810b93919291611683918591900b611a10565b82546001600160401b039182166101009390930a92830291909202199091161790555060018101805467ffffffffffffffff60401b1916905580546040805160008152602081019290925233908201527fcfa919375acf04933787aa7f7b25d71adf2e92839529dad777b47ff2cd0827a490606001611586565b604080516001600160a01b038681166024830152858116604483015284166064820152600783900b6084808301919091528251808303909101815260a490910182526020810180516001600160e01b031663eca3691760e01b179052905160009182918291610167916117709190611a58565b6000604051808303816000865af19150503d80600081146117ad576040519150601f19603f3d011682016040523d82523d6000602084013e6117b2565b606091505b5091509150816117c35760156117d7565b808060200190518101906117d79190611a87565b9250600383900b60161461182d5760405162461bcd60e51b815260206004820152601b60248201527f5361666520746f6b656e207472616e73666572206661696c65642100000000006044820152606401610306565b50505050505050565b8035600781900b811461184857600080fd5b919050565b6000806040838503121561186057600080fd5b61186983611836565b915061187760208401611836565b90509250929050565b60006020828403121561189257600080fd5b5035919050565b80356001600160a01b038116811461184857600080fd5b600080604083850312156118c357600080fd5b61186983611899565b600080604083850312156118df57600080fd5b6118e883611899565b915061187760208401611899565b6000806040838503121561190957600080fd5b823591506020830135801515811461192057600080fd5b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b60008160070b8360070b8061196657634e487b7160e01b600052601260045260246000fd5b677fffffffffffffff198214600019821416156119855761198561192b565b90059392505050565b60008260070b8260070b028060070b91508082146119ae576119ae61192b565b5092915050565b6020808252601290820152714e6f7420656e6f7567682062616c616e636560701b604082015260600190565b600782810b9082900b03677fffffffffffffff198112677fffffffffffffff821317156103eb576103eb61192b565b600781810b9083900b01677fffffffffffffff8113677fffffffffffffff19821217156103eb576103eb61192b565b600060018201611a5157611a5161192b565b5060010190565b6000825160005b81811015611a795760208186018101518583015201611a5f565b506000920191825250919050565b600060208284031215611a9957600080fd5b81518060030b8114611aaa57600080fd5b939250505056fea26469706673582212205aa48bb78bfafd55a1384ef36fe88a0c230cf3807ce8924547abd90a0159119064736f6c63430008180033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/data/abis/OrderBookHTS.json b/data/abis/OrderBookHTS.json index 7b0292b..df8ec2a 100644 --- a/data/abis/OrderBookHTS.json +++ b/data/abis/OrderBookHTS.json @@ -7,7 +7,7 @@ "anonymous": false, "inputs": [ { - "indexed": true, + "indexed": false, "internalType": "address", "name": "trader", "type": "address" @@ -75,13 +75,13 @@ "type": "bool" }, { - "indexed": true, + "indexed": false, "internalType": "uint256", "name": "orderId", "type": "uint256" }, { - "indexed": true, + "indexed": false, "internalType": "address", "name": "trader", "type": "address" diff --git a/package.json b/package.json index 8bb394c..c4e8419 100644 --- a/package.json +++ b/package.json @@ -27,10 +27,12 @@ "@typechain/ethers-v6": "^0.5.0", "@typechain/hardhat": "^9.0.0", "@types/chai": "^4.2.0", + "@types/elliptic": "^6.4.18", "@types/mocha": "^9.1.0", "@types/node": "^18.0.0", "chai": "^4.2.0", "dotenv": "^16.4.5", + "elliptic": "^6.5.5", "eslint": "^8.57.0", "eslint-config-standard-with-typescript": "^43.0.1", "eslint-plugin-import": "^2.29.1", diff --git a/test/orderbook/load/exchange.load-2.test.ts b/test/orderbook/load/exchange.load-2.test.ts new file mode 100644 index 0000000..d052082 --- /dev/null +++ b/test/orderbook/load/exchange.load-2.test.ts @@ -0,0 +1,348 @@ +import { ethers } from 'hardhat'; +import { expect } from 'chai'; +import Utils, { Operator } from '../../utils'; +import { AccountId, PrivateKey, TokenId, ContractId, Client, ContractFunctionParameters, TransactionRecord, AccountCreateTransaction, Hbar, StatusError } from '@hashgraph/sdk'; +import { AbiCoder } from 'ethers'; +import { bytecode as ExchangeHTSbytecode } from '../../../data/abis/ExchangeHTS.json'; +import elliptic from 'elliptic'; + +const depositToken = async (client: Client, operator: Operator, contract: ContractId, tokenId: TokenId | string, amount: number) => { + client.setOperator( + operator.accountId, + operator.key + ); + + if (typeof tokenId != 'string') { + tokenId = `0x${tokenId.toSolidityAddress()}`; + } + + const functionName = "deposit"; + const params = new ContractFunctionParameters() + .addAddress(tokenId) + .addInt64(amount.toString()); + + const { receipt, record } = await Utils.executeContract(client, operator, contract, functionName, params); + + if (receipt.status._code != 22) { + throw new Error('Error depositing token status code' + receipt.status._code); + } + + return {receipt, record}; +} + +const placeBuyOrder = async (client: Client, operator: Operator, contract: ContractId, price: number, volume: number) => { + client.setOperator( + operator.accountId, + operator.key + ); + const functionName = "placeBuyOrder"; + const params = new ContractFunctionParameters() + .addInt64(price.toString()) + .addInt64(volume.toString()); + + const { receipt, record } = await Utils.executeContract(client, operator, contract, functionName, params, { gas : 600_000}); + + if (receipt.status._code != 22) { + throw new Error('Error depositing token status code' + receipt.status._code); + } + + return { receipt, record }; +} + +const queryBalanceOfExchange = async (client: Client, contract: ContractId, userAddress: string, tokenAddress: string) => { + const functionName = "balanceOf"; + const params = new ContractFunctionParameters() + .addAddress(userAddress) + .addAddress(tokenAddress); + + // Decode the result + const result = await Utils.queryContract(client, contract, functionName, params); + const balance = result.getInt64(0); // Adjust based on your function's return type + return balance; +} + +const placeSellOrder = async (client: Client, operator: Operator, contract: ContractId, price: number, volume: number) => { + client.setOperator( + operator.accountId, + operator.key + ); + const functionName = "placeSellOrder"; + const params = new ContractFunctionParameters() + .addInt64(price.toString()) + .addInt64(volume.toString()); + + const { receipt, record } = await Utils.executeContract(client, operator, contract, functionName, params, { gas : 600_000}); + + if (receipt.status._code != 22) { + throw new Error('Error depositing token status code' + receipt.status._code); + } + + return { receipt, record }; +} + +const eventsEmited = (record: TransactionRecord, eventTopic: string) => { + return record.contractFunctionResult?.logs.reduce((acc: Uint8Array[], log) => { + for (const topic of log.topics) { + const pTopic = `0x${Buffer.from(topic).toString('hex')}`; + if (pTopic === eventTopic) { + acc.push(log.data); + } + } + return acc; + }, []) +} + +function getRandomInt(min: number, max: number) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +function returnOneOf(list: T[], except?: T) { + if (list.length === 0) { + throw new Error('returnOneOf: empty list'); + } + + let filteredList = except !== undefined ? list.filter(item => item !== except) : list; + + if (filteredList.length === 0) { + return list[0]; // Handle case where all items are excluded + } + + const randomIndex = Math.floor(Math.random() * filteredList.length); + return filteredList[randomIndex]; +} + +const createECDSAKeyPair = () => { + const EC = elliptic.ec; + const ec = new EC('secp256k1'); + const keyPair = ec.genKeyPair(); + const privateKey = keyPair.getPrivate('hex'); + const publicKey = keyPair.getPublic('hex'); + + return { privateKey, publicKey } +} + +const createAccount = async (client: Client, operator: Operator): Promise => { + + client.setOperator(operator.accountId, operator.key); + + const key = PrivateKey.fromStringECDSA(createECDSAKeyPair().privateKey); + const accountCreate = new AccountCreateTransaction() + .setKey(key) + .setInitialBalance(new Hbar(3)) + .setTransactionValidDuration(180) + .freezeWith(client); + + const tx = await accountCreate.execute(client); + const receipt = await tx.getReceipt(client); + + console.log(`- account created with id ${receipt.accountId}`) + + return { accountId: receipt.accountId as AccountId, key, address: `0x${receipt.accountId?.toSolidityAddress()}` }; +} + +const retryThat = async (action: string, maxRetries: number, retryDelay: number, callback: Function) => { + let attempt = 0; + while (attempt < maxRetries) { + try{ + const result = await callback(); + + return result; + } catch (error) { + //@ts-ignore + console.error(`---- Error ${action}: ${error?.message} ----`); + + if (error instanceof StatusError && error.status.toString() === 'TRANSACTION_EXPIRED') { + attempt++; + console.warn(`Transaction expired. Retry attempt ${attempt}/${maxRetries}`); + if (attempt < maxRetries) { + await new Promise(resolve => setTimeout(resolve, retryDelay)); + } + } else { + throw error; + } + } + } +} + +async function deployExchangeFixture() { + const client = Client.forTestnet().setMaxAttempts(10000) + //Create your local client + // const node = {"127.0.0.1:50211": new AccountId(3)}; + // const client = Client.forNetwork(node).setMirrorNetwork("127.0.0.1:5600") + // .setMaxAttempts(100_000_000) + // .setMaxBackoff(100_000_000); + + const operatorAccountId = AccountId.fromString(process.env.ACCOUNT_ID as string); + const operatorPrivateKey = PrivateKey.fromStringECDSA(process.env.PRIVATE_KEY as string); + + + const operator = { + accountId: operatorAccountId, + key: operatorPrivateKey, + address: '0x' + (operatorAccountId.toSolidityAddress().toLowerCase()) + } + + client.setOperator( + operator.accountId, + operator.key + ); + + // client.setOperator(AccountId.fromString("0.0.2"),PrivateKey.fromStringED25519("302e020100300506032b65700422042091132178e72057a1d7528025956fe39b0b847f200ab59b2fdd367017f3087137")); + + const idTokenA = TokenId.fromSolidityAddress("0x000000000000000000000000000000000043cca1"); + const idTokenB = TokenId.fromSolidityAddress("0x000000000000000000000000000000000043cca2"); + const exchangeId = ContractId.fromString("0.0.4443300"); + // const idTokenA = await Utils.createFungibleToken(client, operator.accountId, operator.key, 'Test Token A', 'TOKEN_A'); + // const idTokenB = await Utils.createFungibleToken(client, operator.accountId, operator.key, 'Test Token B', 'TOKEN_B'); + + const addressTokenA = '0x' + idTokenA.toSolidityAddress(); + const addressTokenB = '0x' + idTokenB.toSolidityAddress(); + + // const exchangeId = await Utils.deployContract( + // client, + // operator, + // ExchangeHTSbytecode, + // [addressTokenA, addressTokenB] + // ); + + // console.log(`deployed exchange at ${exchangeId} or ${exchangeId.toSolidityAddress()}`) + + const toTokenA = (_number: number) => { + return _number * 10 ** 8; + } + + const toTokenB = (_number: number) => { + return _number * 10 ** 8; + } + + const fromTokenA = (_number: number) => { + return _number / 10 ** 8; + } + + const fromTokenB = (_number: number) => { + return _number / 10 ** 8; + } + + const minting = [ + Utils.tokenMint(client, operator, idTokenA, toTokenA(100_000_000)), + Utils.tokenMint(client, operator, idTokenB, toTokenB(100_000_000)), + ]; + + await Promise.all(minting); + + return { + client, + operator, + exchangeId, + idTokenA, + idTokenB, + toTokenA, + toTokenB, + addressTokenA, + addressTokenB, + fromTokenA, + fromTokenB + } +} + +describe('Load Test Exchange HTS', () => { + describe('Exchange', () => { + it('should load test', async () => { + const { client, operator, exchangeId, idTokenB, idTokenA, toTokenB, toTokenA, addressTokenA, addressTokenB, fromTokenA, fromTokenB } = await deployExchangeFixture(); + + function hasTradeEvent (record: TransactionRecord) { + const tradeEvent = eventsEmited(record, ethers.id("Trade(int64,int64,address,address)")) as Uint8Array []; + if (tradeEvent.length){ + for( const trade of tradeEvent) { + const parsedLogTrade = AbiCoder.defaultAbiCoder().decode( + ["uint256", "uint256", "address"], + trade + ); + console.log(`-- Trade happend with ${parsedLogTrade.toString()}`); + } + } + + return tradeEvent.length; + } + + const list = new Array(1300).fill(0); + const userListSell = (await Promise.allSettled(list.slice(0, list.length / 2).map(async (_, index) => { + const price = toTokenB(getRandomInt(1000, 1020)) + const amount = toTokenA(getRandomInt(1, 5)); + + return retryThat('Creating Sell User', 5, 200, async () => { + const newAccount = await createAccount(client, operator); + await Utils.associateTokenToAccount(client, idTokenA, newAccount); + await Utils.transferToken(client, idTokenA, operator, newAccount.accountId, amount); + await Utils.approveToken(client, idTokenA, newAccount, exchangeId, (amount)); + await depositToken(client, newAccount, exchangeId, idTokenA, amount); + return { account: newAccount, price: price, amount: amount } + }); + + }))) + .filter(p => p.status === 'fulfilled') + // @ts-ignore + .map((p) => p.value); + + const userListBuy = (await Promise.allSettled(list.slice(list.length / 2).map(async (_, index) => { + const price = getRandomInt(1000, 1020); + const amount = getRandomInt(1, 5); + + return retryThat('Creating Buy User', 5, 200, async () => { + const newAccount = await createAccount(client, operator); + await Utils.associateTokenToAccount(client, idTokenB, newAccount); + await Utils.transferToken(client, idTokenB, operator, newAccount.accountId, toTokenB(price * amount)); + await Utils.approveToken(client, idTokenB, newAccount, exchangeId, toTokenB(price * amount)); + await depositToken(client, newAccount, exchangeId, idTokenB, toTokenB(price * amount)); + + return { account: newAccount, price: toTokenB(price), amount: toTokenA(amount) } + }); + + }))) + .filter(p => p.status === 'fulfilled') + // @ts-ignore + .map((p) => p.value); + + const buyOrders = userListBuy.map(async (trader, index) => { + await new Promise((res) => { setTimeout(() => {res(true)}, 200 * index)}); + const { record: recordBuy} = await placeBuyOrder(client, trader.account, exchangeId, trader.price, trader.amount); + hasTradeEvent(recordBuy); + return trader; + }); + + const sellOrders = userListSell.map(async (trader, index) => { + await new Promise((res) => { setTimeout(() => {res(true)}, 200 * (index + 1))}); + const { record: recordSell } = await placeSellOrder(client, trader.account, exchangeId, trader.price, trader.amount); + hasTradeEvent(recordSell); + return trader; + }) + + try { + const results = await Promise.allSettled([...buyOrders, ...sellOrders]); + const rejected = results.filter(r => r.status === 'rejected'); + const fulfilled = results.filter(r => r.status === 'fulfilled'); + + + console.log({ + status: 'rejected', + len : rejected.length, + // @ts-ignore + ids: rejected.map(rej => rej?.reason?.transactionId) + }) + + console.log({ + fulfilled: { + len: fulfilled.length, + } + }); + + } catch (error) { + console.error("Error placing orders"); + console.error(error); + expect.fail('Error placing orders'); + } + + }); + }); +}); + diff --git a/test/orderbook/load/exchange.load.test.ts b/test/orderbook/load/exchange.load.test.ts new file mode 100644 index 0000000..9de8452 --- /dev/null +++ b/test/orderbook/load/exchange.load.test.ts @@ -0,0 +1,413 @@ +import { ethers } from 'hardhat'; +import { expect } from 'chai'; +import Utils, { Operator } from '../../utils'; +import { AccountId, PrivateKey, TokenId, ContractId, Client, ContractFunctionParameters, TransactionRecord, AccountCreateTransaction, Hbar } from '@hashgraph/sdk'; +import { AbiCoder } from 'ethers'; +import { bytecode as ExchangeHTSbytecode } from '../../../data/abis/ExchangeHTS.json'; +import elliptic from 'elliptic'; + +const depositToken = async (client: Client, operator: Operator, contract: ContractId, tokenId: TokenId | string, amount: number) => { + client.setOperator( + operator.accountId, + operator.key + ); + + if (typeof tokenId != 'string') { + tokenId = `0x${tokenId.toSolidityAddress()}`; + } + + const functionName = "deposit"; + const params = new ContractFunctionParameters() + .addAddress(tokenId) + .addInt64(amount.toString()); + + const { receipt, record } = await Utils.executeContract(client, operator, contract, functionName, params); + + if (receipt.status._code != 22) { + throw new Error('Error depositing token status code' + receipt.status._code); + } + + return {receipt, record}; +} + +const placeBuyOrder = async (client: Client, operator: Operator, contract: ContractId, price: number, volume: number) => { + client.setOperator( + operator.accountId, + operator.key + ); + const functionName = "placeBuyOrder"; + const params = new ContractFunctionParameters() + .addInt64(price.toString()) + .addInt64(volume.toString()); + + const { receipt, record } = await Utils.executeContract(client, operator, contract, functionName, params, { gas : 600_000}); + + if (receipt.status._code != 22) { + throw new Error('Error depositing token status code' + receipt.status._code); + } + + return { receipt, record }; +} + +const queryBalanceOfExchange = async (client: Client, contract: ContractId, userAddress: string, tokenAddress: string) => { + const functionName = "balanceOf"; + const params = new ContractFunctionParameters() + .addAddress(userAddress) + .addAddress(tokenAddress); + + // Decode the result + const result = await Utils.queryContract(client, contract, functionName, params); + const balance = result.getInt64(0); // Adjust based on your function's return type + return balance; +} + +const placeSellOrder = async (client: Client, operator: Operator, contract: ContractId, price: number, volume: number) => { + client.setOperator( + operator.accountId, + operator.key + ); + const functionName = "placeSellOrder"; + const params = new ContractFunctionParameters() + .addInt64(price.toString()) + .addInt64(volume.toString()); + + const { receipt, record } = await Utils.executeContract(client, operator, contract, functionName, params, { gas : 600_000}); + + if (receipt.status._code != 22) { + throw new Error('Error depositing token status code' + receipt.status._code); + } + + return { receipt, record }; +} + +const eventsEmited = (record: TransactionRecord, eventTopic: string) => { + return record.contractFunctionResult?.logs.reduce((acc: Uint8Array[], log) => { + for (const topic of log.topics) { + const pTopic = `0x${Buffer.from(topic).toString('hex')}`; + if (pTopic === eventTopic) { + acc.push(log.data); + } + } + return acc; + }, []) +} + +function getRandomInt(min: number, max: number) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +function returnOneOf(list: T[], except?: T) { + if (list.length === 0) { + throw new Error('returnOneOf: empty list'); + } + + let filteredList = except !== undefined ? list.filter(item => item !== except) : list; + + if (filteredList.length === 0) { + return list[0]; // Handle case where all items are excluded + } + + const randomIndex = Math.floor(Math.random() * filteredList.length); + return filteredList[randomIndex]; +} + + +const createECDSAKeyPair = () => { + const EC = elliptic.ec; + const ec = new EC('secp256k1'); + const keyPair = ec.genKeyPair(); + const privateKey = keyPair.getPrivate('hex'); + const publicKey = keyPair.getPublic('hex'); + + return { privateKey, publicKey } +} + +const createAccount = async (client: Client, operator: Operator): Promise => { + + client.setOperator(operator.accountId, operator.key); + + const key = PrivateKey.fromStringECDSA(createECDSAKeyPair().privateKey); + const accountCreate = new AccountCreateTransaction() + .setKey(key) + .setInitialBalance(new Hbar(1000)) + .freezeWith(client); + + const tx = await accountCreate.execute(client); + const receipt = await tx.getReceipt(client); + + console.log(`- account created with id ${receipt.accountId}`) + + return { accountId: receipt.accountId as AccountId, key, address: `0x${receipt.accountId?.toSolidityAddress()}` }; +} + +async function deployExchangeFixture() { + const node = {"127.0.0.1:50211": new AccountId(3)}; + const client = Client.forNetwork(node).setMirrorNetwork("127.0.0.1:5600").setMaxAttempts(100_000_000).setMaxBackoff(100_000_000); + + const operatorAccountId = AccountId.fromString(process.env.ACCOUNT_ID as string); + const operatorPrivateKey = PrivateKey.fromStringED25519(process.env.PRIVATE_KEY as string); + + const aliceAccountId = AccountId.fromString(process.env.ALICE_ACCOUNT_ID as string); + const alicePrivateKey = PrivateKey.fromStringED25519(process.env.ALICE_KEY as string); + + const bobAccountId = AccountId.fromString(process.env.BOB_ACCOUNT_ID as string); + const bobPrivateKey = PrivateKey.fromStringECDSA(process.env.BOB_KEY as string); + + const charlieAccountId = AccountId.fromString(process.env.CHARLIE_ACCOUNT_ID as string); + const charliePrivateKey = PrivateKey.fromStringECDSA(process.env.CHARLIE_KEY as string); + + const davidAccountId = AccountId.fromString(process.env.DAVID_ACCOUNT_ID as string); + const davidPrivateKey = PrivateKey.fromStringED25519(process.env.DAVID_KEY as string); + + const operator = { + accountId: operatorAccountId, + key: operatorPrivateKey, + address: '0x' + (operatorAccountId.toSolidityAddress().toLowerCase()) + } + + + // { + // accountId: aliceAccountId, + // key: alicePrivateKey, + // address: '0x' + (aliceAccountId.toSolidityAddress().toLowerCase()) + // } + + // const bob = { + // accountId: bobAccountId, + // key: bobPrivateKey, + // address: '0x' + (bobAccountId.toSolidityAddress().toLowerCase()) + // } + + // const charlie = { + // accountId: charlieAccountId, + // key: charliePrivateKey, + // address: '0x' + (charlieAccountId.toSolidityAddress().toLowerCase()) + // } + + // const david = { + // accountId: davidAccountId, + // key: davidPrivateKey, + // address: '0x' + (davidAccountId.toSolidityAddress().toLowerCase()) + // } + + // client.setOperator( + // operator.accountId, + // operator.key + // ); + + client.setOperator(AccountId.fromString("0.0.2"),PrivateKey.fromStringED25519("302e020100300506032b65700422042091132178e72057a1d7528025956fe39b0b847f200ab59b2fdd367017f3087137")); + + const alice = await createAccount(client, operator) + const bob = await createAccount(client, operator) + const charlie = await createAccount(client, operator) + const david = await createAccount(client, operator) + + // const idTokenA = TokenId.fromString('0.0.4421954'); + // const idTokenB = TokenId.fromString('0.0.4421955'); + // const exchangeId = ContractId.fromString("0.0.4422160"); + const idTokenA = await Utils.createFungibleToken(client, operator.accountId, operator.key, 'Test Token A', 'TOKEN_A'); + const idTokenB = await Utils.createFungibleToken(client, operator.accountId, operator.key, 'Test Token B', 'TOKEN_B'); + + const addressTokenA = '0x' + idTokenA.toSolidityAddress(); + const addressTokenB = '0x' + idTokenB.toSolidityAddress(); + + const exchangeId = await Utils.deployContract( + client, + operator, + ExchangeHTSbytecode, + [addressTokenA, addressTokenB] + ); + + console.log(`deployed exchange at ${exchangeId} or ${exchangeId.toSolidityAddress()}`) + + const toTokenA = (_number: number) => { + return _number * 10 ** 8; + } + + const toTokenB = (_number: number) => { + return _number * 10 ** 8; + } + + const fromTokenA = (_number: number) => { + return _number / 10 ** 8; + } + + const fromTokenB = (_number: number) => { + return _number / 10 ** 8; + } + + const minting = [ + Utils.tokenMint(client, operator, idTokenA, toTokenA(1_000_000 * 4)), + Utils.tokenMint(client, operator, idTokenB, toTokenB(1_000_000 * 4)), + ]; + + await Promise.all(minting); + + const associations = [ + // token A + Utils.associateTokenToAccount(client, idTokenA, alice), + Utils.associateTokenToAccount(client, idTokenA, bob), + Utils.associateTokenToAccount(client, idTokenA, charlie), + Utils.associateTokenToAccount(client, idTokenA, david), + // token B + Utils.associateTokenToAccount(client, idTokenB, alice), + Utils.associateTokenToAccount(client, idTokenB, bob), + Utils.associateTokenToAccount(client, idTokenB, charlie), + Utils.associateTokenToAccount(client, idTokenB, david), + ]; + + await Promise.all(associations); + + const transfers = [ + // token A + Utils.transferToken(client, idTokenA, operator, alice.accountId, toTokenA(1_000_000)), + Utils.transferToken(client, idTokenA, operator, bob.accountId, toTokenA(1_000_000)), + Utils.transferToken(client, idTokenA, operator, charlie.accountId, toTokenA(1_000_000)), + Utils.transferToken(client, idTokenA, operator, david.accountId, toTokenA(1_000_000)), + // // token B + Utils.transferToken(client, idTokenB, operator, alice.accountId, toTokenB(1_000_000)), + Utils.transferToken(client, idTokenB, operator, bob.accountId, toTokenB(1_000_000)), + Utils.transferToken(client, idTokenB, operator, charlie.accountId, toTokenB(1_000_000)), + Utils.transferToken(client, idTokenB, operator, david.accountId, toTokenB(1_000_000)), + // token A + Utils.approveToken(client, idTokenA, alice, exchangeId, toTokenA(1_000_000)), + Utils.approveToken(client, idTokenA, bob, exchangeId, toTokenA(1_000_000)), + Utils.approveToken(client, idTokenA, charlie, exchangeId, toTokenA(1_000_000)), + Utils.approveToken(client, idTokenA, david, exchangeId, toTokenA(1_000_000)), + // token B + Utils.approveToken(client, idTokenB, alice, exchangeId, toTokenB(1_000_000)), + Utils.approveToken(client, idTokenB, bob, exchangeId, toTokenB(1_000_000)), + Utils.approveToken(client, idTokenB, charlie, exchangeId, toTokenB(1_000_000)), + Utils.approveToken(client, idTokenB, david, exchangeId, toTokenB(1_000_000)), + ]; + + await Promise.all(transfers); + + return { + client, + operator, + alice, + bob, + charlie, + david, + exchangeId, + idTokenA, + idTokenB, + toTokenA, + toTokenB, + addressTokenA, + addressTokenB, + fromTokenA, + fromTokenB + } +} + +describe('Load Test Exchange HTS', () => { + describe('Exchange', () => { + it('should load test', async () => { + const { client, alice, bob, charlie, david, exchangeId, idTokenB, idTokenA, toTokenB, toTokenA, addressTokenA, addressTokenB, fromTokenA, fromTokenB } = await deployExchangeFixture(); + + // deposits + await Promise.all([ + depositToken(client, alice, exchangeId, idTokenA, toTokenA(1_000_000)), + depositToken(client, bob, exchangeId, idTokenA, toTokenA(1_000_000)), + depositToken(client, charlie, exchangeId, idTokenA, toTokenA(1_000_000)), + depositToken(client, david, exchangeId, idTokenA, toTokenA(1_000_000)), + + depositToken(client, alice, exchangeId, idTokenB, toTokenB(1_000_000)), + depositToken(client, bob, exchangeId, idTokenB, toTokenB(1_000_000)), + depositToken(client, charlie, exchangeId, idTokenB, toTokenB(1_000_000)), + depositToken(client, david, exchangeId, idTokenB, toTokenB(1_000_000)), + ]); + + function hasTradeEvent (record: TransactionRecord) { + const tradeEvent = eventsEmited(record, ethers.id("Trade(int64,int64,address,address)")) as Uint8Array []; + if (tradeEvent.length){ + for( const trade of tradeEvent) { + const parsedLogTrade = AbiCoder.defaultAbiCoder().decode( + ["uint256", "uint256", "address"], + trade + ); + console.log(`-- Trade happend with ${parsedLogTrade.toString()}`); + } + } + + return tradeEvent.length; + } + + const list = new Array(100).fill(0); + + const buyOrders = list.map(async (order, index) => { + await new Promise((res) => { setTimeout(() => {res(true)}, 300 * index)}); + const buyer = returnOneOf([alice, bob, charlie, david]); + const { record: recordBuy} = await placeBuyOrder(client, buyer, exchangeId, toTokenB(getRandomInt(1000, 1020)), toTokenA(getRandomInt(1, 5))); + hasTradeEvent(recordBuy); + return order; + }); + + const sellOrders = list.map(async (order, index) => { + await new Promise((res) => { setTimeout(() => {res(true)}, 200 * (index + 1))}); + const seller = returnOneOf([alice, bob, charlie, david]); + const { record: recordSell } = await placeSellOrder(client, seller, exchangeId, toTokenB(getRandomInt(1000, 1020)), toTokenA(getRandomInt(1, 15))); + hasTradeEvent(recordSell); + return order; + }) + + try { + const results = await Promise.allSettled([...buyOrders, ...sellOrders]); + const rejected = results.filter(r => r.status === 'rejected'); + const fulfilled = results.filter(r => r.status === 'fulfilled'); + + + console.log({ + status: 'rejected', + len : rejected.length, + // @ts-ignore + ids: rejected.map(rej => rej.reason.transactionId.toString()) + }) + + console.log({ + fulfilled: { + len: fulfilled.length, + } + }); + + + } catch (error) { + console.error("Error placing orders"); + console.error(error); + expect.fail('Error placing orders'); + } + + + + const aliceTokenABalance = (await queryBalanceOfExchange(client, exchangeId, alice.address, addressTokenA)).toNumber(); + const aliceTokenBBalance = (await queryBalanceOfExchange(client, exchangeId, alice.address, addressTokenB)).toNumber(); + + const bobTokenABalance = (await queryBalanceOfExchange(client, exchangeId, "0xed9a4895a19483001d7228354d714e7ea4523d4b", addressTokenA)).toNumber(); + const bobTokenBBalance = (await queryBalanceOfExchange(client, exchangeId, "0xed9a4895a19483001d7228354d714e7ea4523d4b", addressTokenB)).toNumber(); + + const charlieTokenABalance = (await queryBalanceOfExchange(client, exchangeId, "0xb8c8d838121d5bf0a7b022737b34b13eb9fa5bea", addressTokenA)).toNumber(); + const charlieTokenBBalance = (await queryBalanceOfExchange(client, exchangeId, "0xb8c8d838121d5bf0a7b022737b34b13eb9fa5bea", addressTokenB)).toNumber(); + + const davidTokenABalance = (await queryBalanceOfExchange(client, exchangeId, david.address, addressTokenA)).toNumber(); + const davidTokenBBalance = (await queryBalanceOfExchange(client, exchangeId, david.address, addressTokenB)).toNumber(); + + + console.log({ + aliceTokenABalance: fromTokenA(aliceTokenABalance), + bobTokenABalance: fromTokenA(bobTokenABalance), + charlieTokenABalance: fromTokenA(charlieTokenABalance), + davidTokenABalance: fromTokenA(davidTokenABalance), + aliceTokenBBalance: fromTokenB(aliceTokenBBalance), + bobTokenBBalance: fromTokenB(bobTokenBBalance), + charlieTokenBBalance: fromTokenB(charlieTokenBBalance), + davidTokenBBalance: fromTokenB(davidTokenBBalance), + }) + + + + }); + }); +}); + diff --git a/test/orderbook/load/transfer.test.ts b/test/orderbook/load/transfer.test.ts new file mode 100644 index 0000000..b3a8ef6 --- /dev/null +++ b/test/orderbook/load/transfer.test.ts @@ -0,0 +1,34 @@ +import { ethers } from 'hardhat'; +import { expect } from 'chai'; +import Utils from '../../utils'; +import { AccountId, PrivateKey, Client } from '@hashgraph/sdk'; + +async function fixture() { + const client = Client.forTestnet(); + + const operatorAccountId = AccountId.fromString(''); + const operatorPrivateKey = PrivateKey.fromStringED25519(""); + + const operator = { + accountId: operatorAccountId, + key: operatorPrivateKey, + address: '0x' + (operatorAccountId.toSolidityAddress().toLowerCase()) + } + + return { + client, + operator, + } +} + +describe('Load Test Exchange HTS', () => { + describe('Exchange', () => { + it('should load test', async () => { + const { client, operator } = await fixture(); + + await Utils.transferHbar(client, operator, AccountId.fromString('0.0.3640088'), 999); + + }); + }); +}); + diff --git a/test/utils.ts b/test/utils.ts index 3a7dade..c8b0f7e 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -24,7 +24,7 @@ import { FileId, ContractCallQuery, AccountBalanceQuery, - TransactionRecord + TransactionRecord, } from '@hashgraph/sdk'; import axios from 'axios'; @@ -35,6 +35,28 @@ export interface Operator { } class Utils { + async transferHbar(client: Client, from: Operator, to: string | AccountId, amount: number) { + client.setOperator( + from.accountId, + from.key + ); + + const transferTx = new TransferTransaction() + .addHbarTransfer(from.accountId, -amount) + .addHbarTransfer(to, amount) + .freezeWith(client); + + const transferSign = await transferTx.sign(from.key); + const tx = await transferSign.execute(client); + const rx = await tx.getReceipt(client); + + if (rx.status._code != 22) { + throw new Error('Error transfer token status code' + rx.status._code); + } + + console.log(`- transferHbar success with id: ${tx.transactionId}`) + } + async createAccount(client: Client): Promise { const key = PrivateKey.fromStringECDSA(process.env.PRIVATE_KEY as string); const adminAccountTx = await new AccountCreateTransaction() @@ -165,7 +187,14 @@ class Utils { .freezeWith(client); const associateSign = await associateTx.sign(account.key); // Use the recipient's private key - await associateSign.execute(client); + const result = await associateSign.execute(client); + const receipt = await result.getReceipt(client); + + if (receipt.status._code != 22) { + throw new Error('Error Associating token code' + receipt.status._code); + } + + console.log(`- Associate token transaciton executed ${result.transactionId}`); } async transferToken(client: Client, tokenId: TokenId | string, from: Operator, to: AccountId, amount: number) { @@ -175,8 +204,8 @@ class Utils { ); const transferTx = new TransferTransaction() - .addTokenTransfer(tokenId, from.accountId, -amount) - .addTokenTransfer(tokenId, to, amount) + .addTokenTransfer(tokenId, from.accountId, amount * -1) + .addTokenTransfer(tokenId, to, amount * 1) .freezeWith(client); const transferSign = await transferTx.sign(from.key); @@ -218,10 +247,10 @@ class Utils { console.log(`- AccountAllowanceApproveTransaction success with id: ${tx.transactionId}`) } - async executeContract(client: Client, operator: Operator, contract: ContractId | string, functionName: string, params: ContractFunctionParameters): Promise<{ receipt: TransactionReceipt, record : TransactionRecord }> { + async executeContract(client: Client, operator: Operator, contract: ContractId | string, functionName: string, params: ContractFunctionParameters, config?: any): Promise<{ receipt: TransactionReceipt, record : TransactionRecord }> { const contractExecuteTx = new ContractExecuteTransaction() .setContractId(contract) - .setGas(1000000) // Adjust based on the complexity of your function + .setGas(config?.gas || 1000000) // Adjust based on the complexity of your function .setFunction(functionName, params) .setMaxTransactionFee(new Hbar(2)) // Set an appropriate max transaction fee .freezeWith(client) @@ -230,7 +259,7 @@ class Utils { const contractExecuteSign = await contractExecuteTx.sign(operator.key); const contractExecuteSubmit = await contractExecuteSign.execute(client); - console.log(` - Contract Execute with transaction ${contractExecuteSubmit.transactionId.toString()}`); + console.log(` - Contract Execute ${functionName} with transaction ${contractExecuteSubmit.transactionId.toString()}`); return { receipt: await contractExecuteSubmit.getReceipt(client), diff --git a/yarn.lock b/yarn.lock index 920ee42..e924b16 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1189,6 +1189,13 @@ dependencies: fs-extra "^9.1.0" +"@types/bn.js@*", "@types/bn.js@^5.1.0": + version "5.1.5" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.5.tgz#2e0dacdcce2c0f16b905d20ff87aedbc6f7b4bf0" + integrity sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A== + dependencies: + "@types/node" "*" + "@types/bn.js@^4.11.3": version "4.11.6" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" @@ -1196,13 +1203,6 @@ dependencies: "@types/node" "*" -"@types/bn.js@^5.1.0": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.5.tgz#2e0dacdcce2c0f16b905d20ff87aedbc6f7b4bf0" - integrity sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A== - dependencies: - "@types/node" "*" - "@types/chai-as-promised@^7.1.3": version "7.1.8" resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz#f2b3d82d53c59626b5d6bbc087667ccb4b677fe9" @@ -1227,6 +1227,13 @@ dependencies: "@types/node" "*" +"@types/elliptic@^6.4.18": + version "6.4.18" + resolved "https://registry.yarnpkg.com/@types/elliptic/-/elliptic-6.4.18.tgz#bc96e26e1ccccbabe8b6f0e409c85898635482e1" + integrity sha512-UseG6H5vjRiNpQvrhy4VF/JXdA3V/Fp5amvveaL+fs28BZ6xIKJBPnUPRlEaZpysD9MbpfaLi8lbl7PGUAkpWw== + dependencies: + "@types/bn.js" "*" + "@types/form-data@0.0.33": version "0.0.33" resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-0.0.33.tgz#c9ac85b2a5fd18435b8c85d9ecb50e6d6c893ff8" @@ -2607,7 +2614,7 @@ elliptic@6.5.4: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" -elliptic@^6.5.2, elliptic@^6.5.4: +elliptic@^6.5.2, elliptic@^6.5.4, elliptic@^6.5.5: version "6.5.5" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.5.tgz#c715e09f78b6923977610d4c2346d6ce22e6dded" integrity sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==