diff --git a/contracts/interfaces/external/IVelodromeRouter.sol b/contracts/interfaces/external/IVelodromeRouter.sol new file mode 100644 index 000000000..811a51d0e --- /dev/null +++ b/contracts/interfaces/external/IVelodromeRouter.sol @@ -0,0 +1,113 @@ +pragma solidity 0.6.10; +pragma experimental "ABIEncoderV2"; + +interface IVelodromeRouter { + struct route { + address from; + address to; + bool stable; + } + + function factory() external pure returns (address); + function weth() external pure returns (address); + + function addLiquidity( + address tokenA, + address tokenB, + bool stable, + uint amountADesired, + uint amountBDesired, + uint amountAMin, + uint amountBMin, + address to, + uint deadline + ) external returns (uint amountA, uint amountB, uint liquidity); + function addLiquidityETH( + address token, + bool stable, + uint amountTokenDesired, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline + ) external payable returns (uint amountToken, uint amountETH, uint liquidity); + function removeLiquidity( + address tokenA, + address tokenB, + bool stable, + uint liquidity, + uint amountAMin, + uint amountBMin, + address to, + uint deadline + ) external returns (uint amountA, uint amountB); + function removeLiquidityETH( + address token, + bool stable, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline + ) external returns (uint amountToken, uint amountETH); + function removeLiquidityWithPermit( + address tokenA, + address tokenB, + bool stable, + uint liquidity, + uint amountAMin, + uint amountBMin, + address to, + uint deadline, + bool approveMax, uint8 v, bytes32 r, bytes32 s + ) external returns (uint amountA, uint amountB); + function removeLiquidityETHWithPermit( + address token, + bool stable, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline, + bool approveMax, uint8 v, bytes32 r, bytes32 s + ) external returns (uint amountToken, uint amountETH); + function swapExactTokensForTokensSimple( + uint amountIn, + uint amountOutMin, + address tokenFrom, + address tokenTo, + bool stable, + address to, + uint deadline + ) external returns (uint[] memory amounts); + function swapExactTokensForTokens( + uint amountIn, + uint amountOutMin, + route[] calldata routes, + address to, + uint deadline + ) external returns (uint[] memory amounts); + function swapExactETHForTokens( + uint amountOutMin, + route[] calldata routes, + address to, + uint deadline + ) external payable returns (uint[] memory amounts); + + function getReserves(address tokenA, address tokenB, bool stable) external view returns (uint reserveA, uint reserveB); + function getAmountOut(uint amountIn, address tokenIn, address tokenOut) external view returns (uint amount, bool stable); + function getAmountsOut(uint amountIn, route[] memory routes) external view returns (uint[] memory amounts); + function quoteAddLiquidity( + address tokenA, + address tokenB, + bool stable, + uint amountADesired, + uint amountBDesired + ) external view returns (uint amountA, uint amountB, uint liquidity); + function quoteRemoveLiquidity( + address tokenA, + address tokenB, + bool stable, + uint liquidity + ) external view returns (uint amountA, uint amountB); +} \ No newline at end of file diff --git a/contracts/protocol/integration/exchange/VelodromeExchangeAdapter.sol b/contracts/protocol/integration/exchange/VelodromeExchangeAdapter.sol new file mode 100644 index 000000000..b9a23212c --- /dev/null +++ b/contracts/protocol/integration/exchange/VelodromeExchangeAdapter.sol @@ -0,0 +1,126 @@ +/* + Copyright 2022 Set Labs Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache License, Version 2.0 +*/ + +pragma solidity 0.6.10; +pragma experimental "ABIEncoderV2"; + +import { IVelodromeRouter } from "../../../interfaces/external/IVelodromeRouter.sol"; + +/** + * @title VelodromeExchangeAdapter + * @author deephil + * + * Exchange adapter for Velodrome Exchange Router that encodes trade data + */ +contract VelodromeExchangeAdapter { + + /* ============ State Variables ============ */ + + // Address of Velodrome Exchange Router contract + address public immutable router; + + /* ============ Constructor ============ */ + + /** + * Set state variables + * + * @param _router Address of Velodrome Exchange Router contract + */ + constructor(address _router) public { + router = _router; + } + + /* ============ External Getter Functions ============ */ + + /** + * Return calldata for Velodrome Exchange Router + * + * @param _sourceToken Address of source token to be sold + * @param _destinationToken Address of destination token to buy + * @param _destinationAddress Address that assets should be transferred to + * @param _sourceQuantity Amount of source token to sell + * @param _minDestinationQuantity Min amount of destination token to buy + * @param _data Arbitrary bytes containing trade call data + * + * @return address Target contract address + * @return uint256 Call value + * @return bytes Trade calldata + */ + function getTradeCalldata( + address _sourceToken, + address _destinationToken, + address _destinationAddress, + uint256 _sourceQuantity, + uint256 _minDestinationQuantity, + bytes memory _data + ) + external + view + returns (address, uint256, bytes memory) + { + ( + IVelodromeRouter.route[] memory routes, + uint256 deadline + ) = abi.decode(_data, (IVelodromeRouter.route[], uint256)); + + require(routes.length > 0, "empty routes"); + require(_sourceToken == routes[0].from, "Source token path mismatch"); + require(_destinationToken == routes[routes.length - 1].to, "Destination token path mismatch"); + require(deadline >= block.timestamp, "invalid deadline"); + + bytes memory callData = abi.encodeWithSelector( + IVelodromeRouter.swapExactTokensForTokens.selector, + _sourceQuantity, + _minDestinationQuantity, + routes, + _destinationAddress, + deadline + ); + return (router, 0, callData); + } + + /** + * Returns the address to approve source tokens to for trading. This is the Velodrome Exchange Router address + * + * @return address Address of the contract to approve tokens to + */ + function getSpender() + external + view + returns (address) + { + return router; + } + + /** + * Generate data parameter to be passed to `getTradeCallData`. Returns encoded trade routes. + * + * @param _routes array of routes for Velodrome Router + * @param _deadline block timestamp of trade deadline + * @return bytes Data parameter to be passed to `getTradeCallData` + */ + function generateDataParam(IVelodromeRouter.route[] calldata _routes, uint256 _deadline) + external + view + returns (bytes memory) + { + require(_routes.length > 0, "empty routes"); + require(_deadline >= block.timestamp, "invalid deadline"); + return abi.encode(_routes, _deadline); + } +} \ No newline at end of file diff --git a/external/abi/velodrome/VelodromeFactory.json b/external/abi/velodrome/VelodromeFactory.json new file mode 100644 index 000000000..cae4e1b5b --- /dev/null +++ b/external/abi/velodrome/VelodromeFactory.json @@ -0,0 +1,8 @@ +{ + "contractName": "VelodromeFactory", + "abi": [{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token0","type":"address"},{"indexed":true,"internalType":"address","name":"token1","type":"address"},{"indexed":false,"internalType":"bool","name":"stable","type":"bool"},{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"PairCreated","type":"event"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptFeeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptPauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allPairs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allPairsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"name":"createPair","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_stable","type":"bool"}],"name":"getFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInitializable","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"getPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairCodeHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"pauser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingFeeManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingPauser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_stable","type":"bool"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeManager","type":"address"}],"name":"setFeeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pauser","type":"address"}],"name":"setPauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stableFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"volatileFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}], + "bytecode": "0x608060405234801561001057600080fd5b50600080546001600160a81b03191633610100810260ff1916919091178255600480546001600160a01b0319169091179055600280805560035561519190819061005a90396000f3fe60806040523480156200001157600080fd5b50600436106200015d5760003560e01c80639a7165e411620000c7578063bedb86fb1162000086578063bedb86fb14620002da578063d0fb020314620002f1578063e1f76b441462000305578063e5e31b13146200031c578063eb13c4cf1462000342578063f94c53c7146200037b57600080fd5b80639a7165e4146200027b5780639aab9248146200028f5780639fd0506d1462000299578063b187bd2614620002b2578063bc063e1a14620002d157600080fd5b80635084ed0311620001205780635084ed0314620001e9578063512b45ea14620001f3578063574f2ba3146200020a5780636801cc30146200021357806382dfdce414620002505780638a4fa0d2146200026757600080fd5b8063167a6f9014620001625780631e3dd18b146200016e5780632d88af4a14620001a257806340bbd77514620001b9578063472d35b914620001d2575b600080fd5b6200016c62000385565b005b620001856200017f36600462000987565b620003c8565b6040516001600160a01b0390911681526020015b60405180910390f35b6200016c620001b3366004620009be565b620003f3565b620001c360025481565b60405190815260200162000199565b6200016c620001e3366004620009be565b62000432565b620001c360035481565b620001c362000204366004620009f4565b620004a6565b600754620001c3565b620001856200022436600462000a12565b60066020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b620001856200026136600462000a12565b620004c1565b60055462000185906001600160a01b031681565b60015462000185906001600160a01b031681565b620001c3620007ad565b600054620001859061010090046001600160a01b031681565b600054620002c09060ff1681565b604051901515815260200162000199565b620001c3600581565b6200016c620002eb366004620009f4565b620007e1565b60045462000185906001600160a01b031681565b6200016c6200031636600462000a5c565b62000811565b620002c06200032d366004620009be565b60086020526000908152604090205460ff1681565b600954600a54604080516001600160a01b0393841681529282166020840152600160a01b90910460ff1615159082015260600162000199565b6200016c620008f9565b6001546001600160a01b031633146200039d57600080fd5b600154600080546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b60078181548110620003d957600080fd5b6000918252602090912001546001600160a01b0316905081565b60005461010090046001600160a01b031633146200041057600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6004546001600160a01b03163314620004845760405162461bcd60e51b815260206004820152600f60248201526e3737ba103332b29036b0b730b3b2b960891b60448201526064015b60405180910390fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b600081620004b757600354620004bb565b6002545b92915050565b6000826001600160a01b0316846001600160a01b031614156200050c5760405162461bcd60e51b8152602060048201526002602482015261494160f01b60448201526064016200047b565b600080846001600160a01b0316866001600160a01b0316106200053157848662000534565b85855b90925090506001600160a01b038216620005765760405162461bcd60e51b81526020600482015260026024820152615a4160f01b60448201526064016200047b565b6001600160a01b0382811660009081526006602090815260408083208585168452825280832088151584529091529020541615620005dc5760405162461bcd60e51b8152602060048201526002602482015261504560f01b60448201526064016200047b565b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015284151560f81b604882015260009060490160408051601f19818403018152908290528051602090910120600a80546001600160a01b038087166001600160a01b03198b1515600160a01b0281166001600160a81b03199094169390931717909255600980549288169290911691909117905591508190620006839062000979565b8190604051809103906000f5905080158015620006a4573d6000803e3d6000fd5b506001600160a01b0384811660008181526006602081815260408084208987168086529083528185208d15158087529084528286208054988a166001600160a01b0319998a16811790915582875294845282862087875284528286208187528452828620805489168617905560078054600181810183557fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889091018054909a1687179099558587526008855295839020805460ff1916909817909755935481519687529186019290925290840152929650907fc4805696c66d7cf352fc1d6bb633ad5ee82f6cb577c453024b6e0eb8306c6fc99060600160405180910390a35050509392505050565b600060405180602001620007c19062000979565b6020820181038252601f19601f8201166040525080519060200120905090565b60005461010090046001600160a01b03163314620007fe57600080fd5b6000805460ff1916911515919091179055565b6004546001600160a01b031633146200085f5760405162461bcd60e51b815260206004820152600f60248201526e3737ba103332b29036b0b730b3b2b960891b60448201526064016200047b565b6005811115620008a15760405162461bcd60e51b815260206004820152600c60248201526b0cccaca40e8dede40d0d2ced60a31b60448201526064016200047b565b80620008e65760405162461bcd60e51b8152602060048201526013602482015272666565206d757374206265206e6f6e7a65726f60681b60448201526064016200047b565b8115620008f35760025550565b60035550565b6005546001600160a01b03163314620009555760405162461bcd60e51b815260206004820152601760248201527f6e6f742070656e64696e6720666565206d616e6167657200000000000000000060448201526064016200047b565b600554600480546001600160a01b0319166001600160a01b03909216919091179055565b6146d28062000a8a83390190565b6000602082840312156200099a57600080fd5b5035919050565b80356001600160a01b0381168114620009b957600080fd5b919050565b600060208284031215620009d157600080fd5b620009dc82620009a1565b9392505050565b80358015158114620009b957600080fd5b60006020828403121562000a0757600080fd5b620009dc82620009e3565b60008060006060848603121562000a2857600080fd5b62000a3384620009a1565b925062000a4360208501620009a1565b915062000a5360408501620009e3565b90509250925092565b6000806040838503121562000a7057600080fd5b62000a7b83620009e3565b94602093909301359350505056fe61016060405260006002556000600d556000600e5560016013553480156200002657600080fd5b50336001600160a01b0316610100816001600160a01b0316815250506000806000336001600160a01b031663eb13c4cf6040518163ffffffff1660e01b8152600401606060405180830381865afa15801562000086573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000ac9190620007c8565b8015156080526001600160a01b0380831660c052831660a052604051929550909350915083908390620000df90620006f7565b6001600160a01b03928316815291166020820152604001604051809103906000f08015801562000113573d6000803e3d6000fd5b506001600160a01b031660e05280156200034557826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000166573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000190919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620001cf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620001f9919081019062000863565b6040516020016200020c9291906200091b565b604051602081830303815290604052600090805190602001906200023292919062000705565b50826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000272573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200029c919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620002db573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000305919081019062000863565b6040516020016200031892919062000976565b604051602081830303815290604052600190805190602001906200033e92919062000705565b506200055e565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000384573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620003ae919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620003ed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000417919081019062000863565b6040516020016200042a929190620009c7565b604051602081830303815290604052600090805190602001906200045092919062000705565b50826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000490573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620004ba919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620004f9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000523919081019062000863565b6040516020016200053692919062000a24565b604051602081830303815290604052600190805190602001906200055c92919062000705565b505b826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200059d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005c3919062000a46565b620005d090600a62000b87565b6101208181525050816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000617573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200063d919062000a46565b6200064a90600a62000b87565b6101405250506040805160608101825242815260006020820181815292820181815260078054600181018255925291517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860039092029182015591517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689830155517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a909101555062000bd5565b610370806200436283390190565b828054620007139062000b98565b90600052602060002090601f01602090048101928262000737576000855562000782565b82601f106200075257805160ff191683800117855562000782565b8280016001018555821562000782579182015b828111156200078257825182559160200191906001019062000765565b506200079092915062000794565b5090565b5b8082111562000790576000815560010162000795565b80516001600160a01b0381168114620007c357600080fd5b919050565b600080600060608486031215620007de57600080fd5b620007e984620007ab565b9250620007f960208501620007ab565b9150604084015180151581146200080f57600080fd5b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b60005b838110156200084d57818101518382015260200162000833565b838111156200085d576000848401525b50505050565b6000602082840312156200087657600080fd5b81516001600160401b03808211156200088e57600080fd5b818401915084601f830112620008a357600080fd5b815181811115620008b857620008b86200081a565b604051601f8201601f19908116603f01168101908382118183101715620008e357620008e36200081a565b81604052828152876020848701011115620008fd57600080fd5b6200091083602083016020880162000830565b979650505050505050565b6e029ba30b13632ab189020a6a690169608d1b8152600083516200094781600f85016020880162000830565b602f60f81b600f9184019182015283516200096a81601084016020880162000830565b01601001949350505050565b6473414d4d2d60d81b8152600083516200099881600585016020880162000830565b602f60f81b6005918401918201528351620009bb81600684016020880162000830565b01600601949350505050565b7002b37b630ba34b632ab189020a6a690169607d1b815260008351620009f581601185016020880162000830565b602f60f81b601191840191820152835162000a1881601284016020880162000830565b01601201949350505050565b6476414d4d2d60d81b8152600083516200099881600585016020880162000830565b60006020828403121562000a5957600080fd5b815160ff8116811462000a6b57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111562000ac957816000190482111562000aad5762000aad62000a72565b8085161562000abb57918102915b93841c939080029062000a8d565b509250929050565b60008262000ae25750600162000b81565b8162000af15750600062000b81565b816001811462000b0a576002811462000b155762000b35565b600191505062000b81565b60ff84111562000b295762000b2962000a72565b50506001821b62000b81565b5060208310610133831016604e8410600b841016171562000b5a575081810a62000b81565b62000b66838362000a88565b806000190482111562000b7d5762000b7d62000a72565b0290505b92915050565b600062000a6b60ff84168362000ad1565b600181811c9082168062000bad57607f821691505b6020821081141562000bcf57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e05161010051610120516101405161360c62000d5660003960008181610431015281816125340152818161281e015281816128e001526129eb01526000818161040e015281816124f3015281816127df0152818161292201526129c50152600081816107b801528181610c0701528181610cd801526120630152600081816105f201528181611c770152818161235a01526124270152600081816104bb0152818161064701528181610714015281816108f301528181610b9b01528181611510015281816116f701528181611b1e015281816121c001526124060152600081816102f90152818161049301528181610622015281816108d201528181610b7a0152818161147a015281816116d501528181611afc015281816121380152818161233901528181612860015281816128a70152818161298c0152612a2f0152600081816103970152818161046301528181610bcf01528181610ca001528181612032015281816124cb01526127ab015261360c6000f3fe608060405234801561001057600080fd5b50600436106102745760003560e01c80637ecebe0011610151578063bda39cad116100c3578063d294f09311610087578063d294f09314610736578063d505accf1461073e578063dd62ed3e14610751578063ebeb31db1461077c578063f140a35a14610784578063fff6cae91461079757600080fd5b8063bda39cad146106eb578063bf944dbc146106f4578063c245febc146106fd578063c5700a0214610706578063d21220a71461070f57600080fd5b80639d63848a116101155780639d63848a146106145780639e8cc04b146106725780639f767c8814610685578063a1ac4d13146106a5578063a9059cbb146106c5578063bc25cf77146106d857600080fd5b80637ecebe001461057357806389afcb44146105935780638a7b8cf2146105bb57806395d89b41146105e55780639af1d35a146105ed57600080fd5b8063252c09d7116101ea5780634d5a9f8a116101ae5780634d5a9f8a146104f1578063517b3f82146105115780635881c475146105245780635a76f25e146105375780636a6278421461054057806370a082311461055357600080fd5b8063252c09d7146103cc578063313ce567146103df57806332c0defd146103f9578063392f37e914610402578063443cb4bc146104e857600080fd5b806313345fe11161023c57806313345fe11461033357806318160ddd146103535780631df8c7171461036a578063205aabf11461037257806322be3de11461039257806323b872dd146103b957600080fd5b8063022c0d9f1461027957806306fdde031461028e5780630902f1ac146102ac578063095ea7b3146102d15780630dfe1681146102f4575b600080fd5b61028c61028736600461308b565b61079f565b005b610296610eec565b6040516102a3919061314f565b60405180910390f35b600854600954600a545b604080519384526020840192909252908201526060016102a3565b6102e46102df366004613182565b610f7a565b60405190151581526020016102a3565b61031b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102a3565b6103466103413660046131ac565b610fe7565b6040516102a391906131e5565b61035c60025481565b6040519081526020016102a3565b6102b66111e3565b61035c610380366004613229565b60106020526000908152604090205481565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b6102e46103c7366004613244565b611252565b6102b66103da366004613280565b61131b565b6103e7601281565b60405160ff90911681526020016102a3565b61035c600d5481565b600854600954604080517f000000000000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060208201529081019290925260608201527f0000000000000000000000000000000000000000000000000000000000000000151560808201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660a08301527f00000000000000000000000000000000000000000000000000000000000000001660c082015260e0016102a3565b61035c60085481565b61035c6104ff366004613229565b60116020526000908152604090205481565b61035c61051f366004613182565b61134e565b610346610532366004613299565b611437565b61035c60095481565b61035c61054e366004613229565b611446565b61035c610561366004613229565b60046020526000908152604090205481565b61035c610581366004613229565b60066020526000908152604090205481565b6105a66105a1366004613229565b6116a3565b604080519283526020830191909152016102a3565b6105c36119c0565b60408051825181526020808401519082015291810151908201526060016102a3565b610296611a40565b61031b7f000000000000000000000000000000000000000000000000000000000000000081565b604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811682527f0000000000000000000000000000000000000000000000000000000000000000166020820152016102a3565b61035c610680366004613299565b611a4d565b61035c610693366004613229565b600f6020526000908152604090205481565b61035c6106b3366004613229565b60126020526000908152604090205481565b6102e46106d3366004613182565b611aba565b61028c6106e6366004613229565b611ad0565b61035c600e5481565b61035c600b5481565b61035c600c5481565b61035c600a5481565b61031b7f000000000000000000000000000000000000000000000000000000000000000081565b6105a6611bee565b61028c61074c3660046132cc565b611d15565b61035c61075f36600461333f565b600360209081526000928352604080842090915290825290205481565b60075461035c565b61035c610792366004613372565b61201d565b61028c61210b565b6013546001146107ae57600080fd5b60026013819055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b187bd266040518163ffffffff1660e01b8152600401602060405180830381865afa158015610814573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108389190613395565b1561084257600080fd5b60008511806108515750600084115b6108885760405162461bcd60e51b8152602060048201526003602482015262494f4160e81b60448201526064015b60405180910390fd5b600854600954818710801561089c57508086105b6108cd5760405162461bcd60e51b8152602060048201526002602482015261125360f21b604482015260640161087f565b6000807f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03898116908316148015906109405750806001600160a01b0316896001600160a01b031614155b6109715760405162461bcd60e51b8152602060048201526002602482015261125560f21b604482015260640161087f565b8a1561098257610982828a8d612245565b891561099357610993818a8c612245565b8615610a0057604051639a7bff7960e01b81526001600160a01b038a1690639a7bff79906109cd9033908f908f908e908e906004016133b7565b600060405180830381600087803b1580156109e757600080fd5b505af11580156109fb573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a689190613403565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610aaf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad39190613403565b9250505060008985610ae59190613432565b8311610af2576000610b06565b610afc8a86613432565b610b069084613432565b90506000610b148a86613432565b8311610b21576000610b35565b610b2b8a86613432565b610b359084613432565b90506000821180610b465750600081115b610b785760405162461bcd60e51b815260206004820152600360248201526249494160e81b604482015260640161087f565b7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008315610c8b57604051632895a2f560e11b81527f000000000000000000000000000000000000000000000000000000000000000015156004820152610c8b90612710906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063512b45ea90602401602060405180830381865afa158015610c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c729190613403565b610c7c9087613449565b610c869190613468565b612334565b8215610d5c57604051632895a2f560e11b81527f000000000000000000000000000000000000000000000000000000000000000015156004820152610d5c90612710906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063512b45ea90602401602060405180830381865afa158015610d1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d439190613403565b610d4d9086613449565b610d579190613468565b612401565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610da0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc49190613403565b6040516370a0823160e01b81523060048201529096506001600160a01b038216906370a0823190602401602060405180830381865afa158015610e0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2f9190613403565b9450610e3b88886124c7565b610e4587876124c7565b1015610e775760405162461bcd60e51b81526020600482015260016024820152604b60f81b604482015260640161087f565b5050610e8584848888612613565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a350506001601355505050505050505050565b60008054610ef99061348a565b80601f0160208091040260200160405190810160405280929190818152602001828054610f259061348a565b8015610f725780601f10610f4757610100808354040283529160200191610f72565b820191906000526020600020905b815481529060010190602001808311610f5557829003601f168201915b505050505081565b3360008181526003602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610fd59086815260200190565b60405180910390a35060015b92915050565b606060008367ffffffffffffffff811115611004576110046134bf565b60405190808252806020026020018201604052801561102d578160200160208202803683370190505b5060075490915060009061104390600190613432565b905060006110518587613449565b61105b9083613432565b90506000805b838310156111d35761107387846134d5565b915060006007848154811061108a5761108a6134ed565b906000526020600020906003020160000154600784815481106110af576110af6134ed565b9060005260206000209060030201600001546110cb9190613432565b9050600081600786815481106110e3576110e36134ed565b90600052602060002090600302016001015460078681548110611108576111086134ed565b9060005260206000209060030201600101546111249190613432565b61112e9190613468565b905060008260078781548110611146576111466134ed565b9060005260206000209060030201600201546007878154811061116b5761116b6134ed565b9060005260206000209060030201600201546111879190613432565b6111919190613468565b905061119f8c8e84846127a7565b8885815181106111b1576111b16134ed565b60209081029190910101525050506001016111cc87846134d5565b9250611061565b509293505050505b949350505050565b600b54600c544260008080611201600854600954600a549192909190565b92509250925083811461124a57600061121a8286613432565b90506112268185613449565b61123090886134d5565b965061123c8184613449565b61124690876134d5565b9550505b505050909192565b6001600160a01b03831660008181526003602090815260408083203380855292528220549192909190821480159061128c57506000198114155b1561130257600061129d8583613432565b6001600160a01b038881166000818152600360209081526040808320948916808452948252918290208590559051848152939450919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505b61130d868686612a9c565b6001925050505b9392505050565b6007818154811061132b57600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b6000806113596119c0565b90506000806113666111e3565b50845191935091504214156113cf576007805461138590600290613432565b81548110611395576113956134ed565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505092505b82516000906113de9042613432565b90506000818560200151856113f39190613432565b6113fd9190613468565b90506000828660400151856114129190613432565b61141c9190613468565b905061142a888a84846127a7565b9998505050505050505050565b60606111db8484846001610fe7565b600060135460011461145757600080fd5b60026013556008546009546040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156114c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ed9190613403565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015611557573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157b9190613403565b905060006115898584613432565b905060006115978584613432565b600254909150806115d5576103e86115b76115b28486613449565b612b5c565b6115c19190613432565b97506115d060006103e8612bcc565b61160a565b611607876115e38386613449565b6115ed9190613468565b876115f88486613449565b6116029190613468565b612c5f565b97505b600088116116405760405162461bcd60e51b8152602060048201526003602482015262494c4d60e81b604482015260640161087f565b61164a8989612bcc565b61165685858989612613565b604080518481526020810184905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a250506001601355509395945050505050565b6000806013546001146116b557600080fd5b60026013556008546009546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000906000906001600160a01b038416906370a0823190602401602060405180830381865afa15801561174b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176f9190613403565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a0823190602401602060405180830381865afa1580156117b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117dd9190613403565b3060009081526004602052604090205460025491925090806117ff8584613449565b6118099190613468565b9950806118168484613449565b6118209190613468565b985060008a1180156118325750600089115b6118645760405162461bcd60e51b815260206004820152600360248201526224a62160e91b604482015260640161087f565b61186e3083612c75565b611879868c8c612245565b611884858c8b612245565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa1580156118c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ec9190613403565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa158015611933573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119579190613403565b925061196584848a8a612613565b604080518b8152602081018b90526001600160a01b038d169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a350505050505050506001601381905550915091565b6119e460405180606001604052806000815260200160008152602001600081525090565b600780546119f490600190613432565b81548110611a0457611a046134ed565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905090565b60018054610ef99061348a565b600080611a5d8585856001610fe7565b90506000805b8251811015611aa557828181518110611a7e57611a7e6134ed565b602002602001015182611a9191906134d5565b915080611a9d81613503565b915050611a63565b50611ab08482613468565b9695505050505050565b6000611ac7338484612a9c565b50600192915050565b601354600114611adf57600080fd5b60026013556008546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000917f000000000000000000000000000000000000000000000000000000000000000091611bac9184918691906001600160a01b038416906370a08231906024015b602060405180830381865afa158015611b79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9d9190613403565b611ba79190613432565b612245565b6009546040516370a0823160e01b8152306004820152611be49183918691906001600160a01b038416906370a0823190602401611b5c565b5050600160135550565b600080611bfa33612d00565b50503360009081526011602090815260408083205460129092529091205481151580611c265750600081115b15611d11573360008181526011602090815260408083208390556012909152808220919091555163299e7ae760e11b8152600481019190915260248101839052604481018290526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063533cf5ce90606401600060405180830381600087803b158015611cbb57600080fd5b505af1158015611ccf573d6000803e3d6000fd5b505060408051858152602081018590523393508392507f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e94645910160405180910390a35b9091565b42841015611d555760405162461bcd60e51b815260206004820152600d60248201526c14185a5c8e8811561412549151609a1b604482015260640161087f565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051611d85919061351e565b60408051918290038220828201825260018352603160f81b6020938401528151928301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f19818403018152918152815160209283012060058190556001600160a01b038a166000908152600690935290822080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b919087611e5083613503565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e00160405160208183030381529060405280519060200120604051602001611ec992919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015611f34573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590611f6a5750886001600160a01b0316816001600160a01b0316145b611fb65760405162461bcd60e51b815260206004820152601760248201527f506169723a20494e56414c49445f5349474e4154555245000000000000000000604482015260640161087f565b6001600160a01b038981166000818152600360209081526040808320948d16808452948252918290208b905590518a81527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050505050505050565b600854600954604051632895a2f560e11b81527f0000000000000000000000000000000000000000000000000000000000000000151560048201526000929190612710907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063512b45ea90602401602060405180830381865afa1580156120b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d69190613403565b6120e09087613449565b6120ea9190613468565b6120f49086613432565b9450612102858584846127a7565b95945050505050565b60135460011461211a57600080fd5b60026013556040516370a0823160e01b815230600482015261223e907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612187573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ab9190613403565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561220f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122339190613403565b600854600954612613565b6001601355565b6000836001600160a01b03163b1161225c57600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916122b891906135ba565b6000604051808303816000865af19150503d80600081146122f5576040519150601f19603f3d011682016040523d82523d6000602084013e6122fa565b606091505b50915091508180156123245750805115806123245750808060200190518101906123249190613395565b61232d57600080fd5b5050505050565b61237f7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000083612245565b60025460009061239783670de0b6b3a7640000613449565b6123a19190613468565b905080156123c15780600d60008282546123bb91906134d5565b90915550505b604080518381526000602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b61244c7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000083612245565b60025460009061246483670de0b6b3a7640000613449565b61246e9190613468565b9050801561248e5780600e600082825461248891906134d5565b90915550505b60408051600081526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291016123f5565b60007f0000000000000000000000000000000000000000000000000000000000000000156126025760007f000000000000000000000000000000000000000000000000000000000000000061252485670de0b6b3a7640000613449565b61252e9190613468565b905060007f000000000000000000000000000000000000000000000000000000000000000061256585670de0b6b3a7640000613449565b61256f9190613468565b90506000670de0b6b3a76400006125868385613449565b6125909190613468565b90506000670de0b6b3a76400006125a78480613449565b6125b19190613468565b670de0b6b3a76400006125c48680613449565b6125ce9190613468565b6125d891906134d5565b9050670de0b6b3a76400006125ed8284613449565b6125f79190613468565b945050505050610fe1565b61260c8284613449565b9050610fe1565b600a5442906000906126259083613432565b905060008111801561263657508315155b801561264157508215155b15612688576126508185613449565b600b600082825461266191906134d5565b9091555061267190508184613449565b600c600082825461268291906134d5565b90915550505b60006126926119c0565b80519091506126a19084613432565b91506107088211156127565760408051606081018252848152600b5460208201908152600c549282019283526007805460018101825560009190915291517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688600390930292830155517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68982015590517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a909101555b60088790556009869055600a83905560408051888152602081018890527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a150505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000015612a2a5760006127db84846124c7565b90507f000000000000000000000000000000000000000000000000000000000000000061281085670de0b6b3a7640000613449565b61281a9190613468565b93507f000000000000000000000000000000000000000000000000000000000000000061284f84670de0b6b3a7640000613449565b6128599190613468565b92506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b03161461289e5784866128a1565b85855b915091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b031614612920577f000000000000000000000000000000000000000000000000000000000000000061291189670de0b6b3a7640000613449565b61291b9190613468565b61295d565b7f000000000000000000000000000000000000000000000000000000000000000061295389670de0b6b3a7640000613449565b61295d9190613468565b9750600061297561296e848b6134d5565b8584612e60565b61297f9083613432565b9050670de0b6b3a76400007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316896001600160a01b0316146129e9577f0000000000000000000000000000000000000000000000000000000000000000612a0b565b7f00000000000000000000000000000000000000000000000000000000000000005b612a159083613449565b612a1f9190613468565b9450505050506111db565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b031614612a6d578385612a70565b84845b9092509050612a7f87836134d5565b612a898289613449565b612a939190613468565b925050506111db565b612aa583612d00565b612aae82612d00565b6001600160a01b03831660009081526004602052604081208054839290612ad6908490613432565b90915550506001600160a01b03821660009081526004602052604081208054839290612b039084906134d5565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612b4f91815260200190565b60405180910390a3505050565b60006003821115612bbd5750806000612b76600283613468565b612b819060016134d5565b90505b81811015612bb757905080600281612b9c8186613468565b612ba691906134d5565b612bb09190613468565b9050612b84565b50919050565b8115612bc7575060015b919050565b612bd582612d00565b8060026000828254612be791906134d5565b90915550506001600160a01b03821660009081526004602052604081208054839290612c149084906134d5565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b6000818310612c6e5781611314565b5090919050565b612c7e82612d00565b8060026000828254612c909190613432565b90915550506001600160a01b03821660009081526004602052604081208054839290612cbd908490613432565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001612c53565b6001600160a01b0381166000908152600460205260409020548015612e2e576001600160a01b0382166000908152600f60209081526040808320805460108085529285208054600d54600e54948190559490955282905593612d628584613432565b90506000612d708584613432565b90508115612dcb576000670de0b6b3a7640000612d8d848a613449565b612d979190613468565b6001600160a01b038a16600090815260116020526040812080549293508392909190612dc49084906134d5565b9091555050505b8015612e24576000670de0b6b3a7640000612de6838a613449565b612df09190613468565b6001600160a01b038a16600090815260126020526040812080549293508392909190612e1d9084906134d5565b9091555050505b5050505050505050565b600d546001600160a01b0383166000908152600f6020908152604080832093909355600e546010909152919020555050565b6000805b60ff811015612f6657826000612e7a8783612f6f565b905085811015612eca576000612e90888761300c565b612e9a8389613432565b612eac90670de0b6b3a7640000613449565b612eb69190613468565b9050612ec281876134d5565b955050612f0c565b6000612ed6888761300c565b612ee08884613432565b612ef290670de0b6b3a7640000613449565b612efc9190613468565b9050612f088187613432565b9550505b81851115612f35576001612f208387613432565b11612f3057849350505050611314565b612f51565b6001612f418684613432565b11612f5157849350505050611314565b50508080612f5e90613503565b915050612e64565b50909392505050565b6000670de0b6b3a764000082818581612f888280613449565b612f929190613468565b612f9c9190613449565b612fa69190613468565b612fb09190613449565b612fba9190613468565b670de0b6b3a7640000808481612fd08280613449565b612fda9190613468565b612fe49190613449565b612fee9190613468565b612ff89086613449565b6130029190613468565b61131491906134d5565b6000670de0b6b3a764000083816130238280613449565b61302d9190613468565b6130379190613449565b6130419190613468565b670de0b6b3a7640000806130558580613449565b61305f9190613468565b61306a866003613449565b612ff89190613449565b80356001600160a01b0381168114612bc757600080fd5b6000806000806000608086880312156130a357600080fd5b85359450602086013593506130ba60408701613074565b9250606086013567ffffffffffffffff808211156130d757600080fd5b818801915088601f8301126130eb57600080fd5b8135818111156130fa57600080fd5b89602082850101111561310c57600080fd5b9699959850939650602001949392505050565b60005b8381101561313a578181015183820152602001613122565b83811115613149576000848401525b50505050565b602081526000825180602084015261316e81604085016020870161311f565b601f01601f19169190910160400192915050565b6000806040838503121561319557600080fd5b61319e83613074565b946020939093013593505050565b600080600080608085870312156131c257600080fd5b6131cb85613074565b966020860135965060408601359560600135945092505050565b6020808252825182820181905260009190848201906040850190845b8181101561321d57835183529284019291840191600101613201565b50909695505050505050565b60006020828403121561323b57600080fd5b61131482613074565b60008060006060848603121561325957600080fd5b61326284613074565b925061327060208501613074565b9150604084013590509250925092565b60006020828403121561329257600080fd5b5035919050565b6000806000606084860312156132ae57600080fd5b6132b784613074565b95602085013595506040909401359392505050565b600080600080600080600060e0888a0312156132e757600080fd5b6132f088613074565b96506132fe60208901613074565b95506040880135945060608801359350608088013560ff8116811461332257600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561335257600080fd5b61335b83613074565b915061336960208401613074565b90509250929050565b6000806040838503121561338557600080fd5b8235915061336960208401613074565b6000602082840312156133a757600080fd5b8151801515811461131457600080fd5b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b60006020828403121561341557600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000828210156134445761344461341c565b500390565b60008160001904831182151516156134635761346361341c565b500290565b60008261348557634e487b7160e01b600052601260045260246000fd5b500490565b600181811c9082168061349e57607f821691505b60208210811415612bb757634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600082198211156134e8576134e861341c565b500190565b634e487b7160e01b600052603260045260246000fd5b60006000198214156135175761351761341c565b5060010190565b600080835481600182811c91508083168061353a57607f831692505b602080841082141561355a57634e487b7160e01b86526022600452602486fd5b81801561356e576001811461357f576135ac565b60ff198616895284890196506135ac565b60008a81526020902060005b868110156135a45781548b82015290850190830161358b565b505084890196505b509498975050505050505050565b600082516135cc81846020870161311f565b919091019291505056fea264697066735822122012bbc26e6d059c64971894076e1c061b5af33828e3ac3045418303c8201d1fe764736f6c634300080b003360e060405234801561001057600080fd5b5060405161037038038061037083398101604081905261002f91610066565b336080526001600160a01b0391821660a0521660c052610099565b80516001600160a01b038116811461006157600080fd5b919050565b6000806040838503121561007957600080fd5b6100828361004a565b91506100906020840161004a565b90509250929050565b60805160a05160c0516102ab6100c5600039600060b601526000608501526000605001526102ab6000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063533cf5ce14610030575b600080fd5b61004361003e3660046101d0565b610045565b005b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461007a57600080fd5b81156100ab576100ab7f000000000000000000000000000000000000000000000000000000000000000084846100e1565b80156100dc576100dc7f000000000000000000000000000000000000000000000000000000000000000084836100e1565b505050565b6000836001600160a01b03163b116100f857600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916101549190610211565b6000604051808303816000865af19150503d8060008114610191576040519150601f19603f3d011682016040523d82523d6000602084013e610196565b606091505b50915091508180156101c05750805115806101c05750808060200190518101906101c0919061024c565b6101c957600080fd5b5050505050565b6000806000606084860312156101e557600080fd5b83356001600160a01b03811681146101fc57600080fd5b95602085013595506040909401359392505050565b6000825160005b818110156102325760208186018101518583015201610218565b81811115610241576000828501525b509190910192915050565b60006020828403121561025e57600080fd5b8151801515811461026e57600080fd5b939250505056fea26469706673582212205f5c908ef3326a953bd870e8659b0596ff46fae086e9667d4d69778578e14adc64736f6c634300080b0033a2646970667358221220d044256e297a575c8be24751aa6c5b37af7db2fd6b3617dfa590cf6bacfad43964736f6c634300080b0033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b50600436106200015d5760003560e01c80639a7165e411620000c7578063bedb86fb1162000086578063bedb86fb14620002da578063d0fb020314620002f1578063e1f76b441462000305578063e5e31b13146200031c578063eb13c4cf1462000342578063f94c53c7146200037b57600080fd5b80639a7165e4146200027b5780639aab9248146200028f5780639fd0506d1462000299578063b187bd2614620002b2578063bc063e1a14620002d157600080fd5b80635084ed0311620001205780635084ed0314620001e9578063512b45ea14620001f3578063574f2ba3146200020a5780636801cc30146200021357806382dfdce414620002505780638a4fa0d2146200026757600080fd5b8063167a6f9014620001625780631e3dd18b146200016e5780632d88af4a14620001a257806340bbd77514620001b9578063472d35b914620001d2575b600080fd5b6200016c62000385565b005b620001856200017f36600462000987565b620003c8565b6040516001600160a01b0390911681526020015b60405180910390f35b6200016c620001b3366004620009be565b620003f3565b620001c360025481565b60405190815260200162000199565b6200016c620001e3366004620009be565b62000432565b620001c360035481565b620001c362000204366004620009f4565b620004a6565b600754620001c3565b620001856200022436600462000a12565b60066020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b620001856200026136600462000a12565b620004c1565b60055462000185906001600160a01b031681565b60015462000185906001600160a01b031681565b620001c3620007ad565b600054620001859061010090046001600160a01b031681565b600054620002c09060ff1681565b604051901515815260200162000199565b620001c3600581565b6200016c620002eb366004620009f4565b620007e1565b60045462000185906001600160a01b031681565b6200016c6200031636600462000a5c565b62000811565b620002c06200032d366004620009be565b60086020526000908152604090205460ff1681565b600954600a54604080516001600160a01b0393841681529282166020840152600160a01b90910460ff1615159082015260600162000199565b6200016c620008f9565b6001546001600160a01b031633146200039d57600080fd5b600154600080546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b60078181548110620003d957600080fd5b6000918252602090912001546001600160a01b0316905081565b60005461010090046001600160a01b031633146200041057600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6004546001600160a01b03163314620004845760405162461bcd60e51b815260206004820152600f60248201526e3737ba103332b29036b0b730b3b2b960891b60448201526064015b60405180910390fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b600081620004b757600354620004bb565b6002545b92915050565b6000826001600160a01b0316846001600160a01b031614156200050c5760405162461bcd60e51b8152602060048201526002602482015261494160f01b60448201526064016200047b565b600080846001600160a01b0316866001600160a01b0316106200053157848662000534565b85855b90925090506001600160a01b038216620005765760405162461bcd60e51b81526020600482015260026024820152615a4160f01b60448201526064016200047b565b6001600160a01b0382811660009081526006602090815260408083208585168452825280832088151584529091529020541615620005dc5760405162461bcd60e51b8152602060048201526002602482015261504560f01b60448201526064016200047b565b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015284151560f81b604882015260009060490160408051601f19818403018152908290528051602090910120600a80546001600160a01b038087166001600160a01b03198b1515600160a01b0281166001600160a81b03199094169390931717909255600980549288169290911691909117905591508190620006839062000979565b8190604051809103906000f5905080158015620006a4573d6000803e3d6000fd5b506001600160a01b0384811660008181526006602081815260408084208987168086529083528185208d15158087529084528286208054988a166001600160a01b0319998a16811790915582875294845282862087875284528286208187528452828620805489168617905560078054600181810183557fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889091018054909a1687179099558587526008855295839020805460ff1916909817909755935481519687529186019290925290840152929650907fc4805696c66d7cf352fc1d6bb633ad5ee82f6cb577c453024b6e0eb8306c6fc99060600160405180910390a35050509392505050565b600060405180602001620007c19062000979565b6020820181038252601f19601f8201166040525080519060200120905090565b60005461010090046001600160a01b03163314620007fe57600080fd5b6000805460ff1916911515919091179055565b6004546001600160a01b031633146200085f5760405162461bcd60e51b815260206004820152600f60248201526e3737ba103332b29036b0b730b3b2b960891b60448201526064016200047b565b6005811115620008a15760405162461bcd60e51b815260206004820152600c60248201526b0cccaca40e8dede40d0d2ced60a31b60448201526064016200047b565b80620008e65760405162461bcd60e51b8152602060048201526013602482015272666565206d757374206265206e6f6e7a65726f60681b60448201526064016200047b565b8115620008f35760025550565b60035550565b6005546001600160a01b03163314620009555760405162461bcd60e51b815260206004820152601760248201527f6e6f742070656e64696e6720666565206d616e6167657200000000000000000060448201526064016200047b565b600554600480546001600160a01b0319166001600160a01b03909216919091179055565b6146d28062000a8a83390190565b6000602082840312156200099a57600080fd5b5035919050565b80356001600160a01b0381168114620009b957600080fd5b919050565b600060208284031215620009d157600080fd5b620009dc82620009a1565b9392505050565b80358015158114620009b957600080fd5b60006020828403121562000a0757600080fd5b620009dc82620009e3565b60008060006060848603121562000a2857600080fd5b62000a3384620009a1565b925062000a4360208501620009a1565b915062000a5360408501620009e3565b90509250925092565b6000806040838503121562000a7057600080fd5b62000a7b83620009e3565b94602093909301359350505056fe61016060405260006002556000600d556000600e5560016013553480156200002657600080fd5b50336001600160a01b0316610100816001600160a01b0316815250506000806000336001600160a01b031663eb13c4cf6040518163ffffffff1660e01b8152600401606060405180830381865afa15801562000086573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000ac9190620007c8565b8015156080526001600160a01b0380831660c052831660a052604051929550909350915083908390620000df90620006f7565b6001600160a01b03928316815291166020820152604001604051809103906000f08015801562000113573d6000803e3d6000fd5b506001600160a01b031660e05280156200034557826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000166573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000190919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620001cf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620001f9919081019062000863565b6040516020016200020c9291906200091b565b604051602081830303815290604052600090805190602001906200023292919062000705565b50826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000272573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200029c919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620002db573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000305919081019062000863565b6040516020016200031892919062000976565b604051602081830303815290604052600190805190602001906200033e92919062000705565b506200055e565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000384573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620003ae919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620003ed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000417919081019062000863565b6040516020016200042a929190620009c7565b604051602081830303815290604052600090805190602001906200045092919062000705565b50826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000490573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620004ba919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620004f9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000523919081019062000863565b6040516020016200053692919062000a24565b604051602081830303815290604052600190805190602001906200055c92919062000705565b505b826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200059d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005c3919062000a46565b620005d090600a62000b87565b6101208181525050816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000617573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200063d919062000a46565b6200064a90600a62000b87565b6101405250506040805160608101825242815260006020820181815292820181815260078054600181018255925291517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860039092029182015591517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689830155517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a909101555062000bd5565b610370806200436283390190565b828054620007139062000b98565b90600052602060002090601f01602090048101928262000737576000855562000782565b82601f106200075257805160ff191683800117855562000782565b8280016001018555821562000782579182015b828111156200078257825182559160200191906001019062000765565b506200079092915062000794565b5090565b5b8082111562000790576000815560010162000795565b80516001600160a01b0381168114620007c357600080fd5b919050565b600080600060608486031215620007de57600080fd5b620007e984620007ab565b9250620007f960208501620007ab565b9150604084015180151581146200080f57600080fd5b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b60005b838110156200084d57818101518382015260200162000833565b838111156200085d576000848401525b50505050565b6000602082840312156200087657600080fd5b81516001600160401b03808211156200088e57600080fd5b818401915084601f830112620008a357600080fd5b815181811115620008b857620008b86200081a565b604051601f8201601f19908116603f01168101908382118183101715620008e357620008e36200081a565b81604052828152876020848701011115620008fd57600080fd5b6200091083602083016020880162000830565b979650505050505050565b6e029ba30b13632ab189020a6a690169608d1b8152600083516200094781600f85016020880162000830565b602f60f81b600f9184019182015283516200096a81601084016020880162000830565b01601001949350505050565b6473414d4d2d60d81b8152600083516200099881600585016020880162000830565b602f60f81b6005918401918201528351620009bb81600684016020880162000830565b01600601949350505050565b7002b37b630ba34b632ab189020a6a690169607d1b815260008351620009f581601185016020880162000830565b602f60f81b601191840191820152835162000a1881601284016020880162000830565b01601201949350505050565b6476414d4d2d60d81b8152600083516200099881600585016020880162000830565b60006020828403121562000a5957600080fd5b815160ff8116811462000a6b57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111562000ac957816000190482111562000aad5762000aad62000a72565b8085161562000abb57918102915b93841c939080029062000a8d565b509250929050565b60008262000ae25750600162000b81565b8162000af15750600062000b81565b816001811462000b0a576002811462000b155762000b35565b600191505062000b81565b60ff84111562000b295762000b2962000a72565b50506001821b62000b81565b5060208310610133831016604e8410600b841016171562000b5a575081810a62000b81565b62000b66838362000a88565b806000190482111562000b7d5762000b7d62000a72565b0290505b92915050565b600062000a6b60ff84168362000ad1565b600181811c9082168062000bad57607f821691505b6020821081141562000bcf57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e05161010051610120516101405161360c62000d5660003960008181610431015281816125340152818161281e015281816128e001526129eb01526000818161040e015281816124f3015281816127df0152818161292201526129c50152600081816107b801528181610c0701528181610cd801526120630152600081816105f201528181611c770152818161235a01526124270152600081816104bb0152818161064701528181610714015281816108f301528181610b9b01528181611510015281816116f701528181611b1e015281816121c001526124060152600081816102f90152818161049301528181610622015281816108d201528181610b7a0152818161147a015281816116d501528181611afc015281816121380152818161233901528181612860015281816128a70152818161298c0152612a2f0152600081816103970152818161046301528181610bcf01528181610ca001528181612032015281816124cb01526127ab015261360c6000f3fe608060405234801561001057600080fd5b50600436106102745760003560e01c80637ecebe0011610151578063bda39cad116100c3578063d294f09311610087578063d294f09314610736578063d505accf1461073e578063dd62ed3e14610751578063ebeb31db1461077c578063f140a35a14610784578063fff6cae91461079757600080fd5b8063bda39cad146106eb578063bf944dbc146106f4578063c245febc146106fd578063c5700a0214610706578063d21220a71461070f57600080fd5b80639d63848a116101155780639d63848a146106145780639e8cc04b146106725780639f767c8814610685578063a1ac4d13146106a5578063a9059cbb146106c5578063bc25cf77146106d857600080fd5b80637ecebe001461057357806389afcb44146105935780638a7b8cf2146105bb57806395d89b41146105e55780639af1d35a146105ed57600080fd5b8063252c09d7116101ea5780634d5a9f8a116101ae5780634d5a9f8a146104f1578063517b3f82146105115780635881c475146105245780635a76f25e146105375780636a6278421461054057806370a082311461055357600080fd5b8063252c09d7146103cc578063313ce567146103df57806332c0defd146103f9578063392f37e914610402578063443cb4bc146104e857600080fd5b806313345fe11161023c57806313345fe11461033357806318160ddd146103535780631df8c7171461036a578063205aabf11461037257806322be3de11461039257806323b872dd146103b957600080fd5b8063022c0d9f1461027957806306fdde031461028e5780630902f1ac146102ac578063095ea7b3146102d15780630dfe1681146102f4575b600080fd5b61028c61028736600461308b565b61079f565b005b610296610eec565b6040516102a3919061314f565b60405180910390f35b600854600954600a545b604080519384526020840192909252908201526060016102a3565b6102e46102df366004613182565b610f7a565b60405190151581526020016102a3565b61031b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102a3565b6103466103413660046131ac565b610fe7565b6040516102a391906131e5565b61035c60025481565b6040519081526020016102a3565b6102b66111e3565b61035c610380366004613229565b60106020526000908152604090205481565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b6102e46103c7366004613244565b611252565b6102b66103da366004613280565b61131b565b6103e7601281565b60405160ff90911681526020016102a3565b61035c600d5481565b600854600954604080517f000000000000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060208201529081019290925260608201527f0000000000000000000000000000000000000000000000000000000000000000151560808201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660a08301527f00000000000000000000000000000000000000000000000000000000000000001660c082015260e0016102a3565b61035c60085481565b61035c6104ff366004613229565b60116020526000908152604090205481565b61035c61051f366004613182565b61134e565b610346610532366004613299565b611437565b61035c60095481565b61035c61054e366004613229565b611446565b61035c610561366004613229565b60046020526000908152604090205481565b61035c610581366004613229565b60066020526000908152604090205481565b6105a66105a1366004613229565b6116a3565b604080519283526020830191909152016102a3565b6105c36119c0565b60408051825181526020808401519082015291810151908201526060016102a3565b610296611a40565b61031b7f000000000000000000000000000000000000000000000000000000000000000081565b604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811682527f0000000000000000000000000000000000000000000000000000000000000000166020820152016102a3565b61035c610680366004613299565b611a4d565b61035c610693366004613229565b600f6020526000908152604090205481565b61035c6106b3366004613229565b60126020526000908152604090205481565b6102e46106d3366004613182565b611aba565b61028c6106e6366004613229565b611ad0565b61035c600e5481565b61035c600b5481565b61035c600c5481565b61035c600a5481565b61031b7f000000000000000000000000000000000000000000000000000000000000000081565b6105a6611bee565b61028c61074c3660046132cc565b611d15565b61035c61075f36600461333f565b600360209081526000928352604080842090915290825290205481565b60075461035c565b61035c610792366004613372565b61201d565b61028c61210b565b6013546001146107ae57600080fd5b60026013819055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b187bd266040518163ffffffff1660e01b8152600401602060405180830381865afa158015610814573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108389190613395565b1561084257600080fd5b60008511806108515750600084115b6108885760405162461bcd60e51b8152602060048201526003602482015262494f4160e81b60448201526064015b60405180910390fd5b600854600954818710801561089c57508086105b6108cd5760405162461bcd60e51b8152602060048201526002602482015261125360f21b604482015260640161087f565b6000807f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03898116908316148015906109405750806001600160a01b0316896001600160a01b031614155b6109715760405162461bcd60e51b8152602060048201526002602482015261125560f21b604482015260640161087f565b8a1561098257610982828a8d612245565b891561099357610993818a8c612245565b8615610a0057604051639a7bff7960e01b81526001600160a01b038a1690639a7bff79906109cd9033908f908f908e908e906004016133b7565b600060405180830381600087803b1580156109e757600080fd5b505af11580156109fb573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a689190613403565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610aaf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad39190613403565b9250505060008985610ae59190613432565b8311610af2576000610b06565b610afc8a86613432565b610b069084613432565b90506000610b148a86613432565b8311610b21576000610b35565b610b2b8a86613432565b610b359084613432565b90506000821180610b465750600081115b610b785760405162461bcd60e51b815260206004820152600360248201526249494160e81b604482015260640161087f565b7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008315610c8b57604051632895a2f560e11b81527f000000000000000000000000000000000000000000000000000000000000000015156004820152610c8b90612710906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063512b45ea90602401602060405180830381865afa158015610c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c729190613403565b610c7c9087613449565b610c869190613468565b612334565b8215610d5c57604051632895a2f560e11b81527f000000000000000000000000000000000000000000000000000000000000000015156004820152610d5c90612710906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063512b45ea90602401602060405180830381865afa158015610d1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d439190613403565b610d4d9086613449565b610d579190613468565b612401565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610da0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc49190613403565b6040516370a0823160e01b81523060048201529096506001600160a01b038216906370a0823190602401602060405180830381865afa158015610e0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2f9190613403565b9450610e3b88886124c7565b610e4587876124c7565b1015610e775760405162461bcd60e51b81526020600482015260016024820152604b60f81b604482015260640161087f565b5050610e8584848888612613565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a350506001601355505050505050505050565b60008054610ef99061348a565b80601f0160208091040260200160405190810160405280929190818152602001828054610f259061348a565b8015610f725780601f10610f4757610100808354040283529160200191610f72565b820191906000526020600020905b815481529060010190602001808311610f5557829003601f168201915b505050505081565b3360008181526003602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610fd59086815260200190565b60405180910390a35060015b92915050565b606060008367ffffffffffffffff811115611004576110046134bf565b60405190808252806020026020018201604052801561102d578160200160208202803683370190505b5060075490915060009061104390600190613432565b905060006110518587613449565b61105b9083613432565b90506000805b838310156111d35761107387846134d5565b915060006007848154811061108a5761108a6134ed565b906000526020600020906003020160000154600784815481106110af576110af6134ed565b9060005260206000209060030201600001546110cb9190613432565b9050600081600786815481106110e3576110e36134ed565b90600052602060002090600302016001015460078681548110611108576111086134ed565b9060005260206000209060030201600101546111249190613432565b61112e9190613468565b905060008260078781548110611146576111466134ed565b9060005260206000209060030201600201546007878154811061116b5761116b6134ed565b9060005260206000209060030201600201546111879190613432565b6111919190613468565b905061119f8c8e84846127a7565b8885815181106111b1576111b16134ed565b60209081029190910101525050506001016111cc87846134d5565b9250611061565b509293505050505b949350505050565b600b54600c544260008080611201600854600954600a549192909190565b92509250925083811461124a57600061121a8286613432565b90506112268185613449565b61123090886134d5565b965061123c8184613449565b61124690876134d5565b9550505b505050909192565b6001600160a01b03831660008181526003602090815260408083203380855292528220549192909190821480159061128c57506000198114155b1561130257600061129d8583613432565b6001600160a01b038881166000818152600360209081526040808320948916808452948252918290208590559051848152939450919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505b61130d868686612a9c565b6001925050505b9392505050565b6007818154811061132b57600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b6000806113596119c0565b90506000806113666111e3565b50845191935091504214156113cf576007805461138590600290613432565b81548110611395576113956134ed565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505092505b82516000906113de9042613432565b90506000818560200151856113f39190613432565b6113fd9190613468565b90506000828660400151856114129190613432565b61141c9190613468565b905061142a888a84846127a7565b9998505050505050505050565b60606111db8484846001610fe7565b600060135460011461145757600080fd5b60026013556008546009546040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156114c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ed9190613403565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015611557573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157b9190613403565b905060006115898584613432565b905060006115978584613432565b600254909150806115d5576103e86115b76115b28486613449565b612b5c565b6115c19190613432565b97506115d060006103e8612bcc565b61160a565b611607876115e38386613449565b6115ed9190613468565b876115f88486613449565b6116029190613468565b612c5f565b97505b600088116116405760405162461bcd60e51b8152602060048201526003602482015262494c4d60e81b604482015260640161087f565b61164a8989612bcc565b61165685858989612613565b604080518481526020810184905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a250506001601355509395945050505050565b6000806013546001146116b557600080fd5b60026013556008546009546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000906000906001600160a01b038416906370a0823190602401602060405180830381865afa15801561174b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176f9190613403565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a0823190602401602060405180830381865afa1580156117b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117dd9190613403565b3060009081526004602052604090205460025491925090806117ff8584613449565b6118099190613468565b9950806118168484613449565b6118209190613468565b985060008a1180156118325750600089115b6118645760405162461bcd60e51b815260206004820152600360248201526224a62160e91b604482015260640161087f565b61186e3083612c75565b611879868c8c612245565b611884858c8b612245565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa1580156118c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ec9190613403565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa158015611933573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119579190613403565b925061196584848a8a612613565b604080518b8152602081018b90526001600160a01b038d169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a350505050505050506001601381905550915091565b6119e460405180606001604052806000815260200160008152602001600081525090565b600780546119f490600190613432565b81548110611a0457611a046134ed565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905090565b60018054610ef99061348a565b600080611a5d8585856001610fe7565b90506000805b8251811015611aa557828181518110611a7e57611a7e6134ed565b602002602001015182611a9191906134d5565b915080611a9d81613503565b915050611a63565b50611ab08482613468565b9695505050505050565b6000611ac7338484612a9c565b50600192915050565b601354600114611adf57600080fd5b60026013556008546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000917f000000000000000000000000000000000000000000000000000000000000000091611bac9184918691906001600160a01b038416906370a08231906024015b602060405180830381865afa158015611b79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9d9190613403565b611ba79190613432565b612245565b6009546040516370a0823160e01b8152306004820152611be49183918691906001600160a01b038416906370a0823190602401611b5c565b5050600160135550565b600080611bfa33612d00565b50503360009081526011602090815260408083205460129092529091205481151580611c265750600081115b15611d11573360008181526011602090815260408083208390556012909152808220919091555163299e7ae760e11b8152600481019190915260248101839052604481018290526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063533cf5ce90606401600060405180830381600087803b158015611cbb57600080fd5b505af1158015611ccf573d6000803e3d6000fd5b505060408051858152602081018590523393508392507f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e94645910160405180910390a35b9091565b42841015611d555760405162461bcd60e51b815260206004820152600d60248201526c14185a5c8e8811561412549151609a1b604482015260640161087f565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051611d85919061351e565b60408051918290038220828201825260018352603160f81b6020938401528151928301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f19818403018152918152815160209283012060058190556001600160a01b038a166000908152600690935290822080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b919087611e5083613503565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e00160405160208183030381529060405280519060200120604051602001611ec992919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015611f34573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590611f6a5750886001600160a01b0316816001600160a01b0316145b611fb65760405162461bcd60e51b815260206004820152601760248201527f506169723a20494e56414c49445f5349474e4154555245000000000000000000604482015260640161087f565b6001600160a01b038981166000818152600360209081526040808320948d16808452948252918290208b905590518a81527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050505050505050565b600854600954604051632895a2f560e11b81527f0000000000000000000000000000000000000000000000000000000000000000151560048201526000929190612710907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063512b45ea90602401602060405180830381865afa1580156120b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d69190613403565b6120e09087613449565b6120ea9190613468565b6120f49086613432565b9450612102858584846127a7565b95945050505050565b60135460011461211a57600080fd5b60026013556040516370a0823160e01b815230600482015261223e907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612187573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ab9190613403565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561220f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122339190613403565b600854600954612613565b6001601355565b6000836001600160a01b03163b1161225c57600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916122b891906135ba565b6000604051808303816000865af19150503d80600081146122f5576040519150601f19603f3d011682016040523d82523d6000602084013e6122fa565b606091505b50915091508180156123245750805115806123245750808060200190518101906123249190613395565b61232d57600080fd5b5050505050565b61237f7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000083612245565b60025460009061239783670de0b6b3a7640000613449565b6123a19190613468565b905080156123c15780600d60008282546123bb91906134d5565b90915550505b604080518381526000602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b61244c7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000083612245565b60025460009061246483670de0b6b3a7640000613449565b61246e9190613468565b9050801561248e5780600e600082825461248891906134d5565b90915550505b60408051600081526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291016123f5565b60007f0000000000000000000000000000000000000000000000000000000000000000156126025760007f000000000000000000000000000000000000000000000000000000000000000061252485670de0b6b3a7640000613449565b61252e9190613468565b905060007f000000000000000000000000000000000000000000000000000000000000000061256585670de0b6b3a7640000613449565b61256f9190613468565b90506000670de0b6b3a76400006125868385613449565b6125909190613468565b90506000670de0b6b3a76400006125a78480613449565b6125b19190613468565b670de0b6b3a76400006125c48680613449565b6125ce9190613468565b6125d891906134d5565b9050670de0b6b3a76400006125ed8284613449565b6125f79190613468565b945050505050610fe1565b61260c8284613449565b9050610fe1565b600a5442906000906126259083613432565b905060008111801561263657508315155b801561264157508215155b15612688576126508185613449565b600b600082825461266191906134d5565b9091555061267190508184613449565b600c600082825461268291906134d5565b90915550505b60006126926119c0565b80519091506126a19084613432565b91506107088211156127565760408051606081018252848152600b5460208201908152600c549282019283526007805460018101825560009190915291517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688600390930292830155517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68982015590517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a909101555b60088790556009869055600a83905560408051888152602081018890527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a150505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000015612a2a5760006127db84846124c7565b90507f000000000000000000000000000000000000000000000000000000000000000061281085670de0b6b3a7640000613449565b61281a9190613468565b93507f000000000000000000000000000000000000000000000000000000000000000061284f84670de0b6b3a7640000613449565b6128599190613468565b92506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b03161461289e5784866128a1565b85855b915091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b031614612920577f000000000000000000000000000000000000000000000000000000000000000061291189670de0b6b3a7640000613449565b61291b9190613468565b61295d565b7f000000000000000000000000000000000000000000000000000000000000000061295389670de0b6b3a7640000613449565b61295d9190613468565b9750600061297561296e848b6134d5565b8584612e60565b61297f9083613432565b9050670de0b6b3a76400007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316896001600160a01b0316146129e9577f0000000000000000000000000000000000000000000000000000000000000000612a0b565b7f00000000000000000000000000000000000000000000000000000000000000005b612a159083613449565b612a1f9190613468565b9450505050506111db565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b031614612a6d578385612a70565b84845b9092509050612a7f87836134d5565b612a898289613449565b612a939190613468565b925050506111db565b612aa583612d00565b612aae82612d00565b6001600160a01b03831660009081526004602052604081208054839290612ad6908490613432565b90915550506001600160a01b03821660009081526004602052604081208054839290612b039084906134d5565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612b4f91815260200190565b60405180910390a3505050565b60006003821115612bbd5750806000612b76600283613468565b612b819060016134d5565b90505b81811015612bb757905080600281612b9c8186613468565b612ba691906134d5565b612bb09190613468565b9050612b84565b50919050565b8115612bc7575060015b919050565b612bd582612d00565b8060026000828254612be791906134d5565b90915550506001600160a01b03821660009081526004602052604081208054839290612c149084906134d5565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b6000818310612c6e5781611314565b5090919050565b612c7e82612d00565b8060026000828254612c909190613432565b90915550506001600160a01b03821660009081526004602052604081208054839290612cbd908490613432565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001612c53565b6001600160a01b0381166000908152600460205260409020548015612e2e576001600160a01b0382166000908152600f60209081526040808320805460108085529285208054600d54600e54948190559490955282905593612d628584613432565b90506000612d708584613432565b90508115612dcb576000670de0b6b3a7640000612d8d848a613449565b612d979190613468565b6001600160a01b038a16600090815260116020526040812080549293508392909190612dc49084906134d5565b9091555050505b8015612e24576000670de0b6b3a7640000612de6838a613449565b612df09190613468565b6001600160a01b038a16600090815260126020526040812080549293508392909190612e1d9084906134d5565b9091555050505b5050505050505050565b600d546001600160a01b0383166000908152600f6020908152604080832093909355600e546010909152919020555050565b6000805b60ff811015612f6657826000612e7a8783612f6f565b905085811015612eca576000612e90888761300c565b612e9a8389613432565b612eac90670de0b6b3a7640000613449565b612eb69190613468565b9050612ec281876134d5565b955050612f0c565b6000612ed6888761300c565b612ee08884613432565b612ef290670de0b6b3a7640000613449565b612efc9190613468565b9050612f088187613432565b9550505b81851115612f35576001612f208387613432565b11612f3057849350505050611314565b612f51565b6001612f418684613432565b11612f5157849350505050611314565b50508080612f5e90613503565b915050612e64565b50909392505050565b6000670de0b6b3a764000082818581612f888280613449565b612f929190613468565b612f9c9190613449565b612fa69190613468565b612fb09190613449565b612fba9190613468565b670de0b6b3a7640000808481612fd08280613449565b612fda9190613468565b612fe49190613449565b612fee9190613468565b612ff89086613449565b6130029190613468565b61131491906134d5565b6000670de0b6b3a764000083816130238280613449565b61302d9190613468565b6130379190613449565b6130419190613468565b670de0b6b3a7640000806130558580613449565b61305f9190613468565b61306a866003613449565b612ff89190613449565b80356001600160a01b0381168114612bc757600080fd5b6000806000806000608086880312156130a357600080fd5b85359450602086013593506130ba60408701613074565b9250606086013567ffffffffffffffff808211156130d757600080fd5b818801915088601f8301126130eb57600080fd5b8135818111156130fa57600080fd5b89602082850101111561310c57600080fd5b9699959850939650602001949392505050565b60005b8381101561313a578181015183820152602001613122565b83811115613149576000848401525b50505050565b602081526000825180602084015261316e81604085016020870161311f565b601f01601f19169190910160400192915050565b6000806040838503121561319557600080fd5b61319e83613074565b946020939093013593505050565b600080600080608085870312156131c257600080fd5b6131cb85613074565b966020860135965060408601359560600135945092505050565b6020808252825182820181905260009190848201906040850190845b8181101561321d57835183529284019291840191600101613201565b50909695505050505050565b60006020828403121561323b57600080fd5b61131482613074565b60008060006060848603121561325957600080fd5b61326284613074565b925061327060208501613074565b9150604084013590509250925092565b60006020828403121561329257600080fd5b5035919050565b6000806000606084860312156132ae57600080fd5b6132b784613074565b95602085013595506040909401359392505050565b600080600080600080600060e0888a0312156132e757600080fd5b6132f088613074565b96506132fe60208901613074565b95506040880135945060608801359350608088013560ff8116811461332257600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561335257600080fd5b61335b83613074565b915061336960208401613074565b90509250929050565b6000806040838503121561338557600080fd5b8235915061336960208401613074565b6000602082840312156133a757600080fd5b8151801515811461131457600080fd5b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b60006020828403121561341557600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000828210156134445761344461341c565b500390565b60008160001904831182151516156134635761346361341c565b500290565b60008261348557634e487b7160e01b600052601260045260246000fd5b500490565b600181811c9082168061349e57607f821691505b60208210811415612bb757634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600082198211156134e8576134e861341c565b500190565b634e487b7160e01b600052603260045260246000fd5b60006000198214156135175761351761341c565b5060010190565b600080835481600182811c91508083168061353a57607f831692505b602080841082141561355a57634e487b7160e01b86526022600452602486fd5b81801561356e576001811461357f576135ac565b60ff198616895284890196506135ac565b60008a81526020902060005b868110156135a45781548b82015290850190830161358b565b505084890196505b509498975050505050505050565b600082516135cc81846020870161311f565b919091019291505056fea264697066735822122012bbc26e6d059c64971894076e1c061b5af33828e3ac3045418303c8201d1fe764736f6c634300080b003360e060405234801561001057600080fd5b5060405161037038038061037083398101604081905261002f91610066565b336080526001600160a01b0391821660a0521660c052610099565b80516001600160a01b038116811461006157600080fd5b919050565b6000806040838503121561007957600080fd5b6100828361004a565b91506100906020840161004a565b90509250929050565b60805160a05160c0516102ab6100c5600039600060b601526000608501526000605001526102ab6000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063533cf5ce14610030575b600080fd5b61004361003e3660046101d0565b610045565b005b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461007a57600080fd5b81156100ab576100ab7f000000000000000000000000000000000000000000000000000000000000000084846100e1565b80156100dc576100dc7f000000000000000000000000000000000000000000000000000000000000000084836100e1565b505050565b6000836001600160a01b03163b116100f857600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916101549190610211565b6000604051808303816000865af19150503d8060008114610191576040519150601f19603f3d011682016040523d82523d6000602084013e610196565b606091505b50915091508180156101c05750805115806101c05750808060200190518101906101c0919061024c565b6101c957600080fd5b5050505050565b6000806000606084860312156101e557600080fd5b83356001600160a01b03811681146101fc57600080fd5b95602085013595506040909401359392505050565b6000825160005b818110156102325760208186018101518583015201610218565b81811115610241576000828501525b509190910192915050565b60006020828403121561025e57600080fd5b8151801515811461026e57600080fd5b939250505056fea26469706673582212205f5c908ef3326a953bd870e8659b0596ff46fae086e9667d4d69778578e14adc64736f6c634300080b0033a2646970667358221220d044256e297a575c8be24751aa6c5b37af7db2fd6b3617dfa590cf6bacfad43964736f6c634300080b0033", + "linkReferences": {}, + "deployedLinkReferences": {} + } \ No newline at end of file diff --git a/external/abi/velodrome/VelodromePair.json b/external/abi/velodrome/VelodromePair.json new file mode 100644 index 000000000..1bc237fd9 --- /dev/null +++ b/external/abi/velodrome/VelodromePair.json @@ -0,0 +1,8 @@ +{ + "contractName": "VelodromePair", + "abi": [{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Fees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount0Out","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1Out","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reserve0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reserve1","type":"uint256"}],"name":"Sync","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blockTimestampLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"burn","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimFees","outputs":[{"internalType":"uint256","name":"claimed0","type":"uint256"},{"internalType":"uint256","name":"claimed1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimable0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimable1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"current","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentCumulativePrices","outputs":[{"internalType":"uint256","name":"reserve0Cumulative","type":"uint256"},{"internalType":"uint256","name":"reserve1Cumulative","type":"uint256"},{"internalType":"uint256","name":"blockTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fees","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"tokenIn","type":"address"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReserves","outputs":[{"internalType":"uint256","name":"_reserve0","type":"uint256"},{"internalType":"uint256","name":"_reserve1","type":"uint256"},{"internalType":"uint256","name":"_blockTimestampLast","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"index0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"index1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastObservation","outputs":[{"components":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"reserve0Cumulative","type":"uint256"},{"internalType":"uint256","name":"reserve1Cumulative","type":"uint256"}],"internalType":"struct Pair.Observation","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metadata","outputs":[{"internalType":"uint256","name":"dec0","type":"uint256"},{"internalType":"uint256","name":"dec1","type":"uint256"},{"internalType":"uint256","name":"r0","type":"uint256"},{"internalType":"uint256","name":"r1","type":"uint256"},{"internalType":"bool","name":"st","type":"bool"},{"internalType":"address","name":"t0","type":"address"},{"internalType":"address","name":"t1","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"observationLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"observations","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"reserve0Cumulative","type":"uint256"},{"internalType":"uint256","name":"reserve1Cumulative","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"points","type":"uint256"}],"name":"prices","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"granularity","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserve0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserve0CumulativeLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserve1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserve1CumulativeLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"points","type":"uint256"},{"internalType":"uint256","name":"window","type":"uint256"}],"name":"sample","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"skim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"supplyIndex0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"supplyIndex1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0Out","type":"uint256"},{"internalType":"uint256","name":"amount1Out","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"swap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sync","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokens","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}], + "bytecode": "0x61016060405260006002556000600d556000600e5560016013553480156200002657600080fd5b50336001600160a01b0316610100816001600160a01b0316815250506000806000336001600160a01b031663eb13c4cf6040518163ffffffff1660e01b8152600401606060405180830381865afa15801562000086573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000ac9190620007c8565b8015156080526001600160a01b0380831660c052831660a052604051929550909350915083908390620000df90620006f7565b6001600160a01b03928316815291166020820152604001604051809103906000f08015801562000113573d6000803e3d6000fd5b506001600160a01b031660e05280156200034557826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000166573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000190919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620001cf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620001f9919081019062000863565b6040516020016200020c9291906200091b565b604051602081830303815290604052600090805190602001906200023292919062000705565b50826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000272573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200029c919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620002db573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000305919081019062000863565b6040516020016200031892919062000976565b604051602081830303815290604052600190805190602001906200033e92919062000705565b506200055e565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000384573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620003ae919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620003ed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000417919081019062000863565b6040516020016200042a929190620009c7565b604051602081830303815290604052600090805190602001906200045092919062000705565b50826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000490573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620004ba919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620004f9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000523919081019062000863565b6040516020016200053692919062000a24565b604051602081830303815290604052600190805190602001906200055c92919062000705565b505b826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200059d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005c3919062000a46565b620005d090600a62000b87565b6101208181525050816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000617573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200063d919062000a46565b6200064a90600a62000b87565b6101405250506040805160608101825242815260006020820181815292820181815260078054600181018255925291517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860039092029182015591517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689830155517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a909101555062000bd5565b610370806200436283390190565b828054620007139062000b98565b90600052602060002090601f01602090048101928262000737576000855562000782565b82601f106200075257805160ff191683800117855562000782565b8280016001018555821562000782579182015b828111156200078257825182559160200191906001019062000765565b506200079092915062000794565b5090565b5b8082111562000790576000815560010162000795565b80516001600160a01b0381168114620007c357600080fd5b919050565b600080600060608486031215620007de57600080fd5b620007e984620007ab565b9250620007f960208501620007ab565b9150604084015180151581146200080f57600080fd5b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b60005b838110156200084d57818101518382015260200162000833565b838111156200085d576000848401525b50505050565b6000602082840312156200087657600080fd5b81516001600160401b03808211156200088e57600080fd5b818401915084601f830112620008a357600080fd5b815181811115620008b857620008b86200081a565b604051601f8201601f19908116603f01168101908382118183101715620008e357620008e36200081a565b81604052828152876020848701011115620008fd57600080fd5b6200091083602083016020880162000830565b979650505050505050565b6e029ba30b13632ab189020a6a690169608d1b8152600083516200094781600f85016020880162000830565b602f60f81b600f9184019182015283516200096a81601084016020880162000830565b01601001949350505050565b6473414d4d2d60d81b8152600083516200099881600585016020880162000830565b602f60f81b6005918401918201528351620009bb81600684016020880162000830565b01600601949350505050565b7002b37b630ba34b632ab189020a6a690169607d1b815260008351620009f581601185016020880162000830565b602f60f81b601191840191820152835162000a1881601284016020880162000830565b01601201949350505050565b6476414d4d2d60d81b8152600083516200099881600585016020880162000830565b60006020828403121562000a5957600080fd5b815160ff8116811462000a6b57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111562000ac957816000190482111562000aad5762000aad62000a72565b8085161562000abb57918102915b93841c939080029062000a8d565b509250929050565b60008262000ae25750600162000b81565b8162000af15750600062000b81565b816001811462000b0a576002811462000b155762000b35565b600191505062000b81565b60ff84111562000b295762000b2962000a72565b50506001821b62000b81565b5060208310610133831016604e8410600b841016171562000b5a575081810a62000b81565b62000b66838362000a88565b806000190482111562000b7d5762000b7d62000a72565b0290505b92915050565b600062000a6b60ff84168362000ad1565b600181811c9082168062000bad57607f821691505b6020821081141562000bcf57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e05161010051610120516101405161360c62000d5660003960008181610431015281816125340152818161281e015281816128e001526129eb01526000818161040e015281816124f3015281816127df0152818161292201526129c50152600081816107b801528181610c0701528181610cd801526120630152600081816105f201528181611c770152818161235a01526124270152600081816104bb0152818161064701528181610714015281816108f301528181610b9b01528181611510015281816116f701528181611b1e015281816121c001526124060152600081816102f90152818161049301528181610622015281816108d201528181610b7a0152818161147a015281816116d501528181611afc015281816121380152818161233901528181612860015281816128a70152818161298c0152612a2f0152600081816103970152818161046301528181610bcf01528181610ca001528181612032015281816124cb01526127ab015261360c6000f3fe608060405234801561001057600080fd5b50600436106102745760003560e01c80637ecebe0011610151578063bda39cad116100c3578063d294f09311610087578063d294f09314610736578063d505accf1461073e578063dd62ed3e14610751578063ebeb31db1461077c578063f140a35a14610784578063fff6cae91461079757600080fd5b8063bda39cad146106eb578063bf944dbc146106f4578063c245febc146106fd578063c5700a0214610706578063d21220a71461070f57600080fd5b80639d63848a116101155780639d63848a146106145780639e8cc04b146106725780639f767c8814610685578063a1ac4d13146106a5578063a9059cbb146106c5578063bc25cf77146106d857600080fd5b80637ecebe001461057357806389afcb44146105935780638a7b8cf2146105bb57806395d89b41146105e55780639af1d35a146105ed57600080fd5b8063252c09d7116101ea5780634d5a9f8a116101ae5780634d5a9f8a146104f1578063517b3f82146105115780635881c475146105245780635a76f25e146105375780636a6278421461054057806370a082311461055357600080fd5b8063252c09d7146103cc578063313ce567146103df57806332c0defd146103f9578063392f37e914610402578063443cb4bc146104e857600080fd5b806313345fe11161023c57806313345fe11461033357806318160ddd146103535780631df8c7171461036a578063205aabf11461037257806322be3de11461039257806323b872dd146103b957600080fd5b8063022c0d9f1461027957806306fdde031461028e5780630902f1ac146102ac578063095ea7b3146102d15780630dfe1681146102f4575b600080fd5b61028c61028736600461308b565b61079f565b005b610296610eec565b6040516102a3919061314f565b60405180910390f35b600854600954600a545b604080519384526020840192909252908201526060016102a3565b6102e46102df366004613182565b610f7a565b60405190151581526020016102a3565b61031b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102a3565b6103466103413660046131ac565b610fe7565b6040516102a391906131e5565b61035c60025481565b6040519081526020016102a3565b6102b66111e3565b61035c610380366004613229565b60106020526000908152604090205481565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b6102e46103c7366004613244565b611252565b6102b66103da366004613280565b61131b565b6103e7601281565b60405160ff90911681526020016102a3565b61035c600d5481565b600854600954604080517f000000000000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060208201529081019290925260608201527f0000000000000000000000000000000000000000000000000000000000000000151560808201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660a08301527f00000000000000000000000000000000000000000000000000000000000000001660c082015260e0016102a3565b61035c60085481565b61035c6104ff366004613229565b60116020526000908152604090205481565b61035c61051f366004613182565b61134e565b610346610532366004613299565b611437565b61035c60095481565b61035c61054e366004613229565b611446565b61035c610561366004613229565b60046020526000908152604090205481565b61035c610581366004613229565b60066020526000908152604090205481565b6105a66105a1366004613229565b6116a3565b604080519283526020830191909152016102a3565b6105c36119c0565b60408051825181526020808401519082015291810151908201526060016102a3565b610296611a40565b61031b7f000000000000000000000000000000000000000000000000000000000000000081565b604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811682527f0000000000000000000000000000000000000000000000000000000000000000166020820152016102a3565b61035c610680366004613299565b611a4d565b61035c610693366004613229565b600f6020526000908152604090205481565b61035c6106b3366004613229565b60126020526000908152604090205481565b6102e46106d3366004613182565b611aba565b61028c6106e6366004613229565b611ad0565b61035c600e5481565b61035c600b5481565b61035c600c5481565b61035c600a5481565b61031b7f000000000000000000000000000000000000000000000000000000000000000081565b6105a6611bee565b61028c61074c3660046132cc565b611d15565b61035c61075f36600461333f565b600360209081526000928352604080842090915290825290205481565b60075461035c565b61035c610792366004613372565b61201d565b61028c61210b565b6013546001146107ae57600080fd5b60026013819055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b187bd266040518163ffffffff1660e01b8152600401602060405180830381865afa158015610814573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108389190613395565b1561084257600080fd5b60008511806108515750600084115b6108885760405162461bcd60e51b8152602060048201526003602482015262494f4160e81b60448201526064015b60405180910390fd5b600854600954818710801561089c57508086105b6108cd5760405162461bcd60e51b8152602060048201526002602482015261125360f21b604482015260640161087f565b6000807f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03898116908316148015906109405750806001600160a01b0316896001600160a01b031614155b6109715760405162461bcd60e51b8152602060048201526002602482015261125560f21b604482015260640161087f565b8a1561098257610982828a8d612245565b891561099357610993818a8c612245565b8615610a0057604051639a7bff7960e01b81526001600160a01b038a1690639a7bff79906109cd9033908f908f908e908e906004016133b7565b600060405180830381600087803b1580156109e757600080fd5b505af11580156109fb573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a689190613403565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610aaf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad39190613403565b9250505060008985610ae59190613432565b8311610af2576000610b06565b610afc8a86613432565b610b069084613432565b90506000610b148a86613432565b8311610b21576000610b35565b610b2b8a86613432565b610b359084613432565b90506000821180610b465750600081115b610b785760405162461bcd60e51b815260206004820152600360248201526249494160e81b604482015260640161087f565b7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008315610c8b57604051632895a2f560e11b81527f000000000000000000000000000000000000000000000000000000000000000015156004820152610c8b90612710906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063512b45ea90602401602060405180830381865afa158015610c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c729190613403565b610c7c9087613449565b610c869190613468565b612334565b8215610d5c57604051632895a2f560e11b81527f000000000000000000000000000000000000000000000000000000000000000015156004820152610d5c90612710906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063512b45ea90602401602060405180830381865afa158015610d1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d439190613403565b610d4d9086613449565b610d579190613468565b612401565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610da0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc49190613403565b6040516370a0823160e01b81523060048201529096506001600160a01b038216906370a0823190602401602060405180830381865afa158015610e0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2f9190613403565b9450610e3b88886124c7565b610e4587876124c7565b1015610e775760405162461bcd60e51b81526020600482015260016024820152604b60f81b604482015260640161087f565b5050610e8584848888612613565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a350506001601355505050505050505050565b60008054610ef99061348a565b80601f0160208091040260200160405190810160405280929190818152602001828054610f259061348a565b8015610f725780601f10610f4757610100808354040283529160200191610f72565b820191906000526020600020905b815481529060010190602001808311610f5557829003601f168201915b505050505081565b3360008181526003602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610fd59086815260200190565b60405180910390a35060015b92915050565b606060008367ffffffffffffffff811115611004576110046134bf565b60405190808252806020026020018201604052801561102d578160200160208202803683370190505b5060075490915060009061104390600190613432565b905060006110518587613449565b61105b9083613432565b90506000805b838310156111d35761107387846134d5565b915060006007848154811061108a5761108a6134ed565b906000526020600020906003020160000154600784815481106110af576110af6134ed565b9060005260206000209060030201600001546110cb9190613432565b9050600081600786815481106110e3576110e36134ed565b90600052602060002090600302016001015460078681548110611108576111086134ed565b9060005260206000209060030201600101546111249190613432565b61112e9190613468565b905060008260078781548110611146576111466134ed565b9060005260206000209060030201600201546007878154811061116b5761116b6134ed565b9060005260206000209060030201600201546111879190613432565b6111919190613468565b905061119f8c8e84846127a7565b8885815181106111b1576111b16134ed565b60209081029190910101525050506001016111cc87846134d5565b9250611061565b509293505050505b949350505050565b600b54600c544260008080611201600854600954600a549192909190565b92509250925083811461124a57600061121a8286613432565b90506112268185613449565b61123090886134d5565b965061123c8184613449565b61124690876134d5565b9550505b505050909192565b6001600160a01b03831660008181526003602090815260408083203380855292528220549192909190821480159061128c57506000198114155b1561130257600061129d8583613432565b6001600160a01b038881166000818152600360209081526040808320948916808452948252918290208590559051848152939450919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505b61130d868686612a9c565b6001925050505b9392505050565b6007818154811061132b57600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b6000806113596119c0565b90506000806113666111e3565b50845191935091504214156113cf576007805461138590600290613432565b81548110611395576113956134ed565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505092505b82516000906113de9042613432565b90506000818560200151856113f39190613432565b6113fd9190613468565b90506000828660400151856114129190613432565b61141c9190613468565b905061142a888a84846127a7565b9998505050505050505050565b60606111db8484846001610fe7565b600060135460011461145757600080fd5b60026013556008546009546040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156114c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ed9190613403565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015611557573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157b9190613403565b905060006115898584613432565b905060006115978584613432565b600254909150806115d5576103e86115b76115b28486613449565b612b5c565b6115c19190613432565b97506115d060006103e8612bcc565b61160a565b611607876115e38386613449565b6115ed9190613468565b876115f88486613449565b6116029190613468565b612c5f565b97505b600088116116405760405162461bcd60e51b8152602060048201526003602482015262494c4d60e81b604482015260640161087f565b61164a8989612bcc565b61165685858989612613565b604080518481526020810184905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a250506001601355509395945050505050565b6000806013546001146116b557600080fd5b60026013556008546009546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000906000906001600160a01b038416906370a0823190602401602060405180830381865afa15801561174b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176f9190613403565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a0823190602401602060405180830381865afa1580156117b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117dd9190613403565b3060009081526004602052604090205460025491925090806117ff8584613449565b6118099190613468565b9950806118168484613449565b6118209190613468565b985060008a1180156118325750600089115b6118645760405162461bcd60e51b815260206004820152600360248201526224a62160e91b604482015260640161087f565b61186e3083612c75565b611879868c8c612245565b611884858c8b612245565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa1580156118c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ec9190613403565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa158015611933573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119579190613403565b925061196584848a8a612613565b604080518b8152602081018b90526001600160a01b038d169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a350505050505050506001601381905550915091565b6119e460405180606001604052806000815260200160008152602001600081525090565b600780546119f490600190613432565b81548110611a0457611a046134ed565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905090565b60018054610ef99061348a565b600080611a5d8585856001610fe7565b90506000805b8251811015611aa557828181518110611a7e57611a7e6134ed565b602002602001015182611a9191906134d5565b915080611a9d81613503565b915050611a63565b50611ab08482613468565b9695505050505050565b6000611ac7338484612a9c565b50600192915050565b601354600114611adf57600080fd5b60026013556008546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000917f000000000000000000000000000000000000000000000000000000000000000091611bac9184918691906001600160a01b038416906370a08231906024015b602060405180830381865afa158015611b79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9d9190613403565b611ba79190613432565b612245565b6009546040516370a0823160e01b8152306004820152611be49183918691906001600160a01b038416906370a0823190602401611b5c565b5050600160135550565b600080611bfa33612d00565b50503360009081526011602090815260408083205460129092529091205481151580611c265750600081115b15611d11573360008181526011602090815260408083208390556012909152808220919091555163299e7ae760e11b8152600481019190915260248101839052604481018290526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063533cf5ce90606401600060405180830381600087803b158015611cbb57600080fd5b505af1158015611ccf573d6000803e3d6000fd5b505060408051858152602081018590523393508392507f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e94645910160405180910390a35b9091565b42841015611d555760405162461bcd60e51b815260206004820152600d60248201526c14185a5c8e8811561412549151609a1b604482015260640161087f565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051611d85919061351e565b60408051918290038220828201825260018352603160f81b6020938401528151928301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f19818403018152918152815160209283012060058190556001600160a01b038a166000908152600690935290822080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b919087611e5083613503565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e00160405160208183030381529060405280519060200120604051602001611ec992919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015611f34573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590611f6a5750886001600160a01b0316816001600160a01b0316145b611fb65760405162461bcd60e51b815260206004820152601760248201527f506169723a20494e56414c49445f5349474e4154555245000000000000000000604482015260640161087f565b6001600160a01b038981166000818152600360209081526040808320948d16808452948252918290208b905590518a81527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050505050505050565b600854600954604051632895a2f560e11b81527f0000000000000000000000000000000000000000000000000000000000000000151560048201526000929190612710907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063512b45ea90602401602060405180830381865afa1580156120b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d69190613403565b6120e09087613449565b6120ea9190613468565b6120f49086613432565b9450612102858584846127a7565b95945050505050565b60135460011461211a57600080fd5b60026013556040516370a0823160e01b815230600482015261223e907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612187573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ab9190613403565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561220f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122339190613403565b600854600954612613565b6001601355565b6000836001600160a01b03163b1161225c57600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916122b891906135ba565b6000604051808303816000865af19150503d80600081146122f5576040519150601f19603f3d011682016040523d82523d6000602084013e6122fa565b606091505b50915091508180156123245750805115806123245750808060200190518101906123249190613395565b61232d57600080fd5b5050505050565b61237f7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000083612245565b60025460009061239783670de0b6b3a7640000613449565b6123a19190613468565b905080156123c15780600d60008282546123bb91906134d5565b90915550505b604080518381526000602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b61244c7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000083612245565b60025460009061246483670de0b6b3a7640000613449565b61246e9190613468565b9050801561248e5780600e600082825461248891906134d5565b90915550505b60408051600081526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291016123f5565b60007f0000000000000000000000000000000000000000000000000000000000000000156126025760007f000000000000000000000000000000000000000000000000000000000000000061252485670de0b6b3a7640000613449565b61252e9190613468565b905060007f000000000000000000000000000000000000000000000000000000000000000061256585670de0b6b3a7640000613449565b61256f9190613468565b90506000670de0b6b3a76400006125868385613449565b6125909190613468565b90506000670de0b6b3a76400006125a78480613449565b6125b19190613468565b670de0b6b3a76400006125c48680613449565b6125ce9190613468565b6125d891906134d5565b9050670de0b6b3a76400006125ed8284613449565b6125f79190613468565b945050505050610fe1565b61260c8284613449565b9050610fe1565b600a5442906000906126259083613432565b905060008111801561263657508315155b801561264157508215155b15612688576126508185613449565b600b600082825461266191906134d5565b9091555061267190508184613449565b600c600082825461268291906134d5565b90915550505b60006126926119c0565b80519091506126a19084613432565b91506107088211156127565760408051606081018252848152600b5460208201908152600c549282019283526007805460018101825560009190915291517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688600390930292830155517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68982015590517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a909101555b60088790556009869055600a83905560408051888152602081018890527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a150505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000015612a2a5760006127db84846124c7565b90507f000000000000000000000000000000000000000000000000000000000000000061281085670de0b6b3a7640000613449565b61281a9190613468565b93507f000000000000000000000000000000000000000000000000000000000000000061284f84670de0b6b3a7640000613449565b6128599190613468565b92506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b03161461289e5784866128a1565b85855b915091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b031614612920577f000000000000000000000000000000000000000000000000000000000000000061291189670de0b6b3a7640000613449565b61291b9190613468565b61295d565b7f000000000000000000000000000000000000000000000000000000000000000061295389670de0b6b3a7640000613449565b61295d9190613468565b9750600061297561296e848b6134d5565b8584612e60565b61297f9083613432565b9050670de0b6b3a76400007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316896001600160a01b0316146129e9577f0000000000000000000000000000000000000000000000000000000000000000612a0b565b7f00000000000000000000000000000000000000000000000000000000000000005b612a159083613449565b612a1f9190613468565b9450505050506111db565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b031614612a6d578385612a70565b84845b9092509050612a7f87836134d5565b612a898289613449565b612a939190613468565b925050506111db565b612aa583612d00565b612aae82612d00565b6001600160a01b03831660009081526004602052604081208054839290612ad6908490613432565b90915550506001600160a01b03821660009081526004602052604081208054839290612b039084906134d5565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612b4f91815260200190565b60405180910390a3505050565b60006003821115612bbd5750806000612b76600283613468565b612b819060016134d5565b90505b81811015612bb757905080600281612b9c8186613468565b612ba691906134d5565b612bb09190613468565b9050612b84565b50919050565b8115612bc7575060015b919050565b612bd582612d00565b8060026000828254612be791906134d5565b90915550506001600160a01b03821660009081526004602052604081208054839290612c149084906134d5565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b6000818310612c6e5781611314565b5090919050565b612c7e82612d00565b8060026000828254612c909190613432565b90915550506001600160a01b03821660009081526004602052604081208054839290612cbd908490613432565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001612c53565b6001600160a01b0381166000908152600460205260409020548015612e2e576001600160a01b0382166000908152600f60209081526040808320805460108085529285208054600d54600e54948190559490955282905593612d628584613432565b90506000612d708584613432565b90508115612dcb576000670de0b6b3a7640000612d8d848a613449565b612d979190613468565b6001600160a01b038a16600090815260116020526040812080549293508392909190612dc49084906134d5565b9091555050505b8015612e24576000670de0b6b3a7640000612de6838a613449565b612df09190613468565b6001600160a01b038a16600090815260126020526040812080549293508392909190612e1d9084906134d5565b9091555050505b5050505050505050565b600d546001600160a01b0383166000908152600f6020908152604080832093909355600e546010909152919020555050565b6000805b60ff811015612f6657826000612e7a8783612f6f565b905085811015612eca576000612e90888761300c565b612e9a8389613432565b612eac90670de0b6b3a7640000613449565b612eb69190613468565b9050612ec281876134d5565b955050612f0c565b6000612ed6888761300c565b612ee08884613432565b612ef290670de0b6b3a7640000613449565b612efc9190613468565b9050612f088187613432565b9550505b81851115612f35576001612f208387613432565b11612f3057849350505050611314565b612f51565b6001612f418684613432565b11612f5157849350505050611314565b50508080612f5e90613503565b915050612e64565b50909392505050565b6000670de0b6b3a764000082818581612f888280613449565b612f929190613468565b612f9c9190613449565b612fa69190613468565b612fb09190613449565b612fba9190613468565b670de0b6b3a7640000808481612fd08280613449565b612fda9190613468565b612fe49190613449565b612fee9190613468565b612ff89086613449565b6130029190613468565b61131491906134d5565b6000670de0b6b3a764000083816130238280613449565b61302d9190613468565b6130379190613449565b6130419190613468565b670de0b6b3a7640000806130558580613449565b61305f9190613468565b61306a866003613449565b612ff89190613449565b80356001600160a01b0381168114612bc757600080fd5b6000806000806000608086880312156130a357600080fd5b85359450602086013593506130ba60408701613074565b9250606086013567ffffffffffffffff808211156130d757600080fd5b818801915088601f8301126130eb57600080fd5b8135818111156130fa57600080fd5b89602082850101111561310c57600080fd5b9699959850939650602001949392505050565b60005b8381101561313a578181015183820152602001613122565b83811115613149576000848401525b50505050565b602081526000825180602084015261316e81604085016020870161311f565b601f01601f19169190910160400192915050565b6000806040838503121561319557600080fd5b61319e83613074565b946020939093013593505050565b600080600080608085870312156131c257600080fd5b6131cb85613074565b966020860135965060408601359560600135945092505050565b6020808252825182820181905260009190848201906040850190845b8181101561321d57835183529284019291840191600101613201565b50909695505050505050565b60006020828403121561323b57600080fd5b61131482613074565b60008060006060848603121561325957600080fd5b61326284613074565b925061327060208501613074565b9150604084013590509250925092565b60006020828403121561329257600080fd5b5035919050565b6000806000606084860312156132ae57600080fd5b6132b784613074565b95602085013595506040909401359392505050565b600080600080600080600060e0888a0312156132e757600080fd5b6132f088613074565b96506132fe60208901613074565b95506040880135945060608801359350608088013560ff8116811461332257600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561335257600080fd5b61335b83613074565b915061336960208401613074565b90509250929050565b6000806040838503121561338557600080fd5b8235915061336960208401613074565b6000602082840312156133a757600080fd5b8151801515811461131457600080fd5b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b60006020828403121561341557600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000828210156134445761344461341c565b500390565b60008160001904831182151516156134635761346361341c565b500290565b60008261348557634e487b7160e01b600052601260045260246000fd5b500490565b600181811c9082168061349e57607f821691505b60208210811415612bb757634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600082198211156134e8576134e861341c565b500190565b634e487b7160e01b600052603260045260246000fd5b60006000198214156135175761351761341c565b5060010190565b600080835481600182811c91508083168061353a57607f831692505b602080841082141561355a57634e487b7160e01b86526022600452602486fd5b81801561356e576001811461357f576135ac565b60ff198616895284890196506135ac565b60008a81526020902060005b868110156135a45781548b82015290850190830161358b565b505084890196505b509498975050505050505050565b600082516135cc81846020870161311f565b919091019291505056fea264697066735822122012bbc26e6d059c64971894076e1c061b5af33828e3ac3045418303c8201d1fe764736f6c634300080b003360e060405234801561001057600080fd5b5060405161037038038061037083398101604081905261002f91610066565b336080526001600160a01b0391821660a0521660c052610099565b80516001600160a01b038116811461006157600080fd5b919050565b6000806040838503121561007957600080fd5b6100828361004a565b91506100906020840161004a565b90509250929050565b60805160a05160c0516102ab6100c5600039600060b601526000608501526000605001526102ab6000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063533cf5ce14610030575b600080fd5b61004361003e3660046101d0565b610045565b005b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461007a57600080fd5b81156100ab576100ab7f000000000000000000000000000000000000000000000000000000000000000084846100e1565b80156100dc576100dc7f000000000000000000000000000000000000000000000000000000000000000084836100e1565b505050565b6000836001600160a01b03163b116100f857600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916101549190610211565b6000604051808303816000865af19150503d8060008114610191576040519150601f19603f3d011682016040523d82523d6000602084013e610196565b606091505b50915091508180156101c05750805115806101c05750808060200190518101906101c0919061024c565b6101c957600080fd5b5050505050565b6000806000606084860312156101e557600080fd5b83356001600160a01b03811681146101fc57600080fd5b95602085013595506040909401359392505050565b6000825160005b818110156102325760208186018101518583015201610218565b81811115610241576000828501525b509190910192915050565b60006020828403121561025e57600080fd5b8151801515811461026e57600080fd5b939250505056fea26469706673582212205f5c908ef3326a953bd870e8659b0596ff46fae086e9667d4d69778578e14adc64736f6c634300080b0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102745760003560e01c80637ecebe0011610151578063bda39cad116100c3578063d294f09311610087578063d294f09314610736578063d505accf1461073e578063dd62ed3e14610751578063ebeb31db1461077c578063f140a35a14610784578063fff6cae91461079757600080fd5b8063bda39cad146106eb578063bf944dbc146106f4578063c245febc146106fd578063c5700a0214610706578063d21220a71461070f57600080fd5b80639d63848a116101155780639d63848a146106145780639e8cc04b146106725780639f767c8814610685578063a1ac4d13146106a5578063a9059cbb146106c5578063bc25cf77146106d857600080fd5b80637ecebe001461057357806389afcb44146105935780638a7b8cf2146105bb57806395d89b41146105e55780639af1d35a146105ed57600080fd5b8063252c09d7116101ea5780634d5a9f8a116101ae5780634d5a9f8a146104f1578063517b3f82146105115780635881c475146105245780635a76f25e146105375780636a6278421461054057806370a082311461055357600080fd5b8063252c09d7146103cc578063313ce567146103df57806332c0defd146103f9578063392f37e914610402578063443cb4bc146104e857600080fd5b806313345fe11161023c57806313345fe11461033357806318160ddd146103535780631df8c7171461036a578063205aabf11461037257806322be3de11461039257806323b872dd146103b957600080fd5b8063022c0d9f1461027957806306fdde031461028e5780630902f1ac146102ac578063095ea7b3146102d15780630dfe1681146102f4575b600080fd5b61028c61028736600461308b565b61079f565b005b610296610eec565b6040516102a3919061314f565b60405180910390f35b600854600954600a545b604080519384526020840192909252908201526060016102a3565b6102e46102df366004613182565b610f7a565b60405190151581526020016102a3565b61031b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102a3565b6103466103413660046131ac565b610fe7565b6040516102a391906131e5565b61035c60025481565b6040519081526020016102a3565b6102b66111e3565b61035c610380366004613229565b60106020526000908152604090205481565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b6102e46103c7366004613244565b611252565b6102b66103da366004613280565b61131b565b6103e7601281565b60405160ff90911681526020016102a3565b61035c600d5481565b600854600954604080517f000000000000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060208201529081019290925260608201527f0000000000000000000000000000000000000000000000000000000000000000151560808201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660a08301527f00000000000000000000000000000000000000000000000000000000000000001660c082015260e0016102a3565b61035c60085481565b61035c6104ff366004613229565b60116020526000908152604090205481565b61035c61051f366004613182565b61134e565b610346610532366004613299565b611437565b61035c60095481565b61035c61054e366004613229565b611446565b61035c610561366004613229565b60046020526000908152604090205481565b61035c610581366004613229565b60066020526000908152604090205481565b6105a66105a1366004613229565b6116a3565b604080519283526020830191909152016102a3565b6105c36119c0565b60408051825181526020808401519082015291810151908201526060016102a3565b610296611a40565b61031b7f000000000000000000000000000000000000000000000000000000000000000081565b604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811682527f0000000000000000000000000000000000000000000000000000000000000000166020820152016102a3565b61035c610680366004613299565b611a4d565b61035c610693366004613229565b600f6020526000908152604090205481565b61035c6106b3366004613229565b60126020526000908152604090205481565b6102e46106d3366004613182565b611aba565b61028c6106e6366004613229565b611ad0565b61035c600e5481565b61035c600b5481565b61035c600c5481565b61035c600a5481565b61031b7f000000000000000000000000000000000000000000000000000000000000000081565b6105a6611bee565b61028c61074c3660046132cc565b611d15565b61035c61075f36600461333f565b600360209081526000928352604080842090915290825290205481565b60075461035c565b61035c610792366004613372565b61201d565b61028c61210b565b6013546001146107ae57600080fd5b60026013819055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b187bd266040518163ffffffff1660e01b8152600401602060405180830381865afa158015610814573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108389190613395565b1561084257600080fd5b60008511806108515750600084115b6108885760405162461bcd60e51b8152602060048201526003602482015262494f4160e81b60448201526064015b60405180910390fd5b600854600954818710801561089c57508086105b6108cd5760405162461bcd60e51b8152602060048201526002602482015261125360f21b604482015260640161087f565b6000807f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03898116908316148015906109405750806001600160a01b0316896001600160a01b031614155b6109715760405162461bcd60e51b8152602060048201526002602482015261125560f21b604482015260640161087f565b8a1561098257610982828a8d612245565b891561099357610993818a8c612245565b8615610a0057604051639a7bff7960e01b81526001600160a01b038a1690639a7bff79906109cd9033908f908f908e908e906004016133b7565b600060405180830381600087803b1580156109e757600080fd5b505af11580156109fb573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a689190613403565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610aaf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad39190613403565b9250505060008985610ae59190613432565b8311610af2576000610b06565b610afc8a86613432565b610b069084613432565b90506000610b148a86613432565b8311610b21576000610b35565b610b2b8a86613432565b610b359084613432565b90506000821180610b465750600081115b610b785760405162461bcd60e51b815260206004820152600360248201526249494160e81b604482015260640161087f565b7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008315610c8b57604051632895a2f560e11b81527f000000000000000000000000000000000000000000000000000000000000000015156004820152610c8b90612710906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063512b45ea90602401602060405180830381865afa158015610c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c729190613403565b610c7c9087613449565b610c869190613468565b612334565b8215610d5c57604051632895a2f560e11b81527f000000000000000000000000000000000000000000000000000000000000000015156004820152610d5c90612710906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063512b45ea90602401602060405180830381865afa158015610d1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d439190613403565b610d4d9086613449565b610d579190613468565b612401565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610da0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc49190613403565b6040516370a0823160e01b81523060048201529096506001600160a01b038216906370a0823190602401602060405180830381865afa158015610e0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2f9190613403565b9450610e3b88886124c7565b610e4587876124c7565b1015610e775760405162461bcd60e51b81526020600482015260016024820152604b60f81b604482015260640161087f565b5050610e8584848888612613565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a350506001601355505050505050505050565b60008054610ef99061348a565b80601f0160208091040260200160405190810160405280929190818152602001828054610f259061348a565b8015610f725780601f10610f4757610100808354040283529160200191610f72565b820191906000526020600020905b815481529060010190602001808311610f5557829003601f168201915b505050505081565b3360008181526003602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610fd59086815260200190565b60405180910390a35060015b92915050565b606060008367ffffffffffffffff811115611004576110046134bf565b60405190808252806020026020018201604052801561102d578160200160208202803683370190505b5060075490915060009061104390600190613432565b905060006110518587613449565b61105b9083613432565b90506000805b838310156111d35761107387846134d5565b915060006007848154811061108a5761108a6134ed565b906000526020600020906003020160000154600784815481106110af576110af6134ed565b9060005260206000209060030201600001546110cb9190613432565b9050600081600786815481106110e3576110e36134ed565b90600052602060002090600302016001015460078681548110611108576111086134ed565b9060005260206000209060030201600101546111249190613432565b61112e9190613468565b905060008260078781548110611146576111466134ed565b9060005260206000209060030201600201546007878154811061116b5761116b6134ed565b9060005260206000209060030201600201546111879190613432565b6111919190613468565b905061119f8c8e84846127a7565b8885815181106111b1576111b16134ed565b60209081029190910101525050506001016111cc87846134d5565b9250611061565b509293505050505b949350505050565b600b54600c544260008080611201600854600954600a549192909190565b92509250925083811461124a57600061121a8286613432565b90506112268185613449565b61123090886134d5565b965061123c8184613449565b61124690876134d5565b9550505b505050909192565b6001600160a01b03831660008181526003602090815260408083203380855292528220549192909190821480159061128c57506000198114155b1561130257600061129d8583613432565b6001600160a01b038881166000818152600360209081526040808320948916808452948252918290208590559051848152939450919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505b61130d868686612a9c565b6001925050505b9392505050565b6007818154811061132b57600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b6000806113596119c0565b90506000806113666111e3565b50845191935091504214156113cf576007805461138590600290613432565b81548110611395576113956134ed565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505092505b82516000906113de9042613432565b90506000818560200151856113f39190613432565b6113fd9190613468565b90506000828660400151856114129190613432565b61141c9190613468565b905061142a888a84846127a7565b9998505050505050505050565b60606111db8484846001610fe7565b600060135460011461145757600080fd5b60026013556008546009546040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156114c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ed9190613403565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015611557573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157b9190613403565b905060006115898584613432565b905060006115978584613432565b600254909150806115d5576103e86115b76115b28486613449565b612b5c565b6115c19190613432565b97506115d060006103e8612bcc565b61160a565b611607876115e38386613449565b6115ed9190613468565b876115f88486613449565b6116029190613468565b612c5f565b97505b600088116116405760405162461bcd60e51b8152602060048201526003602482015262494c4d60e81b604482015260640161087f565b61164a8989612bcc565b61165685858989612613565b604080518481526020810184905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a250506001601355509395945050505050565b6000806013546001146116b557600080fd5b60026013556008546009546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000906000906001600160a01b038416906370a0823190602401602060405180830381865afa15801561174b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176f9190613403565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a0823190602401602060405180830381865afa1580156117b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117dd9190613403565b3060009081526004602052604090205460025491925090806117ff8584613449565b6118099190613468565b9950806118168484613449565b6118209190613468565b985060008a1180156118325750600089115b6118645760405162461bcd60e51b815260206004820152600360248201526224a62160e91b604482015260640161087f565b61186e3083612c75565b611879868c8c612245565b611884858c8b612245565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa1580156118c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ec9190613403565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa158015611933573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119579190613403565b925061196584848a8a612613565b604080518b8152602081018b90526001600160a01b038d169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a350505050505050506001601381905550915091565b6119e460405180606001604052806000815260200160008152602001600081525090565b600780546119f490600190613432565b81548110611a0457611a046134ed565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905090565b60018054610ef99061348a565b600080611a5d8585856001610fe7565b90506000805b8251811015611aa557828181518110611a7e57611a7e6134ed565b602002602001015182611a9191906134d5565b915080611a9d81613503565b915050611a63565b50611ab08482613468565b9695505050505050565b6000611ac7338484612a9c565b50600192915050565b601354600114611adf57600080fd5b60026013556008546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000917f000000000000000000000000000000000000000000000000000000000000000091611bac9184918691906001600160a01b038416906370a08231906024015b602060405180830381865afa158015611b79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9d9190613403565b611ba79190613432565b612245565b6009546040516370a0823160e01b8152306004820152611be49183918691906001600160a01b038416906370a0823190602401611b5c565b5050600160135550565b600080611bfa33612d00565b50503360009081526011602090815260408083205460129092529091205481151580611c265750600081115b15611d11573360008181526011602090815260408083208390556012909152808220919091555163299e7ae760e11b8152600481019190915260248101839052604481018290526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063533cf5ce90606401600060405180830381600087803b158015611cbb57600080fd5b505af1158015611ccf573d6000803e3d6000fd5b505060408051858152602081018590523393508392507f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e94645910160405180910390a35b9091565b42841015611d555760405162461bcd60e51b815260206004820152600d60248201526c14185a5c8e8811561412549151609a1b604482015260640161087f565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051611d85919061351e565b60408051918290038220828201825260018352603160f81b6020938401528151928301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f19818403018152918152815160209283012060058190556001600160a01b038a166000908152600690935290822080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b919087611e5083613503565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e00160405160208183030381529060405280519060200120604051602001611ec992919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015611f34573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590611f6a5750886001600160a01b0316816001600160a01b0316145b611fb65760405162461bcd60e51b815260206004820152601760248201527f506169723a20494e56414c49445f5349474e4154555245000000000000000000604482015260640161087f565b6001600160a01b038981166000818152600360209081526040808320948d16808452948252918290208b905590518a81527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050505050505050565b600854600954604051632895a2f560e11b81527f0000000000000000000000000000000000000000000000000000000000000000151560048201526000929190612710907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063512b45ea90602401602060405180830381865afa1580156120b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d69190613403565b6120e09087613449565b6120ea9190613468565b6120f49086613432565b9450612102858584846127a7565b95945050505050565b60135460011461211a57600080fd5b60026013556040516370a0823160e01b815230600482015261223e907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612187573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ab9190613403565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561220f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122339190613403565b600854600954612613565b6001601355565b6000836001600160a01b03163b1161225c57600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916122b891906135ba565b6000604051808303816000865af19150503d80600081146122f5576040519150601f19603f3d011682016040523d82523d6000602084013e6122fa565b606091505b50915091508180156123245750805115806123245750808060200190518101906123249190613395565b61232d57600080fd5b5050505050565b61237f7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000083612245565b60025460009061239783670de0b6b3a7640000613449565b6123a19190613468565b905080156123c15780600d60008282546123bb91906134d5565b90915550505b604080518381526000602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b61244c7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000083612245565b60025460009061246483670de0b6b3a7640000613449565b61246e9190613468565b9050801561248e5780600e600082825461248891906134d5565b90915550505b60408051600081526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291016123f5565b60007f0000000000000000000000000000000000000000000000000000000000000000156126025760007f000000000000000000000000000000000000000000000000000000000000000061252485670de0b6b3a7640000613449565b61252e9190613468565b905060007f000000000000000000000000000000000000000000000000000000000000000061256585670de0b6b3a7640000613449565b61256f9190613468565b90506000670de0b6b3a76400006125868385613449565b6125909190613468565b90506000670de0b6b3a76400006125a78480613449565b6125b19190613468565b670de0b6b3a76400006125c48680613449565b6125ce9190613468565b6125d891906134d5565b9050670de0b6b3a76400006125ed8284613449565b6125f79190613468565b945050505050610fe1565b61260c8284613449565b9050610fe1565b600a5442906000906126259083613432565b905060008111801561263657508315155b801561264157508215155b15612688576126508185613449565b600b600082825461266191906134d5565b9091555061267190508184613449565b600c600082825461268291906134d5565b90915550505b60006126926119c0565b80519091506126a19084613432565b91506107088211156127565760408051606081018252848152600b5460208201908152600c549282019283526007805460018101825560009190915291517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688600390930292830155517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68982015590517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a909101555b60088790556009869055600a83905560408051888152602081018890527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a150505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000015612a2a5760006127db84846124c7565b90507f000000000000000000000000000000000000000000000000000000000000000061281085670de0b6b3a7640000613449565b61281a9190613468565b93507f000000000000000000000000000000000000000000000000000000000000000061284f84670de0b6b3a7640000613449565b6128599190613468565b92506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b03161461289e5784866128a1565b85855b915091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b031614612920577f000000000000000000000000000000000000000000000000000000000000000061291189670de0b6b3a7640000613449565b61291b9190613468565b61295d565b7f000000000000000000000000000000000000000000000000000000000000000061295389670de0b6b3a7640000613449565b61295d9190613468565b9750600061297561296e848b6134d5565b8584612e60565b61297f9083613432565b9050670de0b6b3a76400007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316896001600160a01b0316146129e9577f0000000000000000000000000000000000000000000000000000000000000000612a0b565b7f00000000000000000000000000000000000000000000000000000000000000005b612a159083613449565b612a1f9190613468565b9450505050506111db565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b031614612a6d578385612a70565b84845b9092509050612a7f87836134d5565b612a898289613449565b612a939190613468565b925050506111db565b612aa583612d00565b612aae82612d00565b6001600160a01b03831660009081526004602052604081208054839290612ad6908490613432565b90915550506001600160a01b03821660009081526004602052604081208054839290612b039084906134d5565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612b4f91815260200190565b60405180910390a3505050565b60006003821115612bbd5750806000612b76600283613468565b612b819060016134d5565b90505b81811015612bb757905080600281612b9c8186613468565b612ba691906134d5565b612bb09190613468565b9050612b84565b50919050565b8115612bc7575060015b919050565b612bd582612d00565b8060026000828254612be791906134d5565b90915550506001600160a01b03821660009081526004602052604081208054839290612c149084906134d5565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b6000818310612c6e5781611314565b5090919050565b612c7e82612d00565b8060026000828254612c909190613432565b90915550506001600160a01b03821660009081526004602052604081208054839290612cbd908490613432565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001612c53565b6001600160a01b0381166000908152600460205260409020548015612e2e576001600160a01b0382166000908152600f60209081526040808320805460108085529285208054600d54600e54948190559490955282905593612d628584613432565b90506000612d708584613432565b90508115612dcb576000670de0b6b3a7640000612d8d848a613449565b612d979190613468565b6001600160a01b038a16600090815260116020526040812080549293508392909190612dc49084906134d5565b9091555050505b8015612e24576000670de0b6b3a7640000612de6838a613449565b612df09190613468565b6001600160a01b038a16600090815260126020526040812080549293508392909190612e1d9084906134d5565b9091555050505b5050505050505050565b600d546001600160a01b0383166000908152600f6020908152604080832093909355600e546010909152919020555050565b6000805b60ff811015612f6657826000612e7a8783612f6f565b905085811015612eca576000612e90888761300c565b612e9a8389613432565b612eac90670de0b6b3a7640000613449565b612eb69190613468565b9050612ec281876134d5565b955050612f0c565b6000612ed6888761300c565b612ee08884613432565b612ef290670de0b6b3a7640000613449565b612efc9190613468565b9050612f088187613432565b9550505b81851115612f35576001612f208387613432565b11612f3057849350505050611314565b612f51565b6001612f418684613432565b11612f5157849350505050611314565b50508080612f5e90613503565b915050612e64565b50909392505050565b6000670de0b6b3a764000082818581612f888280613449565b612f929190613468565b612f9c9190613449565b612fa69190613468565b612fb09190613449565b612fba9190613468565b670de0b6b3a7640000808481612fd08280613449565b612fda9190613468565b612fe49190613449565b612fee9190613468565b612ff89086613449565b6130029190613468565b61131491906134d5565b6000670de0b6b3a764000083816130238280613449565b61302d9190613468565b6130379190613449565b6130419190613468565b670de0b6b3a7640000806130558580613449565b61305f9190613468565b61306a866003613449565b612ff89190613449565b80356001600160a01b0381168114612bc757600080fd5b6000806000806000608086880312156130a357600080fd5b85359450602086013593506130ba60408701613074565b9250606086013567ffffffffffffffff808211156130d757600080fd5b818801915088601f8301126130eb57600080fd5b8135818111156130fa57600080fd5b89602082850101111561310c57600080fd5b9699959850939650602001949392505050565b60005b8381101561313a578181015183820152602001613122565b83811115613149576000848401525b50505050565b602081526000825180602084015261316e81604085016020870161311f565b601f01601f19169190910160400192915050565b6000806040838503121561319557600080fd5b61319e83613074565b946020939093013593505050565b600080600080608085870312156131c257600080fd5b6131cb85613074565b966020860135965060408601359560600135945092505050565b6020808252825182820181905260009190848201906040850190845b8181101561321d57835183529284019291840191600101613201565b50909695505050505050565b60006020828403121561323b57600080fd5b61131482613074565b60008060006060848603121561325957600080fd5b61326284613074565b925061327060208501613074565b9150604084013590509250925092565b60006020828403121561329257600080fd5b5035919050565b6000806000606084860312156132ae57600080fd5b6132b784613074565b95602085013595506040909401359392505050565b600080600080600080600060e0888a0312156132e757600080fd5b6132f088613074565b96506132fe60208901613074565b95506040880135945060608801359350608088013560ff8116811461332257600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561335257600080fd5b61335b83613074565b915061336960208401613074565b90509250929050565b6000806040838503121561338557600080fd5b8235915061336960208401613074565b6000602082840312156133a757600080fd5b8151801515811461131457600080fd5b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b60006020828403121561341557600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000828210156134445761344461341c565b500390565b60008160001904831182151516156134635761346361341c565b500290565b60008261348557634e487b7160e01b600052601260045260246000fd5b500490565b600181811c9082168061349e57607f821691505b60208210811415612bb757634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600082198211156134e8576134e861341c565b500190565b634e487b7160e01b600052603260045260246000fd5b60006000198214156135175761351761341c565b5060010190565b600080835481600182811c91508083168061353a57607f831692505b602080841082141561355a57634e487b7160e01b86526022600452602486fd5b81801561356e576001811461357f576135ac565b60ff198616895284890196506135ac565b60008a81526020902060005b868110156135a45781548b82015290850190830161358b565b505084890196505b509498975050505050505050565b600082516135cc81846020870161311f565b919091019291505056fea264697066735822122012bbc26e6d059c64971894076e1c061b5af33828e3ac3045418303c8201d1fe764736f6c634300080b0033", + "linkReferences": {}, + "deployedLinkReferences": {} + } \ No newline at end of file diff --git a/external/abi/velodrome/VelodromeRouter.json b/external/abi/velodrome/VelodromeRouter.json new file mode 100644 index 000000000..54f1358b2 --- /dev/null +++ b/external/abi/velodrome/VelodromeRouter.json @@ -0,0 +1,8 @@ +{ + "contractName": "VelodromeRouter", + "abi": [{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_weth","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"UNSAFE_swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"stable","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"name":"getReserves","outputs":[{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"isPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"name":"pairFor","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"}],"name":"quoteAddLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"name":"quoteRemoveLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"sortTokens","outputs":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address","name":"tokenFrom","type":"address"},{"internalType":"address","name":"tokenTo","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSimple","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}], + "bytecode": "0x60e06040523480156200001157600080fd5b5060405162003a0638038062003a068339810160408190526200003491620000d8565b6001600160a01b038216608081905260408051631355724960e31b81529051639aab9248916004808201926020929091908290030181865afa1580156200007f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000a5919062000110565b60c0526001600160a01b031660a052506200012a565b80516001600160a01b0381168114620000d357600080fd5b919050565b60008060408385031215620000ec57600080fd5b620000f783620000bb565b91506200010760208401620000bb565b90509250929050565b6000602082840312156200012357600080fd5b5051919050565b60805160a05160c051613812620001f46000396000610f0b01526000818161013e0152818161020b0152818161091901528181610b5801528181610dbb01528181611483015281816115960152818161163601528181611e0e01528181611e4401528181611e7901528181611f230152818161205e01526120ae01526000818161042d01528181610c5001528181610ed00152818161118a0152818161129e015281816119bb01528181611b2f0152818161215d0152818161274701526127e801526138126000f3fe60806040526004361061012e5760003560e01c80635e60dab5116100ab578063a32b1fcd1161006f578063a32b1fcd146103e8578063b7e0d4c014610408578063c45a01551461041b578063d7b0e0a51461044f578063e5e31b131461046f578063f41766d81461049f57600080fd5b80635e60dab51461035557806367ffb66a146103755780637301e3c8146103885780639881fcb4146103a857806398a0fb3c146103c857600080fd5b8063448725b4116100f2578063448725b4146102655780634c1ee03e14610285578063544caa56146102a55780635a47ddc3146102e55780635e1e63251461032057600080fd5b80630dede6c41461017257806313dcfc59146101ac57806318a13086146101d95780633fc8cef3146101f95780634386e63c1461024557600080fd5b3661016d57336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461016b5761016b612bcf565b005b600080fd5b34801561017e57600080fd5b5061019261018d366004612c16565b6104bf565b604080519283526020830191909152015b60405180910390f35b3480156101b857600080fd5b506101cc6101c7366004612c9b565b6106d9565b6040516101a39190612d16565b3480156101e557600080fd5b506101cc6101f4366004612d9f565b6108ec565b34801561020557600080fd5b5061022d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016101a3565b34801561025157600080fd5b50610192610260366004612e12565b610c49565b34801561027157600080fd5b50610192610280366004612e74565b610db0565b34801561029157600080fd5b5061022d6102a0366004612f1e565b610e89565b3480156102b157600080fd5b506102c56102c0366004612f69565b610f91565b604080516001600160a01b039384168152929091166020830152016101a3565b3480156102f157600080fd5b50610305610300366004612fa2565b611072565b604080519384526020840192909252908201526060016101a3565b34801561032c57600080fd5b5061034061033b366004613031565b611152565b604080519283529015156020830152016101a3565b34801561036157600080fd5b50610192610370366004612f1e565b6113a6565b6101cc610383366004613068565b61145e565b34801561039457600080fd5b506101cc6103a336600461313a565b6117cf565b3480156103b457600080fd5b506101cc6103c336600461327c565b6118a5565b3480156103d457600080fd5b506103056103e3366004613322565b611b27565b3480156103f457600080fd5b5061019261040336600461337d565b611d27565b610305610416366004613439565b611de2565b34801561042757600080fd5b5061022d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561045b57600080fd5b5061019261046a366004613439565b612034565b34801561047b57600080fd5b5061048f61048a366004613494565b61213b565b60405190151581526020016101a3565b3480156104ab57600080fd5b506101cc6104ba366004612d9f565b6121d0565b60008082428110156104ec5760405162461bcd60e51b81526004016104e3906134b1565b60405180910390fd5b60006104f98c8c8c610e89565b6040516323b872dd60e01b81523360048201526001600160a01b03821660248201819052604482018c90529192506323b872dd906064016020604051808303816000875af115801561054f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057391906134da565b61057c57600080fd5b60405163226bf2d160e21b81526001600160a01b03878116600483015260009182918416906389afcb449060240160408051808303816000875af11580156105c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ec91906134f7565b9150915060006105fc8f8f610f91565b509050806001600160a01b03168f6001600160a01b03161461061f578183610622565b82825b90975095508a8710156106775760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e5400000060448201526064016104e3565b898610156106c75760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e5400000060448201526064016104e3565b50505050509850989650505050505050565b606081428110156106fc5760405162461bcd60e51b81526004016104e3906134b1565b604080516001808252818301909252600091816020015b604080516060810182526000808252602080830182905292820152825260001990920191018161071357905050905087816000815181106107565761075661351b565b6020026020010151600001906001600160a01b031690816001600160a01b031681525050868160008151811061078e5761078e61351b565b6020026020010151602001906001600160a01b031690816001600160a01b03168152505085816000815181106107c6576107c661351b565b60209081029190910101519015156040909101526107e48a826118a5565b92508883600185516107f69190613547565b815181106108065761080661351b565b6020026020010151101561082c5760405162461bcd60e51b81526004016104e39061355e565b6108d4816000815181106108425761084261351b565b602002602001015160000151336108b4846000815181106108655761086561351b565b602002602001015160000151856000815181106108845761088461351b565b602002602001015160200151866000815181106108a3576108a361351b565b602002602001015160400151610e89565b866000815181106108c7576108c761351b565b60200260200101516122f5565b6108df8382876123ed565b5050979650505050505050565b6060814281101561090f5760405162461bcd60e51b81526004016104e3906134b1565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168686610946600182613547565b8181106109555761095561351b565b905060600201602001602081019061096d9190613494565b6001600160a01b0316146109935760405162461bcd60e51b81526004016104e3906135a0565b6109ef888787808060200260200160405190810160405280939291908181526020016000905b828210156109e5576109d6606083028601368190038101906135ce565b815260200190600101906109b9565b50505050506118a5565b9150868260018451610a019190613547565b81518110610a1157610a1161351b565b60200260200101511015610a375760405162461bcd60e51b81526004016104e39061355e565b610af986866000818110610a4d57610a4d61351b565b610a639260206060909202019081019150613494565b33610ae689896000818110610a7a57610a7a61351b565b610a909260206060909202019081019150613494565b8a8a6000818110610aa357610aa361351b565b9050606002016020016020810190610abb9190613494565b8b8b6000818110610ace57610ace61351b565b90506060020160400160208101906102a091906135ea565b856000815181106108c7576108c761351b565b610b56828787808060200260200160405190810160405280939291908181526020016000905b82821015610b4b57610b3c606083028601368190038101906135ce565b81526020019060010190610b1f565b5050505050306123ed565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d8360018551610b949190613547565b81518110610ba457610ba461351b565b60200260200101516040518263ffffffff1660e01b8152600401610bca91815260200190565b6020604051808303816000875af1158015610be9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0d9190613607565b50610c3e848360018551610c219190613547565b81518110610c3157610c3161351b565b6020026020010151612642565b509695505050505050565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636801cc308888886040518463ffffffff1660e01b8152600401610c9e93929190613620565b602060405180830381865afa158015610cbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cdf9190613644565b90506001600160a01b038116610cfc576000809250925050610da7565b600080610d0a8989896113a6565b915091506000836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d729190613607565b905080610d7f8489613661565b610d899190613680565b955080610d968389613661565b610da09190613680565b9450505050505b94509492505050565b6000806000610de08e7f00000000000000000000000000000000000000000000000000000000000000008f610e89565b9050600087610def578c610df3565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90610e2e903390309086908f908e908e908e906004016136a2565b600060405180830381600087803b158015610e4857600080fd5b505af1158015610e5c573d6000803e3d6000fd5b50505050610e6f8f8f8f8f8f8f8f612034565b809450819550505050509b509b9950505050505050505050565b6000806000610e988686610f91565b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015286151560f81b604882015291935091507f000000000000000000000000000000000000000000000000000000000000000090604901604051602081830303815290604052805190602001207f0000000000000000000000000000000000000000000000000000000000000000604051602001610f6f939291906001600160f81b0319815260609390931b6bffffffffffffffffffffffff191660018401526015830191909152603582015260550190565b60408051601f1981840301815291905280516020909101209695505050505050565b600080826001600160a01b0316846001600160a01b03161415610ff65760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a204944454e544943414c5f414444524553534553000000000060448201526064016104e3565b826001600160a01b0316846001600160a01b031610611016578284611019565b83835b90925090506001600160a01b03821661106b5760405162461bcd60e51b8152602060048201526014602482015273526f757465723a205a45524f5f4144445245535360601b60448201526064016104e3565b9250929050565b600080600083428110156110985760405162461bcd60e51b81526004016104e3906134b1565b6110a78d8d8d8d8d8d8d612710565b909450925060006110b98e8e8e610e89565b90506110c78e3383886122f5565b6110d38d3383876122f5565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af115801561111b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113f9190613607565b9250505099509950999650505050505050565b600080600061116385856001610e89565b60405163e5e31b1360e01b81526001600160a01b03828116600483015291925060009182917f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa1580156111d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f791906134da565b15611270576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa158015611249573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126d9190613607565b91505b61127c87876000610e89565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529194507f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa1580156112e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130b91906134da565b15611384576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa15801561135d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113819190613607565b90505b80821161139357806000611397565b8160015b94509450505050935093915050565b60008060006113b58686610f91565b5090506000806113c6888888610e89565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611403573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142791906136e3565b5091509150826001600160a01b0316886001600160a01b03161461144c57808261144f565b81815b90999098509650505050505050565b606081428110156114815760405162461bcd60e51b81526004016104e3906134b1565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316868660008181106114be576114be61351b565b6114d49260206060909202019081019150613494565b6001600160a01b0316146114fa5760405162461bcd60e51b81526004016104e3906135a0565b61154c348787808060200260200160405190810160405280939291908181526020016000905b828210156109e55761153d606083028601368190038101906135ce565b81526020019060010190611520565b915086826001845161155e9190613547565b8151811061156e5761156e61351b565b602002602001015110156115945760405162461bcd60e51b81526004016104e39061355e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0836000815181106115d6576115d661351b565b60200260200101516040518263ffffffff1660e01b815260040160206040518083038185885af115801561160e573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906116339190613607565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6116cd888860008181106116795761167961351b565b61168f9260206060909202019081019150613494565b898960008181106116a2576116a261351b565b90506060020160200160208101906116ba9190613494565b8a8a6000818110610ace57610ace61351b565b846000815181106116e0576116e061351b565b60200260200101516040518363ffffffff1660e01b81526004016117199291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015611738573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175c91906134da565b61176857611768612bcf565b6117c5828787808060200260200160405190810160405280939291908181526020016000905b828210156117ba576117ab606083028601368190038101906135ce565b8152602001906001019061178e565b5050505050866123ed565b5095945050505050565b606081428110156117f25760405162461bcd60e51b81526004016104e3906134b1565b611848868660008181106118085761180861351b565b61181e9260206060909202019081019150613494565b3361183589896000818110610a7a57610a7a61351b565b8a6000815181106108c7576108c761351b565b61189a878787808060200260200160405190810160405280939291908181526020016000905b828210156117ba5761188b606083028601368190038101906135ce565b8152602001906001019061186e565b509495945050505050565b60606001825110156118c95760405162461bcd60e51b81526004016104e3906135a0565b81516118d6906001613711565b67ffffffffffffffff8111156118ee576118ee6130cf565b604051908082528060200260200182016040528015611917578160200160208202803683370190505b509050828160008151811061192e5761192e61351b565b60200260200101818152505060005b8251811015611b2057600061199984838151811061195d5761195d61351b565b60200260200101516000015185848151811061197b5761197b61351b565b6020026020010151602001518685815181106108a3576108a361351b565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529192507f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa158015611a04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2891906134da565b15611b0d57806001600160a01b031663f140a35a848481518110611a4e57611a4e61351b565b6020026020010151868581518110611a6857611a6861351b565b6020026020010151600001516040518363ffffffff1660e01b8152600401611aa39291909182526001600160a01b0316602082015260400190565b602060405180830381865afa158015611ac0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae49190613607565b83611af0846001613711565b81518110611b0057611b0061351b565b6020026020010181815250505b5080611b1881613729565b91505061193d565b5092915050565b6000806000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636801cc308a8a8a6040518463ffffffff1660e01b8152600401611b7d93929190613620565b602060405180830381865afa158015611b9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bbe9190613644565b9050600080806001600160a01b03841615611c4857836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c359190613607565b9050611c428c8c8c6113a6565b90935091505b82158015611c54575081155b15611c85578896508795506103e8611c74611c6f888a613661565b61298e565b611c7e9190613547565b9450611d18565b6000611c928a85856129fe565b9050888111611cda57899750955085611cd384611caf848b613661565b611cb99190613680565b84611cc4858b613661565b611cce9190613680565b612ac8565b9550611d16565b6000611ce78a85876129fe565b9850899750889050611d1285611cfd8584613661565b611d079190613680565b85611cc4868c613661565b9650505b505b50505050955095509592505050565b6000806000611d378f8f8f610e89565b9050600087611d46578c611d4a565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90611d85903390309086908f908e908e908e906004016136a2565b600060405180830381600087803b158015611d9f57600080fd5b505af1158015611db3573d6000803e3d6000fd5b5050505050611dc88f8f8f8f8f8f8f8f6104bf565b8093508194505050509c509c9a5050505050505050505050565b60008060008342811015611e085760405162461bcd60e51b81526004016104e3906134b1565b611e378b7f00000000000000000000000000000000000000000000000000000000000000008c8c348d8d612710565b90945092506000611e698c7f00000000000000000000000000000000000000000000000000000000000000008d610e89565b9050611e778c3383886122f5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0856040518263ffffffff1660e01b815260040160206040518083038185885af1158015611ed7573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611efc9190613607565b5060405163a9059cbb60e01b81526001600160a01b038281166004830152602482018690527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015611f6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9091906134da565b611f9c57611f9c612bcf565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af1158015611fe4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120089190613607565b92508334111561202557612025336120208634613547565b612642565b50509750975097945050505050565b60008082428110156120585760405162461bcd60e51b81526004016104e3906134b1565b6120888a7f00000000000000000000000000000000000000000000000000000000000000008b8b8b8b308b6104bf565b90935091506120988a8685612ae0565b604051632e1a7d4d60e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d906024016020604051808303816000875af11580156120ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121239190613607565b5061212e8583612642565b5097509795505050505050565b60405163e5e31b1360e01b81526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa1580156121a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ca91906134da565b92915050565b606081428110156121f35760405162461bcd60e51b81526004016104e3906134b1565b612245888787808060200260200160405190810160405280939291908181526020016000905b828210156109e557612236606083028601368190038101906135ce565b81526020019060010190612219565b91508682600184516122579190613547565b815181106122675761226761351b565b6020026020010151101561228d5760405162461bcd60e51b81526004016104e39061355e565b6122a386866000818110610a4d57610a4d61351b565b610c3e828787808060200260200160405190810160405280939291908181526020016000905b828210156117ba576122e6606083028601368190038101906135ce565b815260200190600101906122c9565b6000846001600160a01b03163b1161230c57600080fd5b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17905291516000928392908816916123709190613770565b6000604051808303816000865af19150503d80600081146123ad576040519150601f19603f3d011682016040523d82523d6000602084013e6123b2565b606091505b50915091508180156123dc5750805115806123dc5750808060200190518101906123dc91906134da565b6123e557600080fd5b505050505050565b60005b825181101561263c57600061243f8483815181106124105761241061351b565b60200260200101516000015185848151811061242e5761242e61351b565b602002602001015160200151610f91565b509050600085612450846001613711565b815181106124605761246061351b565b60200260200101519050600080836001600160a01b03168786815181106124895761248961351b565b6020026020010151600001516001600160a01b0316146124ab578260006124af565b6000835b915091506000600188516124c39190613547565b86106124cf5786612542565b612542886124de886001613711565b815181106124ee576124ee61351b565b602002602001015160000151898860016125089190613711565b815181106125185761251861351b565b6020026020010151602001518a8960016125329190613711565b815181106108a3576108a361351b565b90506125958887815181106125595761255961351b565b6020026020010151600001518988815181106125775761257761351b565b6020026020010151602001518a89815181106108a3576108a361351b565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f1916602001820160405280156125d2576020820181803683370190505b506040518563ffffffff1660e01b81526004016125f2949392919061378c565b600060405180830381600087803b15801561260c57600080fd5b505af1158015612620573d6000803e3d6000fd5b505050505050505050808061263490613729565b9150506123f0565b50505050565b604080516000808252602082019092526001600160a01b03841690839060405161266c9190613770565b60006040518083038185875af1925050503d80600081146126a9576040519150601f19603f3d011682016040523d82523d6000602084013e6126ae565b606091505b505090508061270b5760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b60648201526084016104e3565b505050565b6000808386101561272057600080fd5b8285101561272d57600080fd5b6040516306801cc360e41b81526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636801cc3090612780908d908d908d90600401613620565b602060405180830381865afa15801561279d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127c19190613644565b90506001600160a01b038116612867576040516320b7f73960e21b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906382dfdce490612821908d908d908d90600401613620565b6020604051808303816000875af1158015612840573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128649190613644565b90505b6000806128758c8c8c6113a6565b91509150816000148015612887575080155b156128975788945087935061297f565b60006128a48a84846129fe565b905088811161290857868110156128fd5760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e5400000060448201526064016104e3565b89955093508361297d565b60006129158a84866129fe565b90508a81111561292757612927612bcf565b888110156129775760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e5400000060448201526064016104e3565b95508894505b505b50505097509795505050505050565b600060038211156129ef57508060006129a8600283613680565b6129b3906001613711565b90505b818110156129e9579050806002816129ce8186613680565b6129d89190613711565b6129e29190613680565b90506129b6565b50919050565b81156129f9575060015b919050565b6000808411612a4f5760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a20494e53554646494349454e545f414d4f554e54000000000060448201526064016104e3565b600083118015612a5f5750600082115b612aab5760405162461bcd60e51b815260206004820152601e60248201527f526f757465723a20494e53554646494349454e545f4c4951554944495459000060448201526064016104e3565b82612ab68386613661565b612ac09190613680565b949350505050565b6000818310612ad75781612ad9565b825b9392505050565b6000836001600160a01b03163b11612af757600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691612b539190613770565b6000604051808303816000865af19150503d8060008114612b90576040519150601f19603f3d011682016040523d82523d6000602084013e612b95565b606091505b5091509150818015612bbf575080511580612bbf575080806020019051810190612bbf91906134da565b612bc857600080fd5b5050505050565b634e487b7160e01b600052600160045260246000fd5b6001600160a01b0381168114612bfa57600080fd5b50565b80356129f981612be5565b8015158114612bfa57600080fd5b600080600080600080600080610100898b031215612c3357600080fd5b8835612c3e81612be5565b97506020890135612c4e81612be5565b96506040890135612c5e81612c08565b9550606089013594506080890135935060a0890135925060c0890135612c8381612be5565b8092505060e089013590509295985092959890939650565b600080600080600080600060e0888a031215612cb657600080fd5b87359650602088013595506040880135612ccf81612be5565b94506060880135612cdf81612be5565b93506080880135612cef81612c08565b925060a0880135612cff81612be5565b8092505060c0880135905092959891949750929550565b6020808252825182820181905260009190848201906040850190845b81811015612d4e57835183529284019291840191600101612d32565b50909695505050505050565b60008083601f840112612d6c57600080fd5b50813567ffffffffffffffff811115612d8457600080fd5b60208301915083602060608302850101111561106b57600080fd5b60008060008060008060a08789031215612db857600080fd5b8635955060208701359450604087013567ffffffffffffffff811115612ddd57600080fd5b612de989828a01612d5a565b9095509350506060870135612dfd81612be5565b80925050608087013590509295509295509295565b60008060008060808587031215612e2857600080fd5b8435612e3381612be5565b93506020850135612e4381612be5565b92506040850135612e5381612c08565b9396929550929360600135925050565b803560ff811681146129f957600080fd5b60008060008060008060008060008060006101608c8e031215612e9657600080fd5b8b35612ea181612be5565b9a5060208c0135612eb181612c08565b995060408c0135985060608c0135975060808c0135965060a08c0135612ed681612be5565b955060c08c0135945060e08c0135612eed81612c08565b9350612efc6101008d01612e63565b92506101208c013591506101408c013590509295989b509295989b9093969950565b600080600060608486031215612f3357600080fd5b8335612f3e81612be5565b92506020840135612f4e81612be5565b91506040840135612f5e81612c08565b809150509250925092565b60008060408385031215612f7c57600080fd5b8235612f8781612be5565b91506020830135612f9781612be5565b809150509250929050565b60008060008060008060008060006101208a8c031215612fc157600080fd5b8935612fcc81612be5565b985060208a0135612fdc81612be5565b975060408a0135612fec81612c08565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a013561301881612be5565b809250506101008a013590509295985092959850929598565b60008060006060848603121561304657600080fd5b83359250602084013561305881612be5565b91506040840135612f5e81612be5565b60008060008060006080868803121561308057600080fd5b85359450602086013567ffffffffffffffff81111561309e57600080fd5b6130aa88828901612d5a565b90955093505060408601356130be81612be5565b949793965091946060013592915050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561310e5761310e6130cf565b604052919050565b600067ffffffffffffffff821115613130576131306130cf565b5060051b60200190565b60008060008060006080868803121561315257600080fd5b853567ffffffffffffffff8082111561316a57600080fd5b818801915088601f83011261317e57600080fd5b8135602061319361318e83613116565b6130e5565b82815260059290921b8401810191818101908c8411156131b257600080fd5b948201945b838610156131d0578535825294820194908201906131b7565b995050890135925050808211156131e657600080fd5b506131f388828901612d5a565b90955093506130be905060408701612bfd565b60006060828403121561321857600080fd5b6040516060810181811067ffffffffffffffff8211171561323b5761323b6130cf565b604052905080823561324c81612be5565b8152602083013561325c81612be5565b6020820152604083013561326f81612c08565b6040919091015292915050565b6000806040838503121561328f57600080fd5b8235915060208084013567ffffffffffffffff8111156132ae57600080fd5b8401601f810186136132bf57600080fd5b80356132cd61318e82613116565b818152606091820283018401918482019190898411156132ec57600080fd5b938501935b83851015613312576133038a86613206565b835293840193918501916132f1565b5080955050505050509250929050565b600080600080600060a0868803121561333a57600080fd5b853561334581612be5565b9450602086013561335581612be5565b9350604086013561336581612c08565b94979396509394606081013594506080013592915050565b6000806000806000806000806000806000806101808d8f0312156133a057600080fd5b8c356133ab81612be5565b9b5060208d01356133bb81612be5565b9a5060408d01356133cb81612c08565b995060608d0135985060808d0135975060a08d0135965060c08d01356133f081612be5565b955060e08d013594506101008d013561340881612c08565b93506134176101208e01612e63565b92506101408d013591506101608d013590509295989b509295989b509295989b565b600080600080600080600060e0888a03121561345457600080fd5b873561345f81612be5565b9650602088013561346f81612c08565b955060408801359450606088013593506080880135925060a0880135612cff81612be5565b6000602082840312156134a657600080fd5b8135612ad981612be5565b6020808252600f908201526e149bdd5d195c8e8811561412549151608a1b604082015260600190565b6000602082840312156134ec57600080fd5b8151612ad981612c08565b6000806040838503121561350a57600080fd5b505080516020909101519092909150565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008282101561355957613559613531565b500390565b60208082526022908201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f55604082015261139560f21b606082015260800190565b6020808252601490820152730a4deeae8cae47440929cac82989288bea082a8960631b604082015260600190565b6000606082840312156135e057600080fd5b612ad98383613206565b6000602082840312156135fc57600080fd5b8135612ad981612c08565b60006020828403121561361957600080fd5b5051919050565b6001600160a01b039384168152919092166020820152901515604082015260600190565b60006020828403121561365657600080fd5b8151612ad981612be5565b600081600019048311821515161561367b5761367b613531565b500290565b60008261369d57634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b0397881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b6000806000606084860312156136f857600080fd5b8351925060208401519150604084015190509250925092565b6000821982111561372457613724613531565b500190565b600060001982141561373d5761373d613531565b5060010190565b60005b8381101561375f578181015183820152602001613747565b8381111561263c5750506000910152565b60008251613782818460208701613744565b9190910192915050565b84815283602082015260018060a01b038316604082015260806060820152600082518060808401526137c58160a0850160208701613744565b601f01601f19169190910160a0019594505050505056fea2646970667358221220755b85be4f0fc0117fdda889034ec422f5f182e9df9d0ba336603f0c10b74aeb64736f6c634300080b0033", + "deployedBytecode": "0x60806040526004361061012e5760003560e01c80635e60dab5116100ab578063a32b1fcd1161006f578063a32b1fcd146103e8578063b7e0d4c014610408578063c45a01551461041b578063d7b0e0a51461044f578063e5e31b131461046f578063f41766d81461049f57600080fd5b80635e60dab51461035557806367ffb66a146103755780637301e3c8146103885780639881fcb4146103a857806398a0fb3c146103c857600080fd5b8063448725b4116100f2578063448725b4146102655780634c1ee03e14610285578063544caa56146102a55780635a47ddc3146102e55780635e1e63251461032057600080fd5b80630dede6c41461017257806313dcfc59146101ac57806318a13086146101d95780633fc8cef3146101f95780634386e63c1461024557600080fd5b3661016d57336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461016b5761016b612bcf565b005b600080fd5b34801561017e57600080fd5b5061019261018d366004612c16565b6104bf565b604080519283526020830191909152015b60405180910390f35b3480156101b857600080fd5b506101cc6101c7366004612c9b565b6106d9565b6040516101a39190612d16565b3480156101e557600080fd5b506101cc6101f4366004612d9f565b6108ec565b34801561020557600080fd5b5061022d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016101a3565b34801561025157600080fd5b50610192610260366004612e12565b610c49565b34801561027157600080fd5b50610192610280366004612e74565b610db0565b34801561029157600080fd5b5061022d6102a0366004612f1e565b610e89565b3480156102b157600080fd5b506102c56102c0366004612f69565b610f91565b604080516001600160a01b039384168152929091166020830152016101a3565b3480156102f157600080fd5b50610305610300366004612fa2565b611072565b604080519384526020840192909252908201526060016101a3565b34801561032c57600080fd5b5061034061033b366004613031565b611152565b604080519283529015156020830152016101a3565b34801561036157600080fd5b50610192610370366004612f1e565b6113a6565b6101cc610383366004613068565b61145e565b34801561039457600080fd5b506101cc6103a336600461313a565b6117cf565b3480156103b457600080fd5b506101cc6103c336600461327c565b6118a5565b3480156103d457600080fd5b506103056103e3366004613322565b611b27565b3480156103f457600080fd5b5061019261040336600461337d565b611d27565b610305610416366004613439565b611de2565b34801561042757600080fd5b5061022d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561045b57600080fd5b5061019261046a366004613439565b612034565b34801561047b57600080fd5b5061048f61048a366004613494565b61213b565b60405190151581526020016101a3565b3480156104ab57600080fd5b506101cc6104ba366004612d9f565b6121d0565b60008082428110156104ec5760405162461bcd60e51b81526004016104e3906134b1565b60405180910390fd5b60006104f98c8c8c610e89565b6040516323b872dd60e01b81523360048201526001600160a01b03821660248201819052604482018c90529192506323b872dd906064016020604051808303816000875af115801561054f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057391906134da565b61057c57600080fd5b60405163226bf2d160e21b81526001600160a01b03878116600483015260009182918416906389afcb449060240160408051808303816000875af11580156105c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ec91906134f7565b9150915060006105fc8f8f610f91565b509050806001600160a01b03168f6001600160a01b03161461061f578183610622565b82825b90975095508a8710156106775760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e5400000060448201526064016104e3565b898610156106c75760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e5400000060448201526064016104e3565b50505050509850989650505050505050565b606081428110156106fc5760405162461bcd60e51b81526004016104e3906134b1565b604080516001808252818301909252600091816020015b604080516060810182526000808252602080830182905292820152825260001990920191018161071357905050905087816000815181106107565761075661351b565b6020026020010151600001906001600160a01b031690816001600160a01b031681525050868160008151811061078e5761078e61351b565b6020026020010151602001906001600160a01b031690816001600160a01b03168152505085816000815181106107c6576107c661351b565b60209081029190910101519015156040909101526107e48a826118a5565b92508883600185516107f69190613547565b815181106108065761080661351b565b6020026020010151101561082c5760405162461bcd60e51b81526004016104e39061355e565b6108d4816000815181106108425761084261351b565b602002602001015160000151336108b4846000815181106108655761086561351b565b602002602001015160000151856000815181106108845761088461351b565b602002602001015160200151866000815181106108a3576108a361351b565b602002602001015160400151610e89565b866000815181106108c7576108c761351b565b60200260200101516122f5565b6108df8382876123ed565b5050979650505050505050565b6060814281101561090f5760405162461bcd60e51b81526004016104e3906134b1565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168686610946600182613547565b8181106109555761095561351b565b905060600201602001602081019061096d9190613494565b6001600160a01b0316146109935760405162461bcd60e51b81526004016104e3906135a0565b6109ef888787808060200260200160405190810160405280939291908181526020016000905b828210156109e5576109d6606083028601368190038101906135ce565b815260200190600101906109b9565b50505050506118a5565b9150868260018451610a019190613547565b81518110610a1157610a1161351b565b60200260200101511015610a375760405162461bcd60e51b81526004016104e39061355e565b610af986866000818110610a4d57610a4d61351b565b610a639260206060909202019081019150613494565b33610ae689896000818110610a7a57610a7a61351b565b610a909260206060909202019081019150613494565b8a8a6000818110610aa357610aa361351b565b9050606002016020016020810190610abb9190613494565b8b8b6000818110610ace57610ace61351b565b90506060020160400160208101906102a091906135ea565b856000815181106108c7576108c761351b565b610b56828787808060200260200160405190810160405280939291908181526020016000905b82821015610b4b57610b3c606083028601368190038101906135ce565b81526020019060010190610b1f565b5050505050306123ed565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d8360018551610b949190613547565b81518110610ba457610ba461351b565b60200260200101516040518263ffffffff1660e01b8152600401610bca91815260200190565b6020604051808303816000875af1158015610be9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0d9190613607565b50610c3e848360018551610c219190613547565b81518110610c3157610c3161351b565b6020026020010151612642565b509695505050505050565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636801cc308888886040518463ffffffff1660e01b8152600401610c9e93929190613620565b602060405180830381865afa158015610cbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cdf9190613644565b90506001600160a01b038116610cfc576000809250925050610da7565b600080610d0a8989896113a6565b915091506000836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d729190613607565b905080610d7f8489613661565b610d899190613680565b955080610d968389613661565b610da09190613680565b9450505050505b94509492505050565b6000806000610de08e7f00000000000000000000000000000000000000000000000000000000000000008f610e89565b9050600087610def578c610df3565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90610e2e903390309086908f908e908e908e906004016136a2565b600060405180830381600087803b158015610e4857600080fd5b505af1158015610e5c573d6000803e3d6000fd5b50505050610e6f8f8f8f8f8f8f8f612034565b809450819550505050509b509b9950505050505050505050565b6000806000610e988686610f91565b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015286151560f81b604882015291935091507f000000000000000000000000000000000000000000000000000000000000000090604901604051602081830303815290604052805190602001207f0000000000000000000000000000000000000000000000000000000000000000604051602001610f6f939291906001600160f81b0319815260609390931b6bffffffffffffffffffffffff191660018401526015830191909152603582015260550190565b60408051601f1981840301815291905280516020909101209695505050505050565b600080826001600160a01b0316846001600160a01b03161415610ff65760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a204944454e544943414c5f414444524553534553000000000060448201526064016104e3565b826001600160a01b0316846001600160a01b031610611016578284611019565b83835b90925090506001600160a01b03821661106b5760405162461bcd60e51b8152602060048201526014602482015273526f757465723a205a45524f5f4144445245535360601b60448201526064016104e3565b9250929050565b600080600083428110156110985760405162461bcd60e51b81526004016104e3906134b1565b6110a78d8d8d8d8d8d8d612710565b909450925060006110b98e8e8e610e89565b90506110c78e3383886122f5565b6110d38d3383876122f5565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af115801561111b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113f9190613607565b9250505099509950999650505050505050565b600080600061116385856001610e89565b60405163e5e31b1360e01b81526001600160a01b03828116600483015291925060009182917f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa1580156111d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f791906134da565b15611270576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa158015611249573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126d9190613607565b91505b61127c87876000610e89565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529194507f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa1580156112e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130b91906134da565b15611384576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa15801561135d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113819190613607565b90505b80821161139357806000611397565b8160015b94509450505050935093915050565b60008060006113b58686610f91565b5090506000806113c6888888610e89565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611403573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142791906136e3565b5091509150826001600160a01b0316886001600160a01b03161461144c57808261144f565b81815b90999098509650505050505050565b606081428110156114815760405162461bcd60e51b81526004016104e3906134b1565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316868660008181106114be576114be61351b565b6114d49260206060909202019081019150613494565b6001600160a01b0316146114fa5760405162461bcd60e51b81526004016104e3906135a0565b61154c348787808060200260200160405190810160405280939291908181526020016000905b828210156109e55761153d606083028601368190038101906135ce565b81526020019060010190611520565b915086826001845161155e9190613547565b8151811061156e5761156e61351b565b602002602001015110156115945760405162461bcd60e51b81526004016104e39061355e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0836000815181106115d6576115d661351b565b60200260200101516040518263ffffffff1660e01b815260040160206040518083038185885af115801561160e573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906116339190613607565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6116cd888860008181106116795761167961351b565b61168f9260206060909202019081019150613494565b898960008181106116a2576116a261351b565b90506060020160200160208101906116ba9190613494565b8a8a6000818110610ace57610ace61351b565b846000815181106116e0576116e061351b565b60200260200101516040518363ffffffff1660e01b81526004016117199291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015611738573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175c91906134da565b61176857611768612bcf565b6117c5828787808060200260200160405190810160405280939291908181526020016000905b828210156117ba576117ab606083028601368190038101906135ce565b8152602001906001019061178e565b5050505050866123ed565b5095945050505050565b606081428110156117f25760405162461bcd60e51b81526004016104e3906134b1565b611848868660008181106118085761180861351b565b61181e9260206060909202019081019150613494565b3361183589896000818110610a7a57610a7a61351b565b8a6000815181106108c7576108c761351b565b61189a878787808060200260200160405190810160405280939291908181526020016000905b828210156117ba5761188b606083028601368190038101906135ce565b8152602001906001019061186e565b509495945050505050565b60606001825110156118c95760405162461bcd60e51b81526004016104e3906135a0565b81516118d6906001613711565b67ffffffffffffffff8111156118ee576118ee6130cf565b604051908082528060200260200182016040528015611917578160200160208202803683370190505b509050828160008151811061192e5761192e61351b565b60200260200101818152505060005b8251811015611b2057600061199984838151811061195d5761195d61351b565b60200260200101516000015185848151811061197b5761197b61351b565b6020026020010151602001518685815181106108a3576108a361351b565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529192507f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa158015611a04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2891906134da565b15611b0d57806001600160a01b031663f140a35a848481518110611a4e57611a4e61351b565b6020026020010151868581518110611a6857611a6861351b565b6020026020010151600001516040518363ffffffff1660e01b8152600401611aa39291909182526001600160a01b0316602082015260400190565b602060405180830381865afa158015611ac0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae49190613607565b83611af0846001613711565b81518110611b0057611b0061351b565b6020026020010181815250505b5080611b1881613729565b91505061193d565b5092915050565b6000806000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636801cc308a8a8a6040518463ffffffff1660e01b8152600401611b7d93929190613620565b602060405180830381865afa158015611b9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bbe9190613644565b9050600080806001600160a01b03841615611c4857836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c359190613607565b9050611c428c8c8c6113a6565b90935091505b82158015611c54575081155b15611c85578896508795506103e8611c74611c6f888a613661565b61298e565b611c7e9190613547565b9450611d18565b6000611c928a85856129fe565b9050888111611cda57899750955085611cd384611caf848b613661565b611cb99190613680565b84611cc4858b613661565b611cce9190613680565b612ac8565b9550611d16565b6000611ce78a85876129fe565b9850899750889050611d1285611cfd8584613661565b611d079190613680565b85611cc4868c613661565b9650505b505b50505050955095509592505050565b6000806000611d378f8f8f610e89565b9050600087611d46578c611d4a565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90611d85903390309086908f908e908e908e906004016136a2565b600060405180830381600087803b158015611d9f57600080fd5b505af1158015611db3573d6000803e3d6000fd5b5050505050611dc88f8f8f8f8f8f8f8f6104bf565b8093508194505050509c509c9a5050505050505050505050565b60008060008342811015611e085760405162461bcd60e51b81526004016104e3906134b1565b611e378b7f00000000000000000000000000000000000000000000000000000000000000008c8c348d8d612710565b90945092506000611e698c7f00000000000000000000000000000000000000000000000000000000000000008d610e89565b9050611e778c3383886122f5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0856040518263ffffffff1660e01b815260040160206040518083038185885af1158015611ed7573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611efc9190613607565b5060405163a9059cbb60e01b81526001600160a01b038281166004830152602482018690527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015611f6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9091906134da565b611f9c57611f9c612bcf565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af1158015611fe4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120089190613607565b92508334111561202557612025336120208634613547565b612642565b50509750975097945050505050565b60008082428110156120585760405162461bcd60e51b81526004016104e3906134b1565b6120888a7f00000000000000000000000000000000000000000000000000000000000000008b8b8b8b308b6104bf565b90935091506120988a8685612ae0565b604051632e1a7d4d60e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d906024016020604051808303816000875af11580156120ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121239190613607565b5061212e8583612642565b5097509795505050505050565b60405163e5e31b1360e01b81526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa1580156121a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ca91906134da565b92915050565b606081428110156121f35760405162461bcd60e51b81526004016104e3906134b1565b612245888787808060200260200160405190810160405280939291908181526020016000905b828210156109e557612236606083028601368190038101906135ce565b81526020019060010190612219565b91508682600184516122579190613547565b815181106122675761226761351b565b6020026020010151101561228d5760405162461bcd60e51b81526004016104e39061355e565b6122a386866000818110610a4d57610a4d61351b565b610c3e828787808060200260200160405190810160405280939291908181526020016000905b828210156117ba576122e6606083028601368190038101906135ce565b815260200190600101906122c9565b6000846001600160a01b03163b1161230c57600080fd5b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17905291516000928392908816916123709190613770565b6000604051808303816000865af19150503d80600081146123ad576040519150601f19603f3d011682016040523d82523d6000602084013e6123b2565b606091505b50915091508180156123dc5750805115806123dc5750808060200190518101906123dc91906134da565b6123e557600080fd5b505050505050565b60005b825181101561263c57600061243f8483815181106124105761241061351b565b60200260200101516000015185848151811061242e5761242e61351b565b602002602001015160200151610f91565b509050600085612450846001613711565b815181106124605761246061351b565b60200260200101519050600080836001600160a01b03168786815181106124895761248961351b565b6020026020010151600001516001600160a01b0316146124ab578260006124af565b6000835b915091506000600188516124c39190613547565b86106124cf5786612542565b612542886124de886001613711565b815181106124ee576124ee61351b565b602002602001015160000151898860016125089190613711565b815181106125185761251861351b565b6020026020010151602001518a8960016125329190613711565b815181106108a3576108a361351b565b90506125958887815181106125595761255961351b565b6020026020010151600001518988815181106125775761257761351b565b6020026020010151602001518a89815181106108a3576108a361351b565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f1916602001820160405280156125d2576020820181803683370190505b506040518563ffffffff1660e01b81526004016125f2949392919061378c565b600060405180830381600087803b15801561260c57600080fd5b505af1158015612620573d6000803e3d6000fd5b505050505050505050808061263490613729565b9150506123f0565b50505050565b604080516000808252602082019092526001600160a01b03841690839060405161266c9190613770565b60006040518083038185875af1925050503d80600081146126a9576040519150601f19603f3d011682016040523d82523d6000602084013e6126ae565b606091505b505090508061270b5760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b60648201526084016104e3565b505050565b6000808386101561272057600080fd5b8285101561272d57600080fd5b6040516306801cc360e41b81526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636801cc3090612780908d908d908d90600401613620565b602060405180830381865afa15801561279d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127c19190613644565b90506001600160a01b038116612867576040516320b7f73960e21b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906382dfdce490612821908d908d908d90600401613620565b6020604051808303816000875af1158015612840573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128649190613644565b90505b6000806128758c8c8c6113a6565b91509150816000148015612887575080155b156128975788945087935061297f565b60006128a48a84846129fe565b905088811161290857868110156128fd5760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e5400000060448201526064016104e3565b89955093508361297d565b60006129158a84866129fe565b90508a81111561292757612927612bcf565b888110156129775760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e5400000060448201526064016104e3565b95508894505b505b50505097509795505050505050565b600060038211156129ef57508060006129a8600283613680565b6129b3906001613711565b90505b818110156129e9579050806002816129ce8186613680565b6129d89190613711565b6129e29190613680565b90506129b6565b50919050565b81156129f9575060015b919050565b6000808411612a4f5760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a20494e53554646494349454e545f414d4f554e54000000000060448201526064016104e3565b600083118015612a5f5750600082115b612aab5760405162461bcd60e51b815260206004820152601e60248201527f526f757465723a20494e53554646494349454e545f4c4951554944495459000060448201526064016104e3565b82612ab68386613661565b612ac09190613680565b949350505050565b6000818310612ad75781612ad9565b825b9392505050565b6000836001600160a01b03163b11612af757600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691612b539190613770565b6000604051808303816000865af19150503d8060008114612b90576040519150601f19603f3d011682016040523d82523d6000602084013e612b95565b606091505b5091509150818015612bbf575080511580612bbf575080806020019051810190612bbf91906134da565b612bc857600080fd5b5050505050565b634e487b7160e01b600052600160045260246000fd5b6001600160a01b0381168114612bfa57600080fd5b50565b80356129f981612be5565b8015158114612bfa57600080fd5b600080600080600080600080610100898b031215612c3357600080fd5b8835612c3e81612be5565b97506020890135612c4e81612be5565b96506040890135612c5e81612c08565b9550606089013594506080890135935060a0890135925060c0890135612c8381612be5565b8092505060e089013590509295985092959890939650565b600080600080600080600060e0888a031215612cb657600080fd5b87359650602088013595506040880135612ccf81612be5565b94506060880135612cdf81612be5565b93506080880135612cef81612c08565b925060a0880135612cff81612be5565b8092505060c0880135905092959891949750929550565b6020808252825182820181905260009190848201906040850190845b81811015612d4e57835183529284019291840191600101612d32565b50909695505050505050565b60008083601f840112612d6c57600080fd5b50813567ffffffffffffffff811115612d8457600080fd5b60208301915083602060608302850101111561106b57600080fd5b60008060008060008060a08789031215612db857600080fd5b8635955060208701359450604087013567ffffffffffffffff811115612ddd57600080fd5b612de989828a01612d5a565b9095509350506060870135612dfd81612be5565b80925050608087013590509295509295509295565b60008060008060808587031215612e2857600080fd5b8435612e3381612be5565b93506020850135612e4381612be5565b92506040850135612e5381612c08565b9396929550929360600135925050565b803560ff811681146129f957600080fd5b60008060008060008060008060008060006101608c8e031215612e9657600080fd5b8b35612ea181612be5565b9a5060208c0135612eb181612c08565b995060408c0135985060608c0135975060808c0135965060a08c0135612ed681612be5565b955060c08c0135945060e08c0135612eed81612c08565b9350612efc6101008d01612e63565b92506101208c013591506101408c013590509295989b509295989b9093969950565b600080600060608486031215612f3357600080fd5b8335612f3e81612be5565b92506020840135612f4e81612be5565b91506040840135612f5e81612c08565b809150509250925092565b60008060408385031215612f7c57600080fd5b8235612f8781612be5565b91506020830135612f9781612be5565b809150509250929050565b60008060008060008060008060006101208a8c031215612fc157600080fd5b8935612fcc81612be5565b985060208a0135612fdc81612be5565b975060408a0135612fec81612c08565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a013561301881612be5565b809250506101008a013590509295985092959850929598565b60008060006060848603121561304657600080fd5b83359250602084013561305881612be5565b91506040840135612f5e81612be5565b60008060008060006080868803121561308057600080fd5b85359450602086013567ffffffffffffffff81111561309e57600080fd5b6130aa88828901612d5a565b90955093505060408601356130be81612be5565b949793965091946060013592915050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561310e5761310e6130cf565b604052919050565b600067ffffffffffffffff821115613130576131306130cf565b5060051b60200190565b60008060008060006080868803121561315257600080fd5b853567ffffffffffffffff8082111561316a57600080fd5b818801915088601f83011261317e57600080fd5b8135602061319361318e83613116565b6130e5565b82815260059290921b8401810191818101908c8411156131b257600080fd5b948201945b838610156131d0578535825294820194908201906131b7565b995050890135925050808211156131e657600080fd5b506131f388828901612d5a565b90955093506130be905060408701612bfd565b60006060828403121561321857600080fd5b6040516060810181811067ffffffffffffffff8211171561323b5761323b6130cf565b604052905080823561324c81612be5565b8152602083013561325c81612be5565b6020820152604083013561326f81612c08565b6040919091015292915050565b6000806040838503121561328f57600080fd5b8235915060208084013567ffffffffffffffff8111156132ae57600080fd5b8401601f810186136132bf57600080fd5b80356132cd61318e82613116565b818152606091820283018401918482019190898411156132ec57600080fd5b938501935b83851015613312576133038a86613206565b835293840193918501916132f1565b5080955050505050509250929050565b600080600080600060a0868803121561333a57600080fd5b853561334581612be5565b9450602086013561335581612be5565b9350604086013561336581612c08565b94979396509394606081013594506080013592915050565b6000806000806000806000806000806000806101808d8f0312156133a057600080fd5b8c356133ab81612be5565b9b5060208d01356133bb81612be5565b9a5060408d01356133cb81612c08565b995060608d0135985060808d0135975060a08d0135965060c08d01356133f081612be5565b955060e08d013594506101008d013561340881612c08565b93506134176101208e01612e63565b92506101408d013591506101608d013590509295989b509295989b509295989b565b600080600080600080600060e0888a03121561345457600080fd5b873561345f81612be5565b9650602088013561346f81612c08565b955060408801359450606088013593506080880135925060a0880135612cff81612be5565b6000602082840312156134a657600080fd5b8135612ad981612be5565b6020808252600f908201526e149bdd5d195c8e8811561412549151608a1b604082015260600190565b6000602082840312156134ec57600080fd5b8151612ad981612c08565b6000806040838503121561350a57600080fd5b505080516020909101519092909150565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008282101561355957613559613531565b500390565b60208082526022908201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f55604082015261139560f21b606082015260800190565b6020808252601490820152730a4deeae8cae47440929cac82989288bea082a8960631b604082015260600190565b6000606082840312156135e057600080fd5b612ad98383613206565b6000602082840312156135fc57600080fd5b8135612ad981612c08565b60006020828403121561361957600080fd5b5051919050565b6001600160a01b039384168152919092166020820152901515604082015260600190565b60006020828403121561365657600080fd5b8151612ad981612be5565b600081600019048311821515161561367b5761367b613531565b500290565b60008261369d57634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b0397881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b6000806000606084860312156136f857600080fd5b8351925060208401519150604084015190509250925092565b6000821982111561372457613724613531565b500190565b600060001982141561373d5761373d613531565b5060010190565b60005b8381101561375f578181015183820152602001613747565b8381111561263c5750506000910152565b60008251613782818460208701613744565b9190910192915050565b84815283602082015260018060a01b038316604082015260806060820152600082518060808401526137c58160a0850160208701613744565b601f01601f19169190910160a0019594505050505056fea2646970667358221220755b85be4f0fc0117fdda889034ec422f5f182e9df9d0ba336603f0c10b74aeb64736f6c634300080b0033", + "linkReferences": {}, + "deployedLinkReferences": {} + } \ No newline at end of file diff --git a/test/integration/velodromeExchangeTradeModule.spec.draft.ts b/test/integration/velodromeExchangeTradeModule.spec.draft.ts new file mode 100644 index 000000000..b2154b47c --- /dev/null +++ b/test/integration/velodromeExchangeTradeModule.spec.draft.ts @@ -0,0 +1,238 @@ +import "module-alias/register"; + +import { BigNumber } from "ethers"; +import { ethers, network } from "hardhat"; + +import { Address, Bytes } from "@utils/types"; +import { Account } from "@utils/test/types"; +import { + SetToken, + TradeModule, + ManagerIssuanceHookMock, + VelodromeExchangeAdapter, +} from "@utils/contracts"; +import { ZERO } from "@utils/constants"; +import DeployHelper from "@utils/deploys"; +import { ether, usdc } from "@utils/index"; +import { cacheBeforeEach, getAccounts, getSystemFixture, getWaffleExpect } from "@utils/test/index"; + +import { SystemFixture } from "@utils/fixtures"; +import { parseUnits } from "ethers/lib/utils"; +import { IVelodromeRouter } from "@typechain/IVelodromeRouter"; +import { IERC20 } from "@typechain/IERC20"; +import { IERC20__factory } from "@typechain/factories/IERC20__factory"; +import dependencies from "@utils/deploys/dependencies"; + +const expect = getWaffleExpect(); + +describe("Velodrome TradeModule Integration [@optimism]", () => { + const velodromeAdapterName = "Velodrome"; + + let owner: Account; + let manager: Account; + let deployer: DeployHelper; + + let velodromeExchangeAdapter: VelodromeExchangeAdapter; + + let setup: SystemFixture; + let velodromeRouter: IVelodromeRouter; + let tradeModule: TradeModule; + + before(async () => { + await network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: `https://opt-mainnet.g.alchemy.com/v2/${process.env.ALCHEMY_TOKEN}`, + blockNumber: 13454300, + }, + }, + ], + }); + + [owner, manager] = await getAccounts(); + + deployer = new DeployHelper(owner.wallet); + setup = getSystemFixture(owner.address); + await setup.initialize(); + + velodromeRouter = await ethers.getContractAt( + "IVelodromeRouter", + dependencies.VELODROME_ROUTER[10], + ); + + velodromeExchangeAdapter = await deployer.adapters.deployVelodromeExchangeAdapter( + velodromeRouter.address, + ); + + tradeModule = await deployer.modules.deployTradeModule(setup.controller.address); + await setup.controller.addModule(tradeModule.address); + + await setup.integrationRegistry.addIntegration( + tradeModule.address, + velodromeAdapterName, + velodromeExchangeAdapter.address, + ); + }); + + after(async () => { + await network.provider.request({ + method: "hardhat_reset", + params: [], + }); + }); + + describe("#trade", function () { + let sourceToken: IERC20; + let destinationToken: IERC20; + let setToken: SetToken; + let issueQuantity: BigNumber; + + context("when trading a Default component on Velodrome", async () => { + let mockPreIssuanceHook: ManagerIssuanceHookMock; + let sourceTokenQuantity: BigNumber; + let destinationTokenQuantity: BigNumber; + + let subjectDestinationToken: Address; + let subjectSourceToken: Address; + let subjectSourceQuantity: BigNumber; + let subjectAdapterName: string; + let subjectSetToken: Address; + let subjectMinDestinationQuantity: BigNumber; + let subjectData: Bytes; + let subjectCaller: Account; + + cacheBeforeEach(async () => { + const whale = "0xAD7b4C162707E0B2b5f6fdDbD3f8538A5fbA0d60"; + // prepare WETH and USDC + await network.provider.request({ + method: "hardhat_impersonateAccount", + params: [whale], + }); + + await owner.wallet.sendTransaction({ + from: owner.address, + to: whale, + value: parseUnits("1"), + }); + + sourceToken = IERC20__factory.connect( + "0x4200000000000000000000000000000000000006", // weth + await ethers.getSigner(whale), + ); + destinationToken = IERC20__factory.connect( + "0x7F5c764cBc14f9669B88837ca1490cCa17c31607", // usdc + await ethers.getSigner(whale), + ); + + // Create Set token + setToken = await setup.createSetToken( + [sourceToken.address], + [ether(1)], + [setup.issuanceModule.address, tradeModule.address], + manager.address, + ); + + await sourceToken.approve(velodromeRouter.address, ether(10)); + await destinationToken.approve(velodromeRouter.address, usdc(10000)); + + tradeModule = tradeModule.connect(manager.wallet); + await tradeModule.initialize(setToken.address); + + sourceTokenQuantity = ether(1); + [, destinationTokenQuantity] = await velodromeRouter.getAmountsOut(sourceTokenQuantity, [ + { + from: sourceToken.address, + to: destinationToken.address, + stable: false, + }, + ]); + + // Transfer from weth whale to manager + await sourceToken.transfer(manager.address, sourceTokenQuantity); + + // Approve tokens to Controller and call issue + sourceToken = sourceToken.connect(manager.wallet); + await sourceToken.approve(setup.issuanceModule.address, ethers.constants.MaxUint256); + + // Deploy mock issuance hook and initialize issuance module + setup.issuanceModule = setup.issuanceModule.connect(manager.wallet); + mockPreIssuanceHook = await deployer.mocks.deployManagerIssuanceHookMock(); + await setup.issuanceModule.initialize(setToken.address, mockPreIssuanceHook.address); + + issueQuantity = ether(1); + await setup.issuanceModule.issue(setToken.address, issueQuantity, owner.address); + }); + + beforeEach(async () => { + subjectSourceToken = sourceToken.address; + subjectDestinationToken = destinationToken.address; + subjectSourceQuantity = sourceTokenQuantity; + subjectSetToken = setToken.address; + subjectMinDestinationQuantity = destinationTokenQuantity.sub(usdc(1)); + subjectAdapterName = velodromeAdapterName; + + subjectData = await velodromeExchangeAdapter.generateDataParam( + [ + { + from: subjectSourceToken, + to: subjectDestinationToken, + stable: false, + }, + ], + ethers.constants.MaxUint256, + ); + + subjectCaller = manager; + }); + + async function subject(): Promise { + tradeModule = tradeModule.connect(subjectCaller.wallet); + return tradeModule.trade( + subjectSetToken, + subjectAdapterName, + subjectSourceToken, + subjectSourceQuantity, + subjectDestinationToken, + subjectMinDestinationQuantity, + subjectData, + ); + } + + it("should transfer the correct components to the SetToken", async () => { + const oldDestinationTokenBalance = await destinationToken.balanceOf(setToken.address); + const [, expectedReceiveQuantity] = await velodromeRouter.getAmountsOut( + subjectSourceQuantity, + [ + { + from: subjectSourceToken, + to: subjectDestinationToken, + stable: false, + }, + ], + ); + + await subject(); + + const expectedDestinationTokenBalance = oldDestinationTokenBalance.add( + expectedReceiveQuantity, + ); + const newDestinationTokenBalance = await destinationToken.balanceOf(setToken.address); + expect(expectedReceiveQuantity).to.be.gt(ZERO); + expect(newDestinationTokenBalance).to.eq(expectedDestinationTokenBalance); + }); + + it("should transfer the correct components from the SetToken", async () => { + const oldSourceTokenBalance = await sourceToken.balanceOf(setToken.address); + + await subject(); + + const totalSourceQuantity = issueQuantity.mul(sourceTokenQuantity).div(ether(1)); + const expectedSourceTokenBalance = oldSourceTokenBalance.sub(totalSourceQuantity); + const newSourceTokenBalance = await sourceToken.balanceOf(setToken.address); + expect(newSourceTokenBalance).to.eq(expectedSourceTokenBalance); + }); + }); + }); +}); diff --git a/test/protocol/integration/exchange/velodromeExchangeAdapter.spec.ts b/test/protocol/integration/exchange/velodromeExchangeAdapter.spec.ts new file mode 100644 index 000000000..2f87c1c5c --- /dev/null +++ b/test/protocol/integration/exchange/velodromeExchangeAdapter.spec.ts @@ -0,0 +1,301 @@ +import "module-alias/register"; + +import { ethers } from "hardhat"; +import { BigNumber } from "ethers"; +import { Address, Bytes } from "@utils/types"; +import { Account } from "@utils/test/types"; +import { ZERO } from "@utils/constants"; +import { VelodromeExchangeAdapter } from "@utils/contracts"; +import DeployHelper from "@utils/deploys"; +import { ether } from "@utils/index"; +import { + addSnapshotBeforeRestoreAfterEach, + getAccounts, + getSystemFixture, + getWaffleExpect, + getLastBlockTimestamp, + getVelodromeFixture, +} from "@utils/test/index"; +import { SystemFixture, VelodromeFixture } from "@utils/fixtures"; + +const expect = getWaffleExpect(); +describe("VelodromeExchangeAdapter", () => { + let owner: Account; + let mockSetToken: Account; + let deployer: DeployHelper; + let setup: SystemFixture; + let velodromeSetup: VelodromeFixture; + let velodromeExchangeAdapter: VelodromeExchangeAdapter; + + let sourceAddress: Address; // wbtc + let destinationAddress: Address; // dai + let sourceQuantity: BigNumber; + let destinationQuantity: BigNumber; + + before(async () => { + [owner, mockSetToken] = await getAccounts(); + + deployer = new DeployHelper(owner.wallet); + setup = getSystemFixture(owner.address); + await setup.initialize(); + + velodromeSetup = getVelodromeFixture(owner.address); + await velodromeSetup.initialize(owner, setup.weth.address); + + velodromeExchangeAdapter = await deployer.adapters.deployVelodromeExchangeAdapter( + velodromeSetup.router.address, + ); + + sourceAddress = setup.wbtc.address; // WBTC Address + sourceQuantity = BigNumber.from(100000000); // Trade 1 WBTC + destinationAddress = setup.dai.address; // DAI Address + destinationQuantity = ether(30000); // Receive at least 30k DAI + }); + + addSnapshotBeforeRestoreAfterEach(); + + describe("#constructor", async () => { + let subjectVelodromeRouter: Address; + + beforeEach(async () => { + subjectVelodromeRouter = velodromeSetup.router.address; + }); + + async function subject(): Promise { + return await deployer.adapters.deployVelodromeExchangeAdapter(subjectVelodromeRouter); + } + + it("should have the correct router address", async () => { + const deployedVelodromeV2ExchangeAdapter = await subject(); + + const actualRouterAddress = await deployedVelodromeV2ExchangeAdapter.router(); + expect(actualRouterAddress).to.eq(velodromeSetup.router.address); + }); + }); + + describe("#getSpender", async () => { + async function subject(): Promise { + return await velodromeExchangeAdapter.getSpender(); + } + + it("should return the correct spender address", async () => { + const spender = await subject(); + + expect(spender).to.eq(velodromeSetup.router.address); + }); + }); + + describe("#generateDataParam", async () => { + let subjectData: Bytes; + + it("should revert with empty routes when no routes passed in", async () => { + await expect( + velodromeExchangeAdapter.generateDataParam([], ethers.constants.MaxUint256), + ).to.revertedWith("empty routes"); + }); + + it("should revert with invalid deadline when invalid deadline passed in", async () => { + await expect( + velodromeExchangeAdapter.generateDataParam( + [ + { + from: sourceAddress, + to: destinationAddress, + stable: false, + }, + ], + 0, + ), + ).to.revertedWith("invalid deadline"); + }); + + it("should return the correct data param for wbtc -> dai", async () => { + subjectData = await velodromeExchangeAdapter.generateDataParam( + [ + { + from: sourceAddress, + to: destinationAddress, + stable: false, + }, + ], + ethers.constants.MaxUint256, + ); + expect(subjectData).to.eq( + ethers.utils.defaultAbiCoder.encode( + ["tuple(address,address,bool)[]", "uint256"], + [[[sourceAddress, destinationAddress, false]], ethers.constants.MaxUint256], + ), + ); + }); + + it("should return the correct data param for wbtc -> weth -> dai", async () => { + subjectData = await velodromeExchangeAdapter.generateDataParam( + [ + { from: sourceAddress, to: setup.weth.address, stable: false }, + { from: setup.weth.address, to: destinationAddress, stable: false }, + ], + ethers.constants.MaxUint256, + ); + expect(subjectData).to.eq( + ethers.utils.defaultAbiCoder.encode( + ["tuple(address,address,bool)[]", "uint256"], + [ + [ + [sourceAddress, setup.weth.address, false], + [setup.weth.address, destinationAddress, false], + ], + ethers.constants.MaxUint256, + ], + ), + ); + }); + }); + + describe("#getTradeCalldata", async () => { + let subjectMockSetToken: Address; + let subjectSourceToken: Address; + let subjectDestinationToken: Address; + let subjectSourceQuantity: BigNumber; + let subjectMinDestinationQuantity: BigNumber; + let subjectData: Bytes; + + beforeEach(async () => { + subjectSourceToken = sourceAddress; + subjectDestinationToken = destinationAddress; + subjectMockSetToken = mockSetToken.address; + subjectSourceQuantity = sourceQuantity; + subjectMinDestinationQuantity = destinationQuantity; + }); + + async function subject(): Promise { + return await velodromeExchangeAdapter.getTradeCalldata( + subjectSourceToken, + subjectDestinationToken, + subjectMockSetToken, + subjectSourceQuantity, + subjectMinDestinationQuantity, + subjectData, + ); + } + + it("should revert with empty routes when no routes passed in", async () => { + await expect( + velodromeExchangeAdapter.getTradeCalldata( + subjectSourceToken, + subjectDestinationToken, + subjectMockSetToken, + subjectSourceQuantity, + subjectMinDestinationQuantity, + ethers.utils.defaultAbiCoder.encode( + ["tuple(address,address,bool)[]", "uint256"], + [[], ethers.constants.MaxUint256], + ), + ), + ).to.revertedWith("empty routes"); + }); + + it("should revert with source token path mismatch", async () => { + await expect( + velodromeExchangeAdapter.getTradeCalldata( + subjectDestinationToken, + subjectDestinationToken, + subjectMockSetToken, + subjectSourceQuantity, + subjectMinDestinationQuantity, + ethers.utils.defaultAbiCoder.encode( + ["tuple(address,address,bool)[]", "uint256"], + [[[sourceAddress, destinationAddress, false]], ethers.constants.MaxUint256], + ), + ), + ).to.revertedWith("Source token path mismatch"); + }); + + it("should revert with destination token path mismatch", async () => { + await expect( + velodromeExchangeAdapter.getTradeCalldata( + subjectSourceToken, + subjectSourceToken, + subjectMockSetToken, + subjectSourceQuantity, + subjectMinDestinationQuantity, + ethers.utils.defaultAbiCoder.encode( + ["tuple(address,address,bool)[]", "uint256"], + [[[sourceAddress, destinationAddress, false]], ethers.constants.MaxUint256], + ), + ), + ).to.revertedWith("Destination token path mismatch"); + }); + + it("should revert with invalid deadline when invalid deadline passed in", async () => { + await expect( + velodromeExchangeAdapter.getTradeCalldata( + subjectSourceToken, + subjectDestinationToken, + subjectMockSetToken, + subjectSourceQuantity, + subjectMinDestinationQuantity, + ethers.utils.defaultAbiCoder.encode( + ["tuple(address,address,bool)[]", "uint256"], + [[[sourceAddress, destinationAddress, false]], 0], + ), + ), + ).to.revertedWith("invalid deadline"); + }); + + it("should return the correct trade calldata for wbtc -> dai", async () => { + const callTimestamp = await getLastBlockTimestamp(); + subjectData = await velodromeExchangeAdapter.generateDataParam( + [ + { + from: sourceAddress, + to: destinationAddress, + stable: false, + }, + ], + callTimestamp, + ); + const calldata = await subject(); + const expectedCallData = velodromeSetup.router.interface.encodeFunctionData( + "swapExactTokensForTokens", + [ + sourceQuantity, + destinationQuantity, + [{ from: sourceAddress, to: destinationAddress, stable: false }], + subjectMockSetToken, + callTimestamp, + ], + ); + expect(JSON.stringify(calldata)).to.eq( + JSON.stringify([velodromeSetup.router.address, ZERO, expectedCallData]), + ); + }); + + it("should return the correct trade calldata for wbtc -> wetb -> dai", async () => { + const callTimestamp = await getLastBlockTimestamp(); + subjectData = await velodromeExchangeAdapter.generateDataParam( + [ + { from: sourceAddress, to: setup.weth.address, stable: false }, + { from: setup.weth.address, to: destinationAddress, stable: false }, + ], + callTimestamp, + ); + const calldata = await subject(); + const expectedCallData = velodromeSetup.router.interface.encodeFunctionData( + "swapExactTokensForTokens", + [ + sourceQuantity, + destinationQuantity, + [ + { from: sourceAddress, to: setup.weth.address, stable: false }, + { from: setup.weth.address, to: destinationAddress, stable: false }, + ], + subjectMockSetToken, + callTimestamp, + ], + ); + expect(JSON.stringify(calldata)).to.eq( + JSON.stringify([velodromeSetup.router.address, ZERO, expectedCallData]), + ); + }); + }); +}); diff --git a/utils/contracts/index.ts b/utils/contracts/index.ts index 593889b16..25ca15889 100644 --- a/utils/contracts/index.ts +++ b/utils/contracts/index.ts @@ -109,6 +109,7 @@ export { Uni } from "../../typechain/Uni"; export { UniswapPairPriceAdapter } from "../../typechain/UniswapPairPriceAdapter"; export { UniswapV2AmmAdapter } from "../../typechain/UniswapV2AmmAdapter"; export { UniswapV2ExchangeAdapter } from "../../typechain/UniswapV2ExchangeAdapter"; +export { VelodromeExchangeAdapter } from "../../typechain/VelodromeExchangeAdapter"; export { UniswapV2ExchangeAdapterV2 } from "../../typechain/UniswapV2ExchangeAdapterV2"; export { UniswapV2IndexExchangeAdapter } from "../../typechain/UniswapV2IndexExchangeAdapter"; export { UniswapV3IndexExchangeAdapter } from "../../typechain/UniswapV3IndexExchangeAdapter"; diff --git a/utils/contracts/velodrome.ts b/utils/contracts/velodrome.ts new file mode 100644 index 000000000..c716246f8 --- /dev/null +++ b/utils/contracts/velodrome.ts @@ -0,0 +1,2 @@ +// External Velodrome Contracts +export { VelodromeFactory } from "../../typechain/VelodromeFactory"; \ No newline at end of file diff --git a/utils/deploys/dependencies.ts b/utils/deploys/dependencies.ts index 1da9147c3..40fac66c9 100644 --- a/utils/deploys/dependencies.ts +++ b/utils/deploys/dependencies.ts @@ -124,6 +124,11 @@ export default { 42: "0x4e67bf5bD28Dd4b570FBAFe11D0633eCbA2754Ec", }, + VELODROME_ROUTER: { + 10: "0xa132DAB612dB5cB9fC9Ac426A0Cc215A3423F9c9", + 42: "", + }, + // Governance AAVE_PROTO_GOVERNANCE: { diff --git a/utils/deploys/deployAdapters.ts b/utils/deploys/deployAdapters.ts index 72af8e9d1..03360169d 100644 --- a/utils/deploys/deployAdapters.ts +++ b/utils/deploys/deployAdapters.ts @@ -56,7 +56,11 @@ import { UniswapV3ExchangeAdapterV2__factory } from "../../typechain/factories/U import { SnapshotGovernanceAdapter__factory } from "../../typechain/factories/SnapshotGovernanceAdapter__factory"; import { SynthetixExchangeAdapter__factory } from "../../typechain/factories/SynthetixExchangeAdapter__factory"; import { CompoundBravoGovernanceAdapter__factory } from "../../typechain/factories/CompoundBravoGovernanceAdapter__factory"; -import { CompClaimAdapter__factory } from "../../typechain"; +import { + CompClaimAdapter__factory, + VelodromeExchangeAdapter, + VelodromeExchangeAdapter__factory, +} from "../../typechain"; import { RgtMigrationWrapAdapter__factory } from "../../typechain/factories/RgtMigrationWrapAdapter__factory"; export default class DeployAdapters { @@ -294,4 +298,12 @@ export default class DeployAdapters { exchange, ); } + + public async deployVelodromeExchangeAdapter( + velodromeRouter: Address, + ): Promise { + return await new VelodromeExchangeAdapter__factory(this._deployerSigner).deploy( + velodromeRouter, + ); + } } diff --git a/utils/deploys/deployExternal.ts b/utils/deploys/deployExternal.ts index 0ef99cfbd..822b0cc06 100644 --- a/utils/deploys/deployExternal.ts +++ b/utils/deploys/deployExternal.ts @@ -202,7 +202,12 @@ import { PerpV2ClearingHouseConfig__factory } from "../../typechain/factories/Pe import { PerpV2InsuranceFund__factory } from "../../typechain/factories/PerpV2InsuranceFund__factory"; import { PerpV2AccountBalance__factory } from "../../typechain/factories/PerpV2AccountBalance__factory"; import { PerpV2Exchange__factory } from "../../typechain/factories/PerpV2Exchange__factory"; - +import { VelodromeFactory__factory } from "../../typechain/factories/VelodromeFactory__factory"; +import { VelodromeRouter__factory } from "../../typechain/factories/VelodromeRouter__factory"; +import { VelodromePair__factory } from "../../typechain/factories/VelodromePair__factory"; +import { VelodromeFactory } from "../../typechain/VelodromeFactory"; +import { VelodromeRouter } from "../../typechain/VelodromeRouter"; +import { VelodromePair } from "../../typechain/VelodromePair"; export default class DeployExternalContracts { private _deployerSigner: Signer; @@ -740,4 +745,21 @@ export default class DeployExternalContracts { public async getVToken(token: Address): Promise { return await new PerpV2BaseToken__factory(this._deployerSigner).attach(token); } + + // Velodrome + public async deployVelodromeFactory(): Promise { + return await new VelodromeFactory__factory(this._deployerSigner).deploy(); + } + + public async deployVelodromeRouter(_factory: Address, _weth: Address): Promise { + return await new VelodromeRouter__factory(this._deployerSigner).deploy(_factory, _weth); + } + + public async deployVelodromePair(): Promise { + return await new VelodromePair__factory(this._deployerSigner).deploy(); + } + + public getForkedVelodromeRouter(_mainnetRouter: Address): VelodromeRouter { + return VelodromeRouter__factory.connect(_mainnetRouter, this._deployerSigner); + } } diff --git a/utils/fixtures/index.ts b/utils/fixtures/index.ts index e390db2c4..754f278d4 100644 --- a/utils/fixtures/index.ts +++ b/utils/fixtures/index.ts @@ -8,3 +8,4 @@ export { UniswapFixture } from "./uniswapFixture"; export { UniswapV3Fixture } from "./uniswapV3Fixture"; export { YearnFixture } from "./yearnFixture"; export { PerpV2Fixture } from "./perpV2Fixture"; +export { VelodromeFixture } from "./velodromeFixture"; diff --git a/utils/fixtures/velodromeFixture.ts b/utils/fixtures/velodromeFixture.ts new file mode 100644 index 000000000..7aed9f051 --- /dev/null +++ b/utils/fixtures/velodromeFixture.ts @@ -0,0 +1,66 @@ +import DeployHelper from "../deploys"; +import { Signer, providers, BigNumber } from "ethers"; +import { Address } from "../types"; +import { Account } from "../test/types"; + +import dependencies from "../deploys/dependencies"; +import { Uni } from "../../typechain/Uni"; +import { VelodromeFactory } from "../../typechain/VelodromeFactory"; +import { VelodromePair } from "../../typechain/VelodromePair"; +import { VelodromeRouter } from "../../typechain/VelodromeRouter"; +import { VelodromePair__factory } from "../../typechain/factories/VelodromePair__factory"; + +export class VelodromeFixture { + private _deployer: DeployHelper; + private _provider: providers.Web3Provider | providers.JsonRpcProvider; + private _ownerSigner: Signer; + + public owner: Account; + public uni: Uni; + public factory: VelodromeFactory; + public pair: VelodromePair; + public router: VelodromeRouter; + + public uniWethPool: VelodromePair; + + constructor(provider: providers.Web3Provider | providers.JsonRpcProvider, ownerAddress: Address) { + this._ownerSigner = provider.getSigner(ownerAddress); + this._provider = provider; + this._deployer = new DeployHelper(this._ownerSigner); + } + + public async initialize(_owner: Account, _weth: Address): Promise { + this.owner = _owner; + this.factory = await this._deployer.external.deployVelodromeFactory(); + this.router = await this._deployer.external.deployVelodromeRouter(this.factory.address, _weth); + + const lastBlock = await this._provider.getBlock("latest"); + this.uni = await this._deployer.external.deployUni( + this.owner.address, + this.owner.address, + BigNumber.from(lastBlock.timestamp).add(2), + ); + + this.uniWethPool = await this.createNewPair(_weth, this.uni.address, false); + } + + public async createNewPair( + _tokenOne: Address, + _tokenTwo: Address, + stable: boolean, + ): Promise { + await this.factory.createPair(_tokenOne, _tokenTwo, stable); + const poolAddress = await this.factory.allPairs((await this.factory.allPairsLength()).sub(1)); + return await new VelodromePair__factory(this._ownerSigner).attach(poolAddress); + } + + public getTokenOrder(_tokenOne: Address, _tokenTwo: Address): [Address, Address] { + return _tokenOne.toLowerCase() < _tokenTwo.toLowerCase() + ? [_tokenOne, _tokenTwo] + : [_tokenTwo, _tokenOne]; + } + + public getForkedVelodromeRouter(): VelodromeRouter { + return this._deployer.external.getForkedVelodromeRouter(dependencies.VELODROME_ROUTER[10]); + } +} diff --git a/utils/test/index.ts b/utils/test/index.ts index 3cb59708d..067531ae1 100644 --- a/utils/test/index.ts +++ b/utils/test/index.ts @@ -12,7 +12,8 @@ import { UniswapFixture, YearnFixture, UniswapV3Fixture, - PerpV2Fixture + PerpV2Fixture, + VelodromeFixture } from "../fixtures"; import { Blockchain, ProtocolUtils } from "../common"; @@ -27,6 +28,7 @@ export const getCurveFixture = (ownerAddress: Address) => new CurveFixture(provi export const getCompoundFixture = (ownerAddress: Address) => new CompoundFixture(provider, ownerAddress); export const getKyberV3DMMFixture = (ownerAddress: Address) => new KyberV3DMMFixture(provider, ownerAddress); export const getUniswapFixture = (ownerAddress: Address) => new UniswapFixture(provider, ownerAddress); +export const getVelodromeFixture = (ownerAddress: Address) => new VelodromeFixture(provider, ownerAddress); export const getYearnFixture = (ownerAddress: Address) => new YearnFixture(provider, ownerAddress); export const getUniswapV3Fixture = (ownerAddress: Address) => new UniswapV3Fixture(provider, ownerAddress); export const getPerpV2Fixture = (ownerAddress: Address) => new PerpV2Fixture(provider, ownerAddress);