From c0d55caeaf6d80052452ed1642c1c38d5fce6242 Mon Sep 17 00:00:00 2001 From: ncitron Date: Fri, 10 Sep 2021 16:17:52 -0400 Subject: [PATCH 1/9] add balancer v2 contracts and deploy functions --- external/abi/balancer/{ => v1}/BFactory.json | 0 external/abi/balancer/{ => v1}/BPool.json | 0 external/abi/balancer/{ => v1}/BRegistry.json | 0 .../abi/balancer/{ => v1}/ExchangeProxy.json | 0 external/abi/balancer/v2/BVault.json | 8 ++++++++ .../abi/balancer/v2/WeightedPoolFactory.json | 8 ++++++++ utils/contracts/balancerV2.ts | 3 +++ utils/deploys/deployExternal.ts | 20 +++++++++++++++++-- 8 files changed, 37 insertions(+), 2 deletions(-) rename external/abi/balancer/{ => v1}/BFactory.json (100%) rename external/abi/balancer/{ => v1}/BPool.json (100%) rename external/abi/balancer/{ => v1}/BRegistry.json (100%) rename external/abi/balancer/{ => v1}/ExchangeProxy.json (100%) create mode 100644 external/abi/balancer/v2/BVault.json create mode 100644 external/abi/balancer/v2/WeightedPoolFactory.json create mode 100644 utils/contracts/balancerV2.ts diff --git a/external/abi/balancer/BFactory.json b/external/abi/balancer/v1/BFactory.json similarity index 100% rename from external/abi/balancer/BFactory.json rename to external/abi/balancer/v1/BFactory.json diff --git a/external/abi/balancer/BPool.json b/external/abi/balancer/v1/BPool.json similarity index 100% rename from external/abi/balancer/BPool.json rename to external/abi/balancer/v1/BPool.json diff --git a/external/abi/balancer/BRegistry.json b/external/abi/balancer/v1/BRegistry.json similarity index 100% rename from external/abi/balancer/BRegistry.json rename to external/abi/balancer/v1/BRegistry.json diff --git a/external/abi/balancer/ExchangeProxy.json b/external/abi/balancer/v1/ExchangeProxy.json similarity index 100% rename from external/abi/balancer/ExchangeProxy.json rename to external/abi/balancer/v1/ExchangeProxy.json diff --git a/external/abi/balancer/v2/BVault.json b/external/abi/balancer/v2/BVault.json new file mode 100644 index 000000000..8cbaef130 --- /dev/null +++ b/external/abi/balancer/v2/BVault.json @@ -0,0 +1,8 @@ +{ + "contractName": "BVault", + "abi": [{"inputs":[{"internalType":"contract IAuthorizer","name":"authorizer","type":"address"},{"internalType":"contract IWETH","name":"weth","type":"address"},{"internalType":"uint256","name":"pauseWindowDuration","type":"uint256"},{"internalType":"uint256","name":"bufferPeriodDuration","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IAuthorizer","name":"newAuthorizer","type":"address"}],"name":"AuthorizerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ExternalBalanceTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IFlashLoanRecipient","name":"recipient","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeAmount","type":"uint256"}],"name":"FlashLoan","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"int256","name":"delta","type":"int256"}],"name":"InternalBalanceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"PausedStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"liquidityProvider","type":"address"},{"indexed":false,"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"indexed":false,"internalType":"int256[]","name":"deltas","type":"int256[]"},{"indexed":false,"internalType":"uint256[]","name":"protocolFeeAmounts","type":"uint256[]"}],"name":"PoolBalanceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"assetManager","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"int256","name":"cashDelta","type":"int256"},{"indexed":false,"internalType":"int256","name":"managedDelta","type":"int256"}],"name":"PoolBalanceManaged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"poolAddress","type":"address"},{"indexed":false,"internalType":"enum IVault.PoolSpecialization","name":"specialization","type":"uint8"}],"name":"PoolRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"relayer","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"RelayerApprovalChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":true,"internalType":"contract IERC20","name":"tokenIn","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"contract IERC20[]","name":"tokens","type":"address[]"}],"name":"TokensDeregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"assetManagers","type":"address[]"}],"name":"TokensRegistered","type":"event"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum IVault.SwapKind","name":"kind","type":"uint8"},{"components":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"uint256","name":"assetInIndex","type":"uint256"},{"internalType":"uint256","name":"assetOutIndex","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"internalType":"struct IVault.BatchSwapStep[]","name":"swaps","type":"tuple[]"},{"internalType":"contract IAsset[]","name":"assets","type":"address[]"},{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"bool","name":"fromInternalBalance","type":"bool"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"bool","name":"toInternalBalance","type":"bool"}],"internalType":"struct IVault.FundManagement","name":"funds","type":"tuple"},{"internalType":"int256[]","name":"limits","type":"int256[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"batchSwap","outputs":[{"internalType":"int256[]","name":"assetDeltas","type":"int256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"}],"name":"deregisterTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address payable","name":"recipient","type":"address"},{"components":[{"internalType":"contract IAsset[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"minAmountsOut","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"},{"internalType":"bool","name":"toInternalBalance","type":"bool"}],"internalType":"struct IVault.ExitPoolRequest","name":"request","type":"tuple"}],"name":"exitPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IFlashLoanRecipient","name":"recipient","type":"address"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"flashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"getActionId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAuthorizer","outputs":[{"internalType":"contract IAuthorizer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDomainSeparator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"}],"name":"getInternalBalance","outputs":[{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getNextNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPausedState","outputs":[{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"uint256","name":"pauseWindowEndTime","type":"uint256"},{"internalType":"uint256","name":"bufferPeriodEndTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"}],"name":"getPool","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"enum IVault.PoolSpecialization","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"getPoolTokenInfo","outputs":[{"internalType":"uint256","name":"cash","type":"uint256"},{"internalType":"uint256","name":"managed","type":"uint256"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"address","name":"assetManager","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"}],"name":"getPoolTokens","outputs":[{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProtocolFeesCollector","outputs":[{"internalType":"contract ProtocolFeesCollector","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"relayer","type":"address"}],"name":"hasApprovedRelayer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"components":[{"internalType":"contract IAsset[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"maxAmountsIn","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"},{"internalType":"bool","name":"fromInternalBalance","type":"bool"}],"internalType":"struct IVault.JoinPoolRequest","name":"request","type":"tuple"}],"name":"joinPool","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"enum IVault.PoolBalanceOpKind","name":"kind","type":"uint8"},{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IVault.PoolBalanceOp[]","name":"ops","type":"tuple[]"}],"name":"managePoolBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"enum IVault.UserBalanceOpKind","name":"kind","type":"uint8"},{"internalType":"contract IAsset","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct IVault.UserBalanceOp[]","name":"ops","type":"tuple[]"}],"name":"manageUserBalance","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"enum IVault.SwapKind","name":"kind","type":"uint8"},{"components":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"uint256","name":"assetInIndex","type":"uint256"},{"internalType":"uint256","name":"assetOutIndex","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"internalType":"struct IVault.BatchSwapStep[]","name":"swaps","type":"tuple[]"},{"internalType":"contract IAsset[]","name":"assets","type":"address[]"},{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"bool","name":"fromInternalBalance","type":"bool"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"bool","name":"toInternalBalance","type":"bool"}],"internalType":"struct IVault.FundManagement","name":"funds","type":"tuple"}],"name":"queryBatchSwap","outputs":[{"internalType":"int256[]","name":"","type":"int256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum IVault.PoolSpecialization","name":"specialization","type":"uint8"}],"name":"registerPool","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"address[]","name":"assetManagers","type":"address[]"}],"name":"registerTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IAuthorizer","name":"newAuthorizer","type":"address"}],"name":"setAuthorizer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"relayer","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setRelayerApproval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"enum IVault.SwapKind","name":"kind","type":"uint8"},{"internalType":"contract IAsset","name":"assetIn","type":"address"},{"internalType":"contract IAsset","name":"assetOut","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"internalType":"struct IVault.SingleSwap","name":"singleSwap","type":"tuple"},{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"bool","name":"fromInternalBalance","type":"bool"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"bool","name":"toInternalBalance","type":"bool"}],"internalType":"struct IVault.FundManagement","name":"funds","type":"tuple"},{"internalType":"uint256","name":"limit","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swap","outputs":[{"internalType":"uint256","name":"amountCalculated","type":"uint256"}],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}], + "bytecode": "6101806040523480156200001257600080fd5b5060405162006ed638038062006ed6833981016040819052620000359162000253565b8382826040518060400160405280601181526020017010985b185b98d95c88158c8815985d5b1d607a1b81525080604051806040016040528060018152602001603160f81b815250306001600160a01b031660001b89806001600160a01b03166080816001600160a01b031660601b815250505030604051620000b89062000245565b620000c491906200029f565b604051809103906000f080158015620000e1573d6000803e3d6000fd5b5060601b6001600160601b03191660a052600160005560c052815160209283012060e052805191012061010052507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61012052620001486276a70083111561019462000181565b6200015c62278d0082111561019562000181565b429091016101408190520161016052620001768162000196565b5050505050620002cc565b8162000192576200019281620001f2565b5050565b6040516001600160a01b038216907f94b979b6831a51293e2641426f97747feed46f17779fed9cd18d1ecefcfe92ef90600090a2600380546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b62461bcd60e51b6000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b610be680620062f083390190565b6000806000806080858703121562000269578384fd5b84516200027681620002b3565b60208601519094506200028981620002b3565b6040860151606090960151949790965092505050565b6001600160a01b0391909116815260200190565b6001600160a01b0381168114620002c957600080fd5b50565b60805160601c60a05160601c60c05160e05161010051610120516101405161016051615fc06200033060003980611aed525080611ac952508061289f5250806128e15250806128c05250806110fd5250806113b15250806105285250615fc06000f3fe6080604052600436106101a55760003560e01c8063945bcec9116100e1578063e6c460921161008a578063f84d066e11610064578063f84d066e1461048a578063f94d4668146104aa578063fa6e671d146104d9578063fec90d72146104f9576101d3565b8063e6c4609214610427578063ed24911d14610447578063f6c009271461045c576101d3565b8063b05f8e48116100bb578063b05f8e48146103cf578063b95cac28146103ff578063d2946c2b14610412576101d3565b8063945bcec914610385578063aaabadc514610398578063ad5c4648146103ba576101d3565b806352bbbe291161014e5780637d3aeb96116101285780637d3aeb9614610305578063851c1bb3146103255780638bdb39131461034557806390193b7c14610365576101d3565b806352bbbe29146102b25780635c38449e146102c557806366a9c7d2146102e5576101d3565b80630f5a6efa1161017f5780630f5a6efa1461024157806316c38b3c1461026e5780631c0de0511461028e576101d3565b8063058a628f146101d857806309b2760f146101f85780630e8e3e841461022e576101d3565b366101d3576101d16101b5610526565b6001600160a01b0316336001600160a01b03161461020661054b565b005b600080fd5b3480156101e457600080fd5b506101d16101f3366004615157565b61055d565b34801561020457600080fd5b506102186102133660046156e6565b610581565b6040516102259190615d3e565b60405180910390f35b6101d161023c36600461531e565b610634565b34801561024d57600080fd5b5061026161025c3660046151f5565b610770565b6040516102259190615d08565b34801561027a57600080fd5b506101d161028936600461545c565b610806565b34801561029a57600080fd5b506102a361081f565b60405161022593929190615d26565b6102186102c036600461588f565b610848565b3480156102d157600080fd5b506101d16102e036600461565b565b6109e9565b3480156102f157600080fd5b506101d1610300366004615545565b610e06565b34801561031157600080fd5b506101d1610320366004615516565b610fa5565b34801561033157600080fd5b50610218610340366004615633565b6110f9565b34801561035157600080fd5b506101d16103603660046154ac565b61114b565b34801561037157600080fd5b50610218610380366004615157565b611161565b610261610393366004615786565b61117c565b3480156103a457600080fd5b506103ad6112b0565b6040516102259190615b63565b3480156103c657600080fd5b506103ad6112c4565b3480156103db57600080fd5b506103ef6103ea36600461560f565b6112d3565b6040516102259493929190615eb9565b6101d161040d3660046154ac565b611396565b34801561041e57600080fd5b506103ad6113af565b34801561043357600080fd5b506101d1610442366004615243565b6113d3565b34801561045357600080fd5b506102186114ef565b34801561046857600080fd5b5061047c610477366004615494565b6114f9565b604051610225929190615b9b565b34801561049657600080fd5b506102616104a5366004615702565b611523565b3480156104b657600080fd5b506104ca6104c5366004615494565b611620565b60405161022593929190615cd2565b3480156104e557600080fd5b506101d16104f43660046151ab565b611654565b34801561050557600080fd5b50610519610514366004615173565b6116e6565b6040516102259190615d1b565b7f00000000000000000000000000000000000000000000000000000000000000005b90565b8161055957610559816116fb565b5050565b610565611768565b61056d611781565b610576816117af565b61057e611822565b50565b600061058b611768565b610593611829565b60006105a2338460065461183e565b6000818152600560205260409020549091506105c49060ff16156101f461054b565b60008181526005602052604090819020805460ff1916600190811790915560068054909101905551339082907f3c13bc30b8e878c53fd2a36b679409c073afd75950be43d8858768e956fbc20e9061061d908790615e3a565b60405180910390a3905061062f611822565b919050565b61063c611768565b6000806000805b845181101561075b5760008060008060006106718a878151811061066357fe5b60200260200101518961187d565b9c50939850919650945092509050600185600381111561068d57fe5b14156106a45761069f848383866118f5565b61074a565b866106b6576106b1611829565b600196505b60008560038111156106c457fe5b14156106f5576106d684838386611918565b6106df84611938565b1561069f576106ee8984611945565b985061074a565b61070a61070185611938565b1561020761054b565b600061071585610548565b9050600286600381111561072557fe5b141561073c5761073781848487611957565b610748565b61074881848487611970565b505b505060019093019250610643915050565b50610765836119de565b50505061057e611822565b6060815167ffffffffffffffff8111801561078a57600080fd5b506040519080825280602002602001820160405280156107b4578160200160208202803683370190505b50905060005b82518110156107ff576107e0848483815181106107d357fe5b6020026020010151611a01565b8282815181106107ec57fe5b60209081029190910101526001016107ba565b5092915050565b61080e611768565b610816611781565b61057681611a2c565b600080600061082c611aaa565b159250610837611ac7565b9150610841611aeb565b9050909192565b6000610852611768565b61085a611829565b835161086581611b0f565b610874834211156101fc61054b565b61088760008760800151116101fe61054b565b60006108968760400151611b41565b905060006108a78860600151611b41565b90506108ca816001600160a01b0316836001600160a01b031614156101fd61054b565b6108d2614ce1565b885160808201526020890151819060018111156108eb57fe5b908160018111156108f857fe5b9052506001600160a01b03808416602083015282811660408084019190915260808b0151606084015260a08b01516101008401528951821660c08401528901511660e082015260008061094a83611b66565b9198509250905061098160008c60200151600181111561096657fe5b146109745789831115610979565b898210155b6101fb61054b565b6109998b60400151838c600001518d60200151611c5a565b6109b18b60600151828c604001518d60600151611d38565b6109d36109c18c60400151611938565b6109cc5760006109ce565b825b6119de565b5050505050506109e1611822565b949350505050565b6109f1611768565b6109f9611829565b610a0583518351611e12565b6060835167ffffffffffffffff81118015610a1f57600080fd5b50604051908082528060200260200182016040528015610a49578160200160208202803683370190505b5090506060845167ffffffffffffffff81118015610a6657600080fd5b50604051908082528060200260200182016040528015610a90578160200160208202803683370190505b5090506000805b8651811015610c09576000878281518110610aae57fe5b602002602001015190506000878381518110610ac657fe5b60200260200101519050610b11846001600160a01b0316836001600160a01b03161160006001600160a01b0316846001600160a01b031614610b09576066610b0c565b60685b61054b565b819350816001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610b409190615b63565b60206040518083038186803b158015610b5857600080fd5b505afa158015610b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b909190615968565b858481518110610b9c57fe5b602002602001018181525050610bb181611e1f565b868481518110610bbd57fe5b602002602001018181525050610beb81868581518110610bd957fe5b6020026020010151101561021061054b565b610bff6001600160a01b0383168b83611ea6565b5050600101610a97565b506040517ff04f27070000000000000000000000000000000000000000000000000000000081526001600160a01b0388169063f04f270790610c55908990899088908a90600401615c85565b600060405180830381600087803b158015610c6f57600080fd5b505af1158015610c83573d6000803e3d6000fd5b5050505060005b8651811015610df4576000878281518110610ca157fe5b602002602001015190506000848381518110610cb957fe5b602002602001015190506000826001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610cf19190615b63565b60206040518083038186803b158015610d0957600080fd5b505afa158015610d1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d419190615968565b9050610d528282101561020361054b565b60008282039050610d7b888681518110610d6857fe5b602002602001015182101561025a61054b565b610d858482611f11565b836001600160a01b03168c6001600160a01b03167f0d7d75e01ab95780d3cd1c8ec0dd6c2ce19e3a20427eec8bf53283b6fb8e95f08c8881518110610dc657fe5b602002602001015184604051610ddd929190615e4d565b60405180910390a350505050806001019050610c8a565b50505050610e00611822565b50505050565b610e0e611768565b610e16611829565b82610e2081611f33565b610e2c83518351611e12565b60005b8351811015610eca576000848281518110610e4657fe5b60200260200101519050610e7260006001600160a01b0316826001600160a01b0316141561013561054b565b838281518110610e7e57fe5b6020908102919091018101516000888152600a835260408082206001600160a01b0395861683529093529190912080546001600160a01b03191692909116919091179055600101610e2f565b506000610ed685611f64565b90506002816002811115610ee657fe5b1415610f3457610efc845160021461020c61054b565b610f2f8585600081518110610f0d57fe5b602002602001015186600181518110610f2257fe5b6020026020010151611f7e565b610f5c565b6001816002811115610f4257fe5b1415610f5257610f2f858561202a565b610f5c8585612082565b847ff5847d3f2197b16cdcd2098ec95d0905cd1abdaf415f07bb7cef2bba8ac5dec48585604051610f8e929190615bed565b60405180910390a25050610fa0611822565b505050565b610fad611768565b610fb5611829565b81610fbf81611f33565b6000610fca84611f64565b90506002816002811115610fda57fe5b141561102857610ff0835160021461020c61054b565b611023848460008151811061100157fe5b60200260200101518560018151811061101657fe5b60200260200101516120d7565b611050565b600181600281111561103657fe5b1415611046576110238484612145565b61105084846121ff565b60005b83518110156110b657600a6000868152602001908152602001600020600085838151811061107d57fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055600101611053565b50837f7dcdc6d02ef40c7c1a7046a011b058bd7f988fa14e20a66344f9d4e60657d610846040516110e79190615bda565b60405180910390a25050610559611822565b60007f00000000000000000000000000000000000000000000000000000000000000008260405160200161112e929190615ac2565b604051602081830303815290604052805190602001209050919050565b610e00600185858561115c86612262565b61226e565b6001600160a01b031660009081526002602052604090205490565b6060611186611768565b61118e611829565b835161119981611b0f565b6111a8834211156101fc61054b565b6111b486518551611e12565b6111c08787878b6123f4565b91506000805b87518110156112925760008882815181106111dd57fe5b6020026020010151905060008583815181106111f557fe5b6020026020010151905061122188848151811061120e57fe5b60200260200101518213156101fb61054b565b600081131561126157885160208a015182916112409185918491611c5a565b61124983611938565b1561125b576112588582611945565b94505b50611288565b600081121561128857600081600003905061128683828c604001518d60600151611d38565b505b50506001016111c6565b5061129c816119de565b50506112a6611822565b9695505050505050565b60035461010090046001600160a01b031690565b60006112ce610526565b905090565b600080600080856112e381612683565b6000806112ef89611f64565b905060028160028111156112ff57fe5b14156113165761130f89896126a1565b9150611341565b600181600281111561132457fe5b14156113345761130f898961271b565b61133e8989612789565b91505b61134a826127a1565b9650611355826127b4565b9550611360826127ca565b6000998a52600a60209081526040808c206001600160a01b039b8c168d5290915290992054969995989796909616955050505050565b61139e611829565b610e00600085858561115c86612262565b7f000000000000000000000000000000000000000000000000000000000000000090565b6113db611768565b6113e3611829565b6113eb614d31565b60005b82518110156114e55782818151811061140357fe5b6020026020010151915060008260200151905061141f81612683565b604083015161143961143183836127d0565b61020961054b565b6000828152600a602090815260408083206001600160a01b03858116855292529091205461146c911633146101f661054b565b835160608501516000806114828487878661282c565b91509150846001600160a01b0316336001600160a01b0316877f6edcaf6241105b4c94c2efdbf3a6b12458eb3d07be3a0e81d24b13c44045fe7a85856040516114cc929190615e4d565b60405180910390a45050505050508060010190506113ee565b505061057e611822565b60006112ce61289b565b6000808261150681612683565b61150f84612938565b61151885611f64565b925092505b50915091565b60603330146115f6576000306001600160a01b0316600036604051611549929190615ada565b6000604051808303816000865af19150503d8060008114611586576040519150601f19603f3d011682016040523d82523d6000602084013e61158b565b606091505b50509050806000811461159a57fe5b60046000803e6000516001600160e01b0319167ffa61cc120000000000000000000000000000000000000000000000000000000081146115de573d6000803e3d6000fd5b50602060005260043d0380600460203e602081016000f35b6060611604858585896123f4565b9050602081510263fa61cc126020830352600482036024820181fd5b60608060008361162f81612683565b606061163a8661293e565b9095509050611648816129a0565b95979096509350505050565b61165c611768565b611664611829565b8261166e81611b0f565b6001600160a01b0384811660008181526004602090815260408083209488168084529490915290819020805460ff1916861515179055519091907f46961fdb4502b646d5095fba7600486a8ac05041d55cdf0f16ed677180b5cad8906116d5908690615d1b565b60405180910390a350610fa0611822565b60006116f28383612a4f565b90505b92915050565b7f08c379a0000000000000000000000000000000000000000000000000000000006000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b61177a6002600054141561019061054b565b6002600055565b60006117986000356001600160e01b0319166110f9565b905061057e6117a78233612a7d565b61019161054b565b6040516001600160a01b038216907f94b979b6831a51293e2641426f97747feed46f17779fed9cd18d1ecefcfe92ef90600090a2600380546001600160a01b03909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b6001600055565b61183c611834611aaa565b61019261054b565b565b600069ffffffffffffffffffff8216605084600281111561185b57fe5b901b17606085901b6bffffffffffffffffffffffff19161790505b9392505050565b600080600080600080600088606001519050336001600160a01b0316816001600160a01b0316146118cf57876118ba576118b5611781565b600197505b6118cf6118c78233612a4f565b6101f761054b565b885160208a015160408b01516080909b0151919b909a9992985090965090945092505050565b61190a8361190286611b41565b836000612b20565b50610e008482846000611d38565b61192b8261192586611b41565b83612b76565b610e008482856000611c5a565b6001600160a01b03161590565b60008282016116f2848210158361054b565b6119648385836000612b20565b50610e00828583612b76565b8015610e005761198b6001600160a01b038516848484612ba6565b826001600160a01b0316846001600160a01b03167f540a1a3f28340caec336c81d8d7b3df139ee5cdc1839a4f283d7ebb7eaae2d5c84846040516119d0929190615bc1565b60405180910390a350505050565b6119ed8134101561020461054b565b348190038015610559576105593382612bc7565b6001600160a01b039182166000908152600b6020908152604080832093909416825291909152205490565b8015611a4c57611a47611a3d611ac7565b421061019361054b565b611a61565b611a61611a57611aeb565b42106101a961054b565b6003805460ff19168215151790556040517f9e3a5e37224532dea67b89face185703738a228a6e8a23dee546960180d3be6490611a9f908390615d1b565b60405180910390a150565b6000611ab4611aeb565b4211806112ce57505060035460ff161590565b7f000000000000000000000000000000000000000000000000000000000000000090565b7f000000000000000000000000000000000000000000000000000000000000000090565b336001600160a01b0382161461057e57611b27611781565b611b318133612a4f565b61057e5761057e816101f7612c41565b6000611b4c82611938565b611b5e57611b5982610548565b6116f5565b6116f5610526565b600080600080611b798560800151612938565b90506000611b8a8660800151611f64565b90506002816002811115611b9a57fe5b1415611bb157611baa8683612c75565b9450611bdc565b6001816002811115611bbf57fe5b1415611bcf57611baa8683612d25565b611bd98683612db8565b94505b611bef8660000151876060015187612ff7565b809450819550505085604001516001600160a01b031686602001516001600160a01b031687608001517f2170c741c41531aec20e7c107c24eecfdd15e69c9bb0a8dd37b1840b9e0b207b8787604051611c49929190615e4d565b60405180910390a450509193909250565b82611c6457610e00565b611c6d84611938565b15611cee57611c7f811561020261054b565b611c8e8347101561020461054b565b611c96610526565b6001600160a01b031663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b158015611cd057600080fd5b505af1158015611ce4573d6000803e3d6000fd5b5050505050610e00565b6000611cf985610548565b90508115611d16576000611d108483876001612b20565b90940393505b8315611d3157611d316001600160a01b038216843087612ba6565b5050505050565b82611d4257610e00565b611d4b84611938565b15611ddb57611d5d811561020261054b565b611d65610526565b6001600160a01b0316632e1a7d4d846040518263ffffffff1660e01b8152600401611d909190615d3e565b600060405180830381600087803b158015611daa57600080fd5b505af1158015611dbe573d6000803e3d6000fd5b50611dd6925050506001600160a01b03831684612bc7565b610e00565b6000611de685610548565b90508115611dfe57611df9838286612b76565b611d31565b611d316001600160a01b0382168486611ea6565b610559818314606761054b565b600080611e2a6113af565b6001600160a01b031663d877845c6040518163ffffffff1660e01b815260040160206040518083038186803b158015611e6257600080fd5b505afa158015611e76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9a9190615968565b90506118768382613025565b610fa08363a9059cbb60e01b8484604051602401611ec5929190615bc1565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b031990931692909217909152613072565b801561055957610559611f226113af565b6001600160a01b0384169083611ea6565b611f3c81612683565b61057e611f4882612938565b6001600160a01b0316336001600160a01b0316146101f561054b565b600061ffff605083901c166116f5600382106101f461054b565b611f9f816001600160a01b0316836001600160a01b0316141561020a61054b565b611fbe816001600160a01b0316836001600160a01b031610606661054b565b60008381526009602052604090208054611ffb906001600160a01b0316158015611ff3575060018201546001600160a01b0316155b61020b61054b565b80546001600160a01b039384166001600160a01b03199182161782556001909101805492909316911617905550565b6000828152600860205260408120905b8251811015610e0057600061206b84838151811061205457fe5b60200260200101518461311290919063ffffffff16565b90506120798161020a61054b565b5060010161203a565b6000828152600160205260408120905b8251811015610e005760006120c08483815181106120ac57fe5b602090810291909101015184906000613175565b90506120ce8161020a61054b565b50600101612092565b60008060006120e7868686613222565b9250925092506121116120f9846132e9565b80156121095750612109836132e9565b61020d61054b565b600095865260096020526040862080546001600160a01b031990811682556001909101805490911690559490945550505050565b6000828152600860205260408120905b8251811015610e0057600083828151811061216c57fe5b602002602001015190506121b8612109600760008881526020019081526020016000206000846001600160a01b03166001600160a01b03168152602001908152602001600020546132e9565b60008581526007602090815260408083206001600160a01b038516845290915281208190556121e7848361330b565b90506121f58161020961054b565b5050600101612155565b6000828152600160205260408120905b8251811015610e0057600083828151811061222657fe5b60200260200101519050600061223c8483613412565b905061224a612109826132e9565b6122548483613421565b50505080600101905061220f565b61226a614d5a565b5090565b612276611768565b8361228081612683565b8361228a81611b0f565b61229e836000015151846020015151611e12565b60606122ad84600001516134c3565b905060606122bb8883613552565b905060608060606122d08c8c8c8c8c896135e3565b92509250925060006122e18c611f64565b905060028160028111156122f157fe5b1415612359576123548c8760008151811061230857fe5b60200260200101518660008151811061231d57fe5b60200260200101518960018151811061233257fe5b60200260200101518860018151811061234757fe5b60200260200101516137a8565b612382565b600181600281111561236757fe5b1415612378576123548c87866137e7565b6123828c85613854565b6000808e600181111561239157fe5b1490508b6001600160a01b03168d7fe5ce249087ce04f05a957192435400fd97868dba0e6a4b4c049abf8af80dae78896123cb888661389d565b876040516123db93929190615c4c565b60405180910390a3505050505050505050611d31611822565b6060835167ffffffffffffffff8111801561240e57600080fd5b50604051908082528060200260200182016040528015612438578160200160208202803683370190505b509050612443614d84565b61244b614ce1565b60008060005b89518110156126765789818151811061246657fe5b6020026020010151945060008951866020015110801561248a575089518660400151105b905061249781606461054b565b60006124b98b8860200151815181106124ac57fe5b6020026020010151611b41565b905060006124d08c8960400151815181106124ac57fe5b90506124f3816001600160a01b0316836001600160a01b031614156101fd61054b565b60608801516125435761250b600085116101fe61054b565b60006125188b8484613945565b6001600160a01b0316876001600160a01b031614905061253a816101ff61054b565b50606088018590525b87516080880152868a600181111561255757fe5b9081600181111561256457fe5b9052506001600160a01b0380831660208901528181166040808a01919091526060808b0151908a015260808a01516101008a01528c51821660c08a01528c01511660e08801526000806125b689611b66565b919850925090506125c88c8585613967565b97506125fc6125d683613981565b8c8c60200151815181106125e657fe5b60200260200101516139b190919063ffffffff16565b8b8b602001518151811061260c57fe5b60200260200101818152505061264a61262482613981565b8c8c604001518151811061263457fe5b60200260200101516139e590919063ffffffff16565b8b8b604001518151811061265a57fe5b6020026020010181815250505050505050806001019050612451565b5050505050949350505050565b60008181526005602052604090205461057e9060ff166101f461054b565b60008060008060006126b287613a19565b945094509450945050836001600160a01b0316866001600160a01b031614156126e157829450505050506116f5565b816001600160a01b0316866001600160a01b031614156127065793506116f592505050565b6127116102096116fb565b5050505092915050565b60008281526007602090815260408083206001600160a01b03851684529091528120548161274882613a8f565b80612766575060008581526008602052604090206127669085613aa1565b9050806127815761277685612683565b6127816102096116fb565b509392505050565b60008281526001602052604081206109e18184613412565b6dffffffffffffffffffffffffffff1690565b60701c6dffffffffffffffffffffffffffff1690565b60e01c90565b6000806127dc84611f64565b905060028160028111156127ec57fe5b1415612804576127fc8484613ac2565b9150506116f5565b600181600281111561281257fe5b1415612822576127fc8484613b13565b6127fc8484613b2b565b600080600061283a86611f64565b9050600087600281111561284a57fe5b14156128665761285c86828787613b43565b9250925050612892565b600187600281111561287457fe5b14156128865761285c86828787613bbe565b61285c86828787613c3a565b94509492505050565b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612908613c9d565b3060405160200161291d959493929190615df0565b60405160208183030381529060405280519060200120905090565b60601c90565b606080600061294c84611f64565b9050600281600281111561295c57fe5b14156129755761296b84613ca1565b925092505061299b565b600181600281111561298357fe5b14156129925761296b84613dd6565b61296b84613efd565b915091565b60606000825167ffffffffffffffff811180156129bc57600080fd5b506040519080825280602002602001820160405280156129e6578160200160208202803683370190505b5091506000905060005b825181101561151d576000848281518110612a0757fe5b60200260200101519050612a1a81613ff9565b848381518110612a2657fe5b602002602001018181525050612a4483612a3f836127ca565b614014565b9250506001016129f0565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205460ff1690565b6003546040517f9be2a88400000000000000000000000000000000000000000000000000000000815260009161010090046001600160a01b031690639be2a88490612ad090869086903090600401615d47565b60206040518083038186803b158015612ae857600080fd5b505afa158015612afc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f29190615478565b600080612b2d8686611a01565b9050612b468380612b3e5750848210155b61020161054b565b612b50818561402b565b9150818103612b6c878783612b6487613981565b60000361403a565b5050949350505050565b6000612b828484611a01565b90506000612b908284611945565b9050611d31858583612ba187613981565b61403a565b610e00846323b872dd60e01b858585604051602401611ec593929190615b77565b612bd6814710156101a361054b565b6000826001600160a01b031682604051612bef90610548565b60006040518083038185875af1925050503d8060008114612c2c576040519150601f19603f3d011682016040523d82523d6000602084013e612c31565b606091505b50509050610fa0816101a461054b565b6001600160a01b0382166000908152600260205260409020805460018101909155610fa0612c6f8483614095565b8361054b565b600080600080612c92866080015187602001518860400151613222565b92509250925060008087604001516001600160a01b031688602001516001600160a01b03161015612cc7575083905082612ccd565b50829050835b612cd9888884846141bb565b60408b015160208c01519199509294509092506001600160a01b03918216911610612d0d57612d0881836142d1565b612d17565b612d1782826142d1565b909255509295945050505050565b600080612d3a8460800151856020015161271b565b90506000612d508560800151866040015161271b565b9050612d5e858584846141bb565b6080880180516000908152600760208181526040808420828e01516001600160a01b03908116865290835281852098909855935183529081528282209a830151909516815298909352919096209590955550929392505050565b60808201516000908152600160209081526040822090840151829182918290612de290839061430c565b90506000612dfd88604001518461430c90919063ffffffff16565b9050811580612e0a575080155b15612e2757612e1c8860800151612683565b612e276102096116fb565b60001991820191016000612e3a8461432b565b905060608167ffffffffffffffff81118015612e5557600080fd5b50604051908082528060200260200182016040528015612e7f578160200160208202803683370190505b50600060a08c018190529091505b82811015612eff576000612ea1878361432f565b9050612eac81613ff9565b838381518110612eb857fe5b602002602001018181525050612ed58c60a00151612a3f836127ca565b60a08d015281861415612eea57809850612ef6565b84821415612ef6578097505b50600101612e8d565b506040517f01ec954a0000000000000000000000000000000000000000000000000000000081526001600160a01b038a16906301ec954a90612f4b908d90859089908990600401615e5b565b602060405180830381600087803b158015612f6557600080fd5b505af1158015612f79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f9d9190615968565b9750600080612fb58c600001518d606001518c612ff7565b9092509050612fc48983614345565b9850612fd08882614376565b9750612fdd87878b61438c565b612fe887868a61438c565b50505050505050505092915050565b6000808085600181111561300757fe5b141561301757508290508161301d565b50819050825b935093915050565b600082820261304984158061304257508385838161303f57fe5b04145b600361054b565b806130585760009150506116f5565b670de0b6b3a76400006000198201046001019150506116f5565b60006060836001600160a01b03168360405161308e9190615aea565b6000604051808303816000865af19150503d80600081146130cb576040519150601f19603f3d011682016040523d82523d6000602084013e6130d0565b606091505b509150915060008214156130e8573d6000803e3d6000fd5b610e0081516000148061310a57508180602001905181019061310a9190615478565b6101a261054b565b600061311e8383613aa1565b61316d57508154600180820184556000848152602080822090930180546001600160a01b0319166001600160a01b038616908117909155855490825282860190935260409020919091556116f5565b5060006116f5565b6001600160a01b03821660009081526002840160205260408120548061320257505082546040805180820182526001600160a01b03858116808352602080840187815260008781526001808c018452878220965187546001600160a01b03191696169590951786559051948401949094559482018089559083526002880190945291902091909155611876565b600019016000908152600180860160205260408220018390559050611876565b600080600080600061323487876143a4565b91509150600061324483836143d5565b60008a81526009602090815260408083208484526002019091528120805460018201549197509293509061327783613a8f565b80613286575061328682613a8f565b806132a757506132968c87613ac2565b80156132a757506132a78c86613ac2565b9050806132c2576132b78c612683565b6132c26102096116fb565b6132cc8383614408565b98506132d8838361442d565b975050505050505093509350939050565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161590565b6001600160a01b03811660009081526001830160205260408120548015613408578354600019808301919081019060009087908390811061334857fe5b60009182526020909120015487546001600160a01b039091169150819088908590811061337157fe5b600091825260208083209190910180546001600160a01b0319166001600160a01b039485161790559183168152600189810190925260409020908401905586548790806133ba57fe5b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b03881682526001898101909152604082209190915594506116f59350505050565b60009150506116f5565b60006116f28383610209614444565b6001600160a01b0381166000908152600283016020526040812054801561340857835460001990810160008181526001878101602090815260408084209587018452808420865481546001600160a01b03199081166001600160a01b0392831617835588860180549387019390935588548216875260028d018086528488209a909a5588541690975584905593895593871682529390925281205590506116f5565b606080825167ffffffffffffffff811180156134de57600080fd5b50604051908082528060200260200182016040528015613508578160200160208202803683370190505b50905060005b83518110156107ff576135268482815181106124ac57fe5b82828151811061353257fe5b6001600160a01b039092166020928302919091019091015260010161350e565b60608060606135608561293e565b9150915061357082518551611e12565b613580600083511161020f61054b565b60005b82518110156135da576135d285828151811061359b57fe5b60200260200101516001600160a01b03168483815181106135b857fe5b60200260200101516001600160a01b03161461020861054b565b600101613583565b50949350505050565b60608060608060006135f4866129a0565b9150915060006136038b612938565b905060008c600181111561361357fe5b146136b657806001600160a01b03166374f3b0098c8c8c8787613634614481565b8f604001516040518863ffffffff1660e01b815260040161365b9796959493929190615d66565b600060405180830381600087803b15801561367557600080fd5b505af1158015613689573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526136b19190810190615405565b61374f565b806001600160a01b031663d5c096c48c8c8c87876136d2614481565b8f604001516040518863ffffffff1660e01b81526004016136f99796959493929190615d66565b600060405180830381600087803b15801561371357600080fd5b505af1158015613727573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261374f9190810190615405565b80955081965050506137658751865186516144fb565b60008c600181111561377357fe5b1461378a576137858989898888614513565b613797565b6137978a8989888861465a565b955050505096509650969350505050565b60006137b485846143d5565b600087815260096020908152604080832084845260020190915290209091506137dd85846142d1565b9055505050505050565b60005b8251811015610e00578181815181106137ff57fe5b602002602001015160076000868152602001908152602001600020600085848151811061382857fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020556001016137ea565b6000828152600160205260408120905b8251811015610e00576138958184838151811061387d57fe5b60200260200101518461438c9092919063ffffffff16565b600101613864565b6060825167ffffffffffffffff811180156138b757600080fd5b506040519080825280602002602001820160405280156138e1578160200160208202803683370190505b50905060005b83518110156107ff57826139115783818151811061390157fe5b6020026020010151600003613926565b83818151811061391d57fe5b60200260200101515b82828151811061393257fe5b60209081029190910101526001016138e7565b60008084600181111561395457fe5b1461395f57816109e1565b509092915050565b60008084600181111561397657fe5b146107ff57826109e1565b600061226a7f800000000000000000000000000000000000000000000000000000000000000083106101a561054b565b60008282016116f28284128015906139c95750848212155b806139de57506000841280156139de57508482125b600061054b565b60008183036116f28284128015906139fd5750848213155b80613a125750600084128015613a1257508482135b600161054b565b6000818152600960205260408120805460018201546001600160a01b0391821692849290911690829081613a4d86856143d5565b6000818152600284016020526040902080546001820154919950919250613a748282614408565b9650613a80828261442d565b94505050505091939590929450565b6000613a9a826132e9565b1592915050565b6001600160a01b031660009081526001919091016020526040902054151590565b600082815260096020526040812080546001600160a01b0384811691161480613afa575060018101546001600160a01b038481169116145b80156109e1575050506001600160a01b03161515919050565b60008281526008602052604081206109e18184613aa1565b60008281526001602052604081206109e181846147d0565b6000806002856002811115613b5457fe5b1415613b6a57613b658685856147f1565b613b94565b6001856002811115613b7857fe5b1415613b8957613b658685856147ff565b613b9486858561480d565b8215613bae57613bae6001600160a01b0385163385611ea6565b5050600081900394909350915050565b6000806002856002811115613bcf57fe5b1415613be557613be086858561481b565b613c0f565b6001856002811115613bf357fe5b1415613c0457613be0868585614829565b613c0f868585614837565b8215613c2a57613c2a6001600160a01b038516333086612ba6565b5090946000869003945092505050565b6000806002856002811115613c4b57fe5b1415613c6357613c5c868585614845565b9050613c90565b6001856002811115613c7157fe5b1415613c8257613c5c868585614855565b613c8d868585614865565b90505b6000915094509492505050565b4690565b606080600080600080613cb387613a19565b92975090955093509150506001600160a01b0384161580613cdb57506001600160a01b038216155b15613d04575050604080516000808252602082019081528183019092529450925061299b915050565b60408051600280825260608201835290916020830190803683370190505095508386600081518110613d3257fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508186600181518110613d6057fe5b6001600160a01b03929092166020928302919091018201526040805160028082526060820183529092909190830190803683370190505094508285600081518110613da757fe5b6020026020010181815250508085600181518110613dc157fe5b60200260200101818152505050505050915091565b60008181526008602052604090206060908190613df28161432b565b67ffffffffffffffff81118015613e0857600080fd5b50604051908082528060200260200182016040528015613e32578160200160208202803683370190505b509250825167ffffffffffffffff81118015613e4d57600080fd5b50604051908082528060200260200182016040528015613e77578160200160208202803683370190505b50915060005b8351811015613ef6576000613e928383614875565b905080858381518110613ea157fe5b6001600160a01b03928316602091820292909201810191909152600088815260078252604080822093851682529290915220548451859084908110613ee257fe5b602090810291909101015250600101613e7d565b5050915091565b60008181526001602052604090206060908190613f198161432b565b67ffffffffffffffff81118015613f2f57600080fd5b50604051908082528060200260200182016040528015613f59578160200160208202803683370190505b509250825167ffffffffffffffff81118015613f7457600080fd5b50604051908082528060200260200182016040528015613f9e578160200160208202803683370190505b50915060005b8351811015613ef657613fb782826148a2565b858381518110613fc357fe5b60200260200101858481518110613fd657fe5b60209081029190910101919091526001600160a01b039091169052600101613fa4565b6000614004826127b4565b61400d836127a1565b0192915050565b60008183101561402457816116f2565b5090919050565b600081831061402457816116f2565b6001600160a01b038085166000818152600b602090815260408083209488168084529490915290819020859055517f18e1ea4139e68413d7d08aa752e71568e36b2c5bf940893314c2c5b01eaa0c42906119d0908590615d3e565b6000806140a06148c6565b9050428110156140b45760009150506116f5565b60006140be6148d2565b9050806140d0576000925050506116f5565b6000816140db6149e3565b80516020918201206040516140f7939233918a91899101615dc4565b604051602081830303815290604052805190602001209050600061411a82614a32565b90506000806000614129614a4e565b9250925092506000600185858585604051600081526020016040526040516141549493929190615e1c565b6020604051602081039080840390855afa158015614176573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906141ac57508a6001600160a01b0316816001600160a01b0316145b9b9a5050505050505050505050565b6000806000806141ca86613ff9565b905060006141d786613ff9565b90506141ee6141e5886127ca565b612a3f886127ca565b60a08a01526040517f9d2c110c0000000000000000000000000000000000000000000000000000000081526001600160a01b03891690639d2c110c9061423c908c9086908690600401615e94565b602060405180830381600087803b15801561425657600080fd5b505af115801561426a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061428e9190615968565b92506000806142a68b600001518c6060015187612ff7565b90925090506142b58983614345565b96506142c18882614376565b9550505050509450945094915050565b6000806142e96142e0856127ca565b612a3f856127ca565b90506109e16142f7856127a1565b614300856127a1565b8363ffffffff16614a75565b6001600160a01b03166000908152600291909101602052604090205490565b5490565b6000908152600191820160205260409020015490565b60008061435b83614355866127a1565b90611945565b90506000614368856127b4565b9050436112a6838383614a83565b60008061435b83614386866127a1565b90614abc565b60009182526001928301602052604090912090910155565b600080826001600160a01b0316846001600160a01b0316106143c75782846143ca565b83835b915091509250929050565b600082826040516020016143ea929190615b06565b60405160208183030381529060405280519060200120905092915050565b60006116f2614416846127a1565b61441f846127a1565b614428866127ca565b614a83565b60006116f261443b846127b4565b61441f846127b4565b6001600160a01b038216600090815260028401602052604081205461446b8115158461054b565b614478856001830361432f565b95945050505050565b600061448b6113af565b6001600160a01b03166355c676286040518163ffffffff1660e01b815260040160206040518083038186803b1580156144c357600080fd5b505afa1580156144d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ce9190615968565b610fa0828414801561450c57508183145b606761054b565b6060835167ffffffffffffffff8111801561452d57600080fd5b50604051908082528060200260200182016040528015614557578160200160208202803683370190505b50905060005b85515181101561465057600084828151811061457557fe5b602002602001015190506145a58760200151838151811061459257fe5b60200260200101518210156101f961054b565b6000876000015183815181106145b757fe5b602002602001015190506145d181838b8b60600151611d38565b60008584815181106145df57fe5b602002602001015190506145fb6145f583611b41565b82611f11565b61462a6146088483611945565b89868151811061461457fe5b602002602001015161437690919063ffffffff16565b85858151811061463657fe5b60200260200101818152505050505080600101905061455d565b5095945050505050565b60606000845167ffffffffffffffff8111801561467657600080fd5b506040519080825280602002602001820160405280156146a0578160200160208202803683370190505b50915060005b8651518110156147c65760008582815181106146be57fe5b602002602001015190506146ee886020015183815181106146db57fe5b60200260200101518211156101fa61054b565b60008860000151838151811061470057fe5b6020026020010151905061471a81838c8c60600151611c5a565b61472381611938565b15614735576147328483611945565b93505b600086848151811061474357fe5b602002602001015190506147596145f583611b41565b80831015614778576147738382038a868151811061461457fe5b6147a0565b6147a08184038a868151811061478a57fe5b602002602001015161434590919063ffffffff16565b8685815181106147ac57fe5b6020026020010181815250505050508060010190506146a6565b50614650816119de565b6001600160a01b031660009081526002919091016020526040902054151590565b610e008383614ad284614b0d565b610e008383614ad284614bb8565b610e008383614ad284614c13565b610e008383614c6284614b0d565b610e008383614c6284614bb8565b610e008383614c6284614c13565b60006109e18484614c8385614b0d565b60006109e18484614c8385614bb8565b60006109e18484614c8385614c13565b600082600001828154811061488657fe5b6000918252602090912001546001600160a01b03169392505050565b600090815260019182016020526040902080549101546001600160a01b0390911691565b60006112ce6000614c9d565b6000803560e01c8063b95cac28811461491a57638bdb39138114614942576352bbbe29811461496a5763945bcec981146149925763fa6e671d81146149ba57600092506149de565b7f3f7b71252bd19113ff48c19c6e004a9bcfcca320a0d74d58e85877cbd7dcae5892506149de565b7f8bbc57f66ea936902f50a71ce12b92c43f3c5340bb40c27c4e90ab84eeae335392506149de565b7fe192dcbc143b1e244ad73b813fd3c097b832ad260a157340b4e5e5beda067abe92506149de565b7f9bfc43a4d98313c6766986ffd7c916c7481566d9f224c6819af0a53388aced3a92506149de565b7fa3f865aa351e51cfeb40f5178d1564bb629fe9030b83caf6361d1baaf5b90b5a92505b505090565b60606000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505050608010156105485760803603815290565b6000614a3c61289b565b8260405160200161112e929190615b2d565b6000806000614a5d6020614c9d565b9250614a696040614c9d565b91506108416060614c9d565b60e01b60709190911b010190565b6000838301614ab1858210801590614aa957506e01000000000000000000000000000082105b61020e61054b565b614478858585614a75565b6000614acc83831115600161054b565b50900390565b600080614ae283614386866127a1565b90506000614af384614355876127b4565b90506000614b00866127ca565b90506112a6838383614a83565b6000806000806000614b1e89613a19565b9450509350935093506000836001600160a01b0316896001600160a01b03161415614b69576000614b5384898b63ffffffff16565b9050614b5f8185614ca7565b9093509050614b8b565b6000614b7983898b63ffffffff16565b9050614b858184614ca7565b90925090505b614b9583836142d1565b8555614ba18383614cc3565b600190950194909455509192505050949350505050565b600080614bc5868661271b565b90506000614bd782858763ffffffff16565b60008881526007602090815260408083206001600160a01b038b16845290915290208190559050614c088183614ca7565b979650505050505050565b600084815260016020526040812081614c2c8287613412565b90506000614c3e82868863ffffffff16565b9050614c4b838883613175565b50614c568183614ca7565b98975050505050505050565b600080614c7283614355866127a1565b90506000614af384614386876127b4565b600080614c8f846127a1565b905043614478828583614a83565b3601607f19013590565b6000614cb2826127b4565b614cbb846127b4565b039392505050565b60006116f2614cd1846127b4565b614cda846127b4565b6000614a75565b60408051610120810190915280600081526000602082018190526040820181905260608083018290526080830182905260a0830182905260c0830182905260e08301919091526101009091015290565b604080516080810190915280600081526000602082018190526040820181905260609091015290565b60405180608001604052806060815260200160608152602001606081526020016000151581525090565b6040518060a0016040528060008019168152602001600081526020016000815260200160008152602001606081525090565b80356116f581615f5a565b600082601f830112614dd1578081fd5b8135614de4614ddf82615f04565b615edd565b818152915060208083019084810181840286018201871015614e0557600080fd5b60005b84811015614e2d578135614e1b81615f5a565b84529282019290820190600101614e08565b505050505092915050565b600082601f830112614e48578081fd5b8135614e56614ddf82615f04565b818152915060208083019084810160005b84811015614e2d578135870160a080601f19838c03011215614e8857600080fd5b614e9181615edd565b85830135815260408084013587830152606080850135828401526080915081850135818401525082840135925067ffffffffffffffff831115614ed357600080fd5b614ee18c8885870101614fc0565b90820152865250509282019290820190600101614e67565b600082601f830112614f09578081fd5b8135614f17614ddf82615f04565b818152915060208083019084810181840286018201871015614f3857600080fd5b60005b84811015614e2d57813584529282019290820190600101614f3b565b600082601f830112614f67578081fd5b8151614f75614ddf82615f04565b818152915060208083019084810181840286018201871015614f9657600080fd5b60005b84811015614e2d57815184529282019290820190600101614f99565b80356116f581615f6f565b600082601f830112614fd0578081fd5b813567ffffffffffffffff811115614fe6578182fd5b614ff9601f8201601f1916602001615edd565b915080825283602082850101111561501057600080fd5b8060208401602084013760009082016020015292915050565b80356116f581615f7d565b8035600281106116f557600080fd5b8035600481106116f557600080fd5b600060808284031215615063578081fd5b61506d6080615edd565b9050813567ffffffffffffffff8082111561508757600080fd5b61509385838601614dc1565b835260208401359150808211156150a957600080fd5b6150b585838601614ef9565b602084015260408401359150808211156150ce57600080fd5b506150db84828501614fc0565b6040830152506150ee8360608401614fb5565b606082015292915050565b60006080828403121561510a578081fd5b6151146080615edd565b9050813561512181615f5a565b8152602082013561513181615f6f565b6020820152604082013561514481615f5a565b604082015260608201356150ee81615f6f565b600060208284031215615168578081fd5b81356116f281615f5a565b60008060408385031215615185578081fd5b823561519081615f5a565b915060208301356151a081615f5a565b809150509250929050565b6000806000606084860312156151bf578081fd5b83356151ca81615f5a565b925060208401356151da81615f5a565b915060408401356151ea81615f6f565b809150509250925092565b60008060408385031215615207578182fd5b823561521281615f5a565b9150602083013567ffffffffffffffff81111561522d578182fd5b61523985828601614dc1565b9150509250929050565b60006020808385031215615255578182fd5b823567ffffffffffffffff81111561526b578283fd5b8301601f8101851361527b578283fd5b8035615289614ddf82615f04565b818152838101908385016080808502860187018a10156152a7578788fd5b8795505b848610156153105780828b0312156152c1578788fd5b6152ca81615edd565b6152d48b84615029565b8152878301358882015260406152ec8c828601614db6565b908201526060838101359082015284526001959095019492860192908101906152ab565b509098975050505050505050565b60006020808385031215615330578182fd5b823567ffffffffffffffff811115615346578283fd5b8301601f81018513615356578283fd5b8035615364614ddf82615f04565b8181528381019083850160a0808502860187018a1015615382578788fd5b8795505b848610156153105780828b03121561539c578788fd5b6153a581615edd565b6153af8b84615043565b81526153bd8b898501614db6565b818901526040838101359082015260606153d98c828601614db6565b9082015260806153eb8c858301614db6565b908201528452600195909501949286019290810190615386565b60008060408385031215615417578182fd5b825167ffffffffffffffff8082111561542e578384fd5b61543a86838701614f57565b9350602085015191508082111561544f578283fd5b5061523985828601614f57565b60006020828403121561546d578081fd5b81356116f281615f6f565b600060208284031215615489578081fd5b81516116f281615f6f565b6000602082840312156154a5578081fd5b5035919050565b600080600080608085870312156154c1578182fd5b8435935060208501356154d381615f5a565b925060408501356154e381615f5a565b9150606085013567ffffffffffffffff8111156154fe578182fd5b61550a87828801615052565b91505092959194509250565b60008060408385031215615528578182fd5b82359150602083013567ffffffffffffffff81111561522d578182fd5b600080600060608486031215615559578081fd5b8335925060208085013567ffffffffffffffff80821115615578578384fd5b61558488838901614dc1565b94506040870135915080821115615599578384fd5b508501601f810187136155aa578283fd5b80356155b8614ddf82615f04565b81815283810190838501858402850186018b10156155d4578687fd5b8694505b838510156155ff5780356155eb81615f5a565b8352600194909401939185019185016155d8565b5080955050505050509250925092565b60008060408385031215615621578182fd5b8235915060208301356151a081615f5a565b600060208284031215615644578081fd5b81356001600160e01b0319811681146116f2578182fd5b60008060008060808587031215615670578182fd5b843561567b81615f5a565b9350602085013567ffffffffffffffff80821115615697578384fd5b6156a388838901614dc1565b945060408701359150808211156156b8578384fd5b6156c488838901614ef9565b935060608701359150808211156156d9578283fd5b5061550a87828801614fc0565b6000602082840312156156f7578081fd5b81356116f281615f7d565b60008060008060e08587031215615717578182fd5b6157218686615034565b9350602085013567ffffffffffffffff8082111561573d578384fd5b61574988838901614e38565b9450604087013591508082111561575e578384fd5b5061576b87828801614dc1565b92505061577b86606087016150f9565b905092959194509250565b600080600080600080610120878903121561579f578384fd5b6157a98888615034565b955060208088013567ffffffffffffffff808211156157c6578687fd5b6157d28b838c01614e38565b975060408a01359150808211156157e7578687fd5b6157f38b838c01614dc1565b96506158028b60608c016150f9565b955060e08a0135915080821115615817578485fd5b508801601f81018a13615828578384fd5b8035615836614ddf82615f04565b81815283810190838501858402850186018e1015615852578788fd5b8794505b83851015615874578035835260019490940193918501918501615856565b50809650505050505061010087013590509295509295509295565b60008060008060e085870312156158a4578182fd5b843567ffffffffffffffff808211156158bb578384fd5b9086019060c082890312156158ce578384fd5b6158d860c0615edd565b823581526158e98960208501615034565b602082015260408301356158fc81615f5a565b604082015261590e8960608501614db6565b60608201526080830135608082015260a08301358281111561592e578586fd5b61593a8a828601614fc0565b60a08301525080965050505061595386602087016150f9565b939693955050505060a08201359160c0013590565b600060208284031215615979578081fd5b5051919050565b6001600160a01b03169052565b6000815180845260208085019450808401835b838110156159c55781516001600160a01b0316875295820195908201906001016159a0565b509495945050505050565b6000815180845260208085019450808401835b838110156159c5578151875295820195908201906001016159e3565b60008151808452615a17816020860160208601615f24565b601f01601f19169290920160200192915050565b6000610120825160028110615a3c57fe5b808552506020830151615a526020860182615980565b506040830151615a656040860182615980565b50606083015160608501526080830151608085015260a083015160a085015260c0830151615a9660c0860182615980565b5060e0830151615aa960e0860182615980565b506101008084015182828701526112a6838701826159ff565b9182526001600160e01b031916602082015260240190565b6000828483379101908152919050565b60008251615afc818460208701615f24565b9190910192915050565b6bffffffffffffffffffffffff19606093841b811682529190921b16601482015260280190565b7f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b038316815260408101615bb483615f50565b8260208301529392505050565b6001600160a01b03929092168252602082015260400190565b6000602082526116f2602083018461598d565b600060408252615c00604083018561598d565b828103602084810191909152845180835285820192820190845b81811015615c3f5784516001600160a01b031683529383019391830191600101615c1a565b5090979650505050505050565b600060608252615c5f606083018661598d565b8281036020840152615c7181866159d0565b905082810360408401526112a681856159d0565b600060808252615c98608083018761598d565b8281036020840152615caa81876159d0565b90508281036040840152615cbe81866159d0565b90508281036060840152614c0881856159ff565b600060608252615ce5606083018661598d565b8281036020840152615cf781866159d0565b915050826040830152949350505050565b6000602082526116f260208301846159d0565b901515815260200190565b92151583526020830191909152604082015260600190565b90815260200190565b9283526001600160a01b03918216602084015216604082015260600190565b60008882526001600160a01b03808916602084015280881660408401525060e06060830152615d9860e08301876159d0565b8560808401528460a084015282810360c0840152615db681856159ff565b9a9950505050505050505050565b94855260208501939093526001600160a01b039190911660408401526060830152608082015260a00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b60208101615e4783615f50565b91905290565b918252602082015260400190565b600060808252615e6e6080830187615a2b565b8281036020840152615e8081876159d0565b604084019590955250506060015292915050565b600060608252615ea76060830186615a2b565b60208301949094525060400152919050565b938452602084019290925260408301526001600160a01b0316606082015260800190565b60405181810167ffffffffffffffff81118282101715615efc57600080fd5b604052919050565b600067ffffffffffffffff821115615f1a578081fd5b5060209081020190565b60005b83811015615f3f578181015183820152602001615f27565b83811115610e005750506000910152565b6003811061057e57fe5b6001600160a01b038116811461057e57600080fd5b801515811461057e57600080fd5b6003811061057e57600080fdfea2646970667358221220201e4f926e390fed8dd5318c58846af735c2bebc61b80693ae936a5fe76dcf1464736f6c6343000701003360c060405234801561001057600080fd5b50604051610be6380380610be683398101604081905261002f9161004d565b30608052600160005560601b6001600160601b03191660a05261007b565b60006020828403121561005e578081fd5b81516001600160a01b0381168114610074578182fd5b9392505050565b60805160a05160601c610b406100a66000398061041352806105495250806102a75250610b406000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063851c1bb311610076578063d877845c1161005b578063d877845c14610129578063e42abf3514610131578063fbfa77cf14610151576100a3565b8063851c1bb314610101578063aaabadc514610114576100a3565b806338e9922e146100a857806355c67628146100bd5780636b6b9f69146100db5780636daefab6146100ee575b600080fd5b6100bb6100b636600461099c565b610159565b005b6100c56101b8565b6040516100d29190610aa6565b60405180910390f35b6100bb6100e936600461099c565b6101be565b6100bb6100fc3660046107d1565b610211565b6100c561010f366004610924565b6102a3565b61011c6102f5565b6040516100d29190610a35565b6100c5610304565b61014461013f366004610852565b61030a565b6040516100d29190610a62565b61011c610411565b610161610435565b6101786706f05b59d3b2000082111561025861047e565b60018190556040517fa9ba3ffe0b6c366b81232caab38605a0699ad5398d6cce76f91ee809e322dafc906101ad908390610aa6565b60405180910390a150565b60015490565b6101c6610435565b6101dc662386f26fc1000082111561025961047e565b60028190556040517f5a0b7386237e7f07fa741efc64e59c9387d2cccafec760efed4d53387f20e19a906101ad908390610aa6565b610219610490565b610221610435565b61022b84836104a9565b60005b8481101561029357600086868381811061024457fe5b90506020020160208101906102599190610980565b9050600085858481811061026957fe5b6020029190910135915061028990506001600160a01b03831685836104b6565b505060010161022e565b5061029c61053e565b5050505050565b60007f0000000000000000000000000000000000000000000000000000000000000000826040516020016102d89291906109cc565b604051602081830303815290604052805190602001209050919050565b60006102ff610545565b905090565b60025490565b6060815167ffffffffffffffff8111801561032457600080fd5b5060405190808252806020026020018201604052801561034e578160200160208202803683370190505b50905060005b825181101561040b5782818151811061036957fe5b60200260200101516001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161039c9190610a35565b60206040518083038186803b1580156103b457600080fd5b505afa1580156103c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ec91906109b4565b8282815181106103f857fe5b6020908102919091010152600101610354565b50919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60006104646000357fffffffff00000000000000000000000000000000000000000000000000000000166102a3565b905061047b61047382336105d8565b61019161047e565b50565b8161048c5761048c8161066a565b5050565b6104a26002600054141561019061047e565b6002600055565b61048c818314606761047e565b6105398363a9059cbb60e01b84846040516024016104d5929190610a49565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526106d7565b505050565b6001600055565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663aaabadc56040518163ffffffff1660e01b815260040160206040518083038186803b1580156105a057600080fd5b505afa1580156105b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ff9190610964565b60006105e2610545565b6001600160a01b0316639be2a8848484306040518463ffffffff1660e01b815260040161061193929190610aaf565b60206040518083038186803b15801561062957600080fd5b505afa15801561063d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066191906108fd565b90505b92915050565b7f08c379a0000000000000000000000000000000000000000000000000000000006000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b60006060836001600160a01b0316836040516106f391906109fc565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150600082141561074d573d6000803e3d6000fd5b61077781516000148061076f57508180602001905181019061076f91906108fd565b6101a261047e565b50505050565b60008083601f84011261078e578182fd5b50813567ffffffffffffffff8111156107a5578182fd5b60208301915083602080830285010111156107bf57600080fd5b9250929050565b803561066481610af5565b6000806000806000606086880312156107e8578081fd5b853567ffffffffffffffff808211156107ff578283fd5b61080b89838a0161077d565b90975095506020880135915080821115610823578283fd5b506108308882890161077d565b909450925050604086013561084481610af5565b809150509295509295909350565b60006020808385031215610864578182fd5b823567ffffffffffffffff8082111561087b578384fd5b818501915085601f83011261088e578384fd5b81358181111561089c578485fd5b83810291506108ac848301610ace565b8181528481019084860184860187018a10156108c6578788fd5b8795505b838610156108f0576108dc8a826107c6565b8352600195909501949186019186016108ca565b5098975050505050505050565b60006020828403121561090e578081fd5b8151801515811461091d578182fd5b9392505050565b600060208284031215610935578081fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461091d578182fd5b600060208284031215610975578081fd5b815161091d81610af5565b600060208284031215610991578081fd5b813561091d81610af5565b6000602082840312156109ad578081fd5b5035919050565b6000602082840312156109c5578081fd5b5051919050565b9182527fffffffff0000000000000000000000000000000000000000000000000000000016602082015260240190565b60008251815b81811015610a1c5760208186018101518583015201610a02565b81811115610a2a5782828501525b509190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015610a9a57835183529284019291840191600101610a7e565b50909695505050505050565b90815260200190565b9283526001600160a01b03918216602084015216604082015260600190565b60405181810167ffffffffffffffff81118282101715610aed57600080fd5b604052919050565b6001600160a01b038116811461047b57600080fdfea2646970667358221220be72bdf8e7a3c38606c5f954fbe2d77798347aaa1cfb76fe77ec2f6c245d24bc64736f6c63430007010033", + "deployedBytecode": "", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/external/abi/balancer/v2/WeightedPoolFactory.json b/external/abi/balancer/v2/WeightedPoolFactory.json new file mode 100644 index 000000000..df10f53b6 --- /dev/null +++ b/external/abi/balancer/v2/WeightedPoolFactory.json @@ -0,0 +1,8 @@ +{ + "contractName": "BVault", + "abi": [{"inputs":[{"internalType":"contract IVault","name":"vault","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"}],"name":"PoolCreated","type":"event"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"weights","type":"uint256[]"},{"internalType":"uint256","name":"swapFeePercentage","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"create","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getPauseConfiguration","outputs":[{"internalType":"uint256","name":"pauseWindowDuration","type":"uint256"},{"internalType":"uint256","name":"bufferPeriodDuration","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVault","outputs":[{"internalType":"contract IVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"name":"isPoolFromFactory","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}], + "bytecode": "60c060405234801561001057600080fd5b5060405161604138038061604183398101604081905261002f9161004d565b60601b6001600160601b0319166080526276a700420160a05261007b565b60006020828403121561005e578081fd5b81516001600160a01b0381168114610074578182fd5b9392505050565b60805160601c60a051615f9c6100a56000398060d6528061010052508061015c5250615f9c6000f3fe60806040523480156200001157600080fd5b5060043610620000525760003560e01c80632da47c4014620000575780636634b753146200007a5780638d928af814620000a0578063fbce039314620000b9575b600080fd5b62000061620000d0565b6040516200007192919062000634565b60405180910390f35b620000916200008b366004620003c0565b6200013c565b60405162000071919062000562565b620000aa6200015a565b6040516200007191906200054e565b620000aa620000ca366004620003e6565b6200017e565b600080427f00000000000000000000000000000000000000000000000000000000000000008110156200012e57807f000000000000000000000000000000000000000000000000000000000000000003925062278d00915062000137565b60009250600091505b509091565b6001600160a01b031660009081526020819052604090205460ff1690565b7f000000000000000000000000000000000000000000000000000000000000000090565b60008060006200018d620000d0565b9150915060006200019d6200015a565b8a8a8a8a8a88888c604051620001b3906200024b565b620001c7999897969594939291906200056d565b604051809103906000f080158015620001e4573d6000803e3d6000fd5b509050620001f281620001ff565b9998505050505050505050565b6001600160a01b038116600081815260208190526040808220805460ff19166001179055517f83a48fbcfc991335314e74d0496aab6a1987e992ddc85dddbcc4d6dd6ef2e9fc9190a250565b6158b680620006b183390190565b8035620002668162000697565b92915050565b600082601f8301126200027d578081fd5b8135620002946200028e826200066a565b62000642565b818152915060208083019084810181840286018201871015620002b657600080fd5b60005b84811015620002e2578135620002cf8162000697565b84529282019290820190600101620002b9565b505050505092915050565b600082601f830112620002fe578081fd5b81356200030f6200028e826200066a565b8181529150602080830190848101818402860182018710156200033157600080fd5b60005b84811015620002e25781358452928201929082019060010162000334565b600082601f83011262000363578081fd5b813567ffffffffffffffff8111156200037a578182fd5b6200038f601f8201601f191660200162000642565b9150808252836020828501011115620003a757600080fd5b8060208401602084013760009082016020015292915050565b600060208284031215620003d2578081fd5b8135620003df8162000697565b9392505050565b60008060008060008060c08789031215620003ff578182fd5b863567ffffffffffffffff8082111562000417578384fd5b620004258a838b0162000352565b975060208901359150808211156200043b578384fd5b620004498a838b0162000352565b965060408901359150808211156200045f578384fd5b6200046d8a838b016200026c565b9550606089013591508082111562000483578384fd5b506200049289828a01620002ed565b93505060808701359150620004ab8860a0890162000259565b90509295509295509295565b6001600160a01b03169052565b6000815180845260208085019450808401835b83811015620004f557815187529582019590820190600101620004d7565b509495945050505050565b60008151808452815b81811015620005275760208185018101518683018201520162000509565b81811115620005395782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b901515815260200190565b60006101206001600160a01b038c16835260208181850152620005938285018d62000500565b91508382036040850152620005a9828c62000500565b84810360608601528a51808252828c01935090820190845b81811015620005e957620005d685516200068b565b83529383019391830191600101620005c1565b50508481036080860152620005ff818b620004c4565b93505050508560a08301528460c08301528360e083015262000626610100830184620004b7565b9a9950505050505050505050565b918252602082015260400190565b60405181810167ffffffffffffffff811182821017156200066257600080fd5b604052919050565b600067ffffffffffffffff82111562000681578081fd5b5060209081020190565b6001600160a01b031690565b6001600160a01b0381168114620006ad57600080fd5b5056fe6105006040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9610120523480156200003757600080fd5b50604051620058b6380380620058b68339810160408190526200005a9162000cf2565b88888888878787878785516002146200007557600162000078565b60025b6040805180820190915260018152603160f81b6020808301918252336080526001600160601b0319606087901b1660a0528b51908c0190812060c0529151902060e0527f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6101005289518a918a918a918a918a918a918a91849184918a918a9162000107916003919062000abb565b5080516200011d90600490602084019062000abb565b50620001359150506276a70083111561019462000865565b6200014962278d0082111561019562000865565b42909101610140819052016101605284516200016b906002111560c862000865565b6200018360088651111560c96200086560201b60201c565b62000199856200087a60201b62000d571760201c565b620001a48462000886565b6040516309b2760f60e01b81526000906001600160a01b038b16906309b2760f90620001d5908c9060040162000eab565b602060405180830381600087803b158015620001f057600080fd5b505af115801562000205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022b919062000cd9565b9050896001600160a01b03166366a9c7d2828889516001600160401b03811180156200025657600080fd5b5060405190808252806020026020018201604052801562000281578160200160208202803683370190505b506040518463ffffffff1660e01b8152600401620002a29392919062000e0f565b600060405180830381600087803b158015620002bd57600080fd5b505af1158015620002d2573d6000803e3d6000fd5b5050506001600160601b031960608c901b1661018052506101a081905285516101c0528551620003045760006200031b565b856000815181106200031257fe5b60200260200101515b60601b6001600160601b0319166101e05285516001106200033e57600062000355565b856001815181106200034c57fe5b60200260200101515b60601b6001600160601b031916610200528551600210620003785760006200038f565b856002815181106200038657fe5b60200260200101515b60601b6001600160601b031916610220528551600310620003b2576000620003c9565b85600381518110620003c057fe5b60200260200101515b60601b6001600160601b031916610240528551600410620003ec57600062000403565b85600481518110620003fa57fe5b60200260200101515b60601b6001600160601b031916610260528551600510620004265760006200043d565b856005815181106200043457fe5b60200260200101515b60601b6001600160601b0319166102805285516006106200046057600062000477565b856006815181106200046e57fe5b60200260200101515b60601b6001600160601b0319166102a05285516007106200049a576000620004b1565b85600781518110620004a857fe5b60200260200101515b60601b6001600160601b0319166102c0528551620004d1576000620004f7565b620004f786600081518110620004e357fe5b6020026020010151620008f560201b60201c565b6102e05285516001106200050d5760006200051f565b6200051f86600181518110620004e357fe5b6103005285516002106200053557600062000547565b6200054786600281518110620004e357fe5b6103205285516003106200055d5760006200056f565b6200056f86600381518110620004e357fe5b6103405285516004106200058557600062000597565b6200059786600481518110620004e357fe5b610360528551600510620005ad576000620005bf565b620005bf86600581518110620004e357fe5b610380528551600610620005d5576000620005e7565b620005e786600681518110620004e357fe5b6103a0528551600710620005fd5760006200060f565b6200060f86600781518110620004e357fe5b6103c08181525050505050505050505050505050505050505050600086519050620006478187516200099760201b62000d651760201c565b6000806000805b848160ff161015620006cd5760008a8260ff16815181106200066c57fe5b6020026020010151905062000694662386f26fc1000082101561012e6200086560201b60201c565b620006ae8186620009a660201b62000d721790919060201c565b945082811115620006c3578160ff1693508092505b506001016200064e565b50620006e6670de0b6b3a7640000841461013462000865565b6103e08290528851620006fb57600062000712565b886000815181106200070957fe5b60200260200101515b610400528851600110620007285760006200073f565b886001815181106200073657fe5b60200260200101515b610420528851600210620007555760006200076c565b886002815181106200076357fe5b60200260200101515b6104405288516003106200078257600062000799565b886003815181106200079057fe5b60200260200101515b610460528851600410620007af576000620007c6565b88600481518110620007bd57fe5b60200260200101515b610480528851600510620007dc576000620007f3565b88600581518110620007ea57fe5b60200260200101515b6104a05288516006106200080957600062000820565b886006815181106200081757fe5b60200260200101515b6104c0528851600710620008365760006200084d565b886007815181106200084457fe5b60200260200101515b6104e0525062000f329b505050505050505050505050565b8162000876576200087681620009c3565b5050565b80620008768162000a16565b6200089b64e8d4a5100082101560cb62000865565b620008b367016345785d8a000082111560ca62000865565b60078190556040517fa9ba3ffe0b6c366b81232caab38605a0699ad5398d6cce76f91ee809e322dafc90620008ea90839062000ec0565b60405180910390a150565b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156200093257600080fd5b505afa15801562000947573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200096d919062000dec565b60ff16905060006200098c60128362000aa360201b62000d841760201c565b600a0a949350505050565b62000876828214606762000865565b6000828201620009ba848210158362000865565b90505b92915050565b62461bcd60e51b6000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b60028151101562000a275762000aa0565b60008160008151811062000a3757fe5b602002602001015190506000600190505b825181101562000a9d57600083828151811062000a6157fe5b6020026020010151905062000a92816001600160a01b0316846001600160a01b03161060656200086560201b60201c565b915060010162000a48565b50505b50565b600062000ab583831115600162000865565b50900390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1062000afe57805160ff191683800117855562000b2e565b8280016001018555821562000b2e579182015b8281111562000b2e57825182559160200191906001019062000b11565b5062000b3c92915062000b40565b5090565b5b8082111562000b3c576000815560010162000b41565b8051620009bd8162000f1c565b600082601f83011262000b75578081fd5b815162000b8c62000b868262000ef0565b62000ec9565b81815291506020808301908481018184028601820187101562000bae57600080fd5b60005b8481101562000bda57815162000bc78162000f1c565b8452928201929082019060010162000bb1565b505050505092915050565b600082601f83011262000bf6578081fd5b815162000c0762000b868262000ef0565b81815291506020808301908481018184028601820187101562000c2957600080fd5b60005b8481101562000bda5781518452928201929082019060010162000c2c565b600082601f83011262000c5b578081fd5b81516001600160401b0381111562000c71578182fd5b602062000c87601f8301601f1916820162000ec9565b9250818352848183860101111562000c9e57600080fd5b60005b8281101562000cbe57848101820151848201830152810162000ca1565b8281111562000cd05760008284860101525b50505092915050565b60006020828403121562000ceb578081fd5b5051919050565b60008060008060008060008060006101208a8c03121562000d11578485fd5b62000d1d8b8b62000b57565b60208b01519099506001600160401b038082111562000d3a578687fd5b62000d488d838e0162000c4a565b995060408c015191508082111562000d5e578687fd5b62000d6c8d838e0162000c4a565b985060608c015191508082111562000d82578687fd5b62000d908d838e0162000b64565b975060808c015191508082111562000da6578687fd5b5062000db58c828d0162000be5565b95505060a08a0151935060c08a0151925060e08a0151915062000ddd8b6101008c0162000b57565b90509295985092959850929598565b60006020828403121562000dfe578081fd5b815160ff81168114620009ba578182fd5b60006060820185835260206060818501528186518084526080860191508288019350845b8181101562000e5b5762000e48855162000f10565b8352938301939183019160010162000e33565b505084810360408601528551808252908201925081860190845b8181101562000e9d5762000e8a835162000f10565b8552938301939183019160010162000e75565b509298975050505050505050565b602081016003831062000eba57fe5b91905290565b90815260200190565b6040518181016001600160401b038111828210171562000ee857600080fd5b604052919050565b60006001600160401b0382111562000f06578081fd5b5060209081020190565b6001600160a01b031690565b6001600160a01b038116811462000aa057600080fd5b60805160a05160601c60c05160e051610100516101205161014051610160516101805160601c6101a0516101c0516101e05160601c6102005160601c6102205160601c6102405160601c6102605160601c6102805160601c6102a05160601c6102c05160601c6102e05161030051610320516103405161036051610380516103a0516103c0516103e05161040051610420516104405161046051610480516104a0516104c0516104e05161476e6200114860003980611ec55280612857525080611e8252806127f6525080611e3f5280612795525080611dfc5280612734525080611db952806126d3525080611d765280612672525080611d335280612611525080611cf052806125b05250806122d0528061230452806123405250806116285280611b1e5250806115e55280611abd5250806115a25280611a5c52508061155f52806119fb52508061151c528061199a5250806114d9528061193952508061149652806118d85250806114455280611877525080611ae3528061281c525080611a8252806127bb525080611a21528061275a5250806119c052806126f952508061195f52806126985250806118fe528061263752508061189d52806125d652508061183c52806125755250806111025250806105d7525080610835525080610ef1525080610ecd525080610ab5525080610ff452508061103652508061101552508061081152508061079b525061476e6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80637ecebe001161010f578063a9059cbb116100a2578063d5c096c411610071578063d5c096c4146103e6578063d73dd623146103f9578063dd62ed3e1461040c578063f89f27ed1461041f576101f0565b8063a9059cbb146103b0578063aaabadc5146103c3578063c0ff1a15146103cb578063d505accf146103d3576101f0565b80638d928af8116100de5780638d928af81461038557806395d89b411461038d5780639b02cdde146103955780639d2c110c1461039d576101f0565b80637ecebe0014610337578063851c1bb31461034a57806387ec68171461035d578063893d20e814610370576101f0565b806338e9922e11610187578063661884631161015657806366188463146102e8578063679aefce146102fb57806370a082311461030357806374f3b00914610316576101f0565b806338e9922e146102a457806338fff2d0146102b757806355c67628146102bf5780636028bfd4146102c7576101f0565b80631c0de051116101c35780631c0de0511461025d57806323b872dd14610274578063313ce567146102875780633644e5151461029c576101f0565b806306fdde03146101f5578063095ea7b31461021357806316c38b3c1461023357806318160ddd14610248575b600080fd5b6101fd610434565b60405161020a9190614647565b60405180910390f35b61022661022136600461401c565b6104cb565b60405161020a919061457e565b610246610241366004614113565b6104e2565b005b6102506104f6565b60405161020a91906145a1565b6102656104fc565b60405161020a93929190614589565b610226610282366004613f67565b610525565b61028f6105a8565b60405161020a91906146b3565b6102506105ad565b6102466102b236600461449d565b6105bc565b6102506105d5565b6102506105f9565b6102da6102d536600461414b565b6105ff565b60405161020a92919061469a565b6102266102f636600461401c565b610636565b610250610690565b610250610311366004613f13565b6106bb565b61032961032436600461414b565b6106da565b60405161020a929190614559565b610250610345366004613f13565b61077c565b610250610358366004614248565b610797565b6102da61036b36600461414b565b6107e9565b61037861080f565b60405161020a9190614532565b610378610833565b6101fd610857565b6102506108b8565b6102506103ab3660046143a1565b6108be565b6102266103be36600461401c565b6109a5565b6103786109b2565b6102506109bc565b6102466103e1366004613fa7565b610a80565b6103296103f436600461414b565b610bc9565b61022661040736600461401c565b610cec565b61025061041a366004613f2f565b610d22565b610427610d4d565b60405161020a9190614546565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104c05780601f10610495576101008083540402835291602001916104c0565b820191906000526020600020905b8154815290600101906020018083116104a357829003601f168201915b505050505090505b90565b60006104d8338484610d9a565b5060015b92915050565b6104ea610e02565b6104f381610e30565b50565b60025490565b6000806000610509610eae565b159250610514610ecb565b915061051e610eef565b9050909192565b6001600160a01b0383166000818152600160209081526040808320338085529252822054919261056391148061055b5750838210155b610197610f13565b61056e858585610f21565b336001600160a01b0386161480159061058957506000198114155b1561059b5761059b8533858403610d9a565b60019150505b9392505050565b601290565b60006105b7610ff0565b905090565b6105c4610e02565b6105cc61108d565b6104f3816110a2565b7f000000000000000000000000000000000000000000000000000000000000000090565b60075490565b600060606106158651610610611100565b610d65565b61062a898989898989896111246111ec611252565b97509795505050505050565b3360009081526001602090815260408083206001600160a01b03861684529091528120548083106106725761066d33856000610d9a565b610686565b61068633856106818487610d84565b610d9a565b5060019392505050565b60006105b761069d6104f6565b6106b56106a86109bc565b6106b0611100565b611374565b90611398565b6001600160a01b0381166000908152602081905260409020545b919050565b606080886107046106e9610833565b6001600160a01b0316336001600160a01b03161460cd610f13565b61071961070f6105d5565b82146101f4610f13565b60606107236113e9565b905061072f8882611666565b60006060806107438e8e8e8e8e8e8e611124565b9250925092506107538d846116c7565b61075d82856111ec565b61076781856111ec565b909550935050505b5097509795505050505050565b6001600160a01b031660009081526005602052604090205490565b60007f0000000000000000000000000000000000000000000000000000000000000000826040516020016107cc9291906144ef565b604051602081830303815290604052805190602001209050919050565b600060606107fa8651610610611100565b61062a8989898989898961175a6117d7611252565b7f000000000000000000000000000000000000000000000000000000000000000090565b7f000000000000000000000000000000000000000000000000000000000000000090565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104c05780601f10610495576101008083540402835291602001916104c0565b60085490565b6000806108ce8560200151611838565b905060006108df8660400151611838565b90506000865160018111156108f057fe5b1415610956576109038660600151611b4d565b60608701526109128583611b71565b945061091e8482611b71565b935061092e866060015183611b71565b60608701526000610940878787611b7d565b905061094c8183611bb8565b93505050506105a1565b6109608583611b71565b945061096c8482611b71565b935061097c866060015182611b71565b6060870152600061098e878787611bc4565b905061099a8184611bf7565b905061094c81611c03565b60006104d8338484610f21565b60006105b7611c1a565b600060606109c8610833565b6001600160a01b031663f94d46686109de6105d5565b6040518263ffffffff1660e01b81526004016109fa91906145a1565b60006040518083038186803b158015610a1257600080fd5b505afa158015610a26573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a4e9190810190614047565b50915050610a6381610a5e6113e9565b611666565b6060610a6d611c94565b9050610a798183611ef1565b9250505090565b610a8e8442111560d1610f13565b6001600160a01b0387166000908152600560209081526040808320549051909291610ae5917f0000000000000000000000000000000000000000000000000000000000000000918c918c918c9188918d91016145c9565b6040516020818303038152906040528051906020012090506000610b0882611f63565b9050600060018288888860405160008152602001604052604051610b2f9493929190614629565b6020604051602081039080840390855afa158015610b51573d6000803e3d6000fd5b5050604051601f1901519150610b9390506001600160a01b03821615801590610b8b57508b6001600160a01b0316826001600160a01b0316145b6101f8610f13565b6001600160a01b038b166000908152600560205260409020600185019055610bbc8b8b8b610d9a565b5050505050505050505050565b60608088610bd86106e9610833565b610be361070f6105d5565b6060610bed6113e9565b9050610bf76104f6565b610c9d5760006060610c0b8d8d8d8a611f7f565b91509150610c20620f424083101560cc610f13565b610c2e6000620f424061201a565b610c3d8b620f4240840361201a565b610c4781846117d7565b80610c50611100565b67ffffffffffffffff81118015610c6657600080fd5b50604051908082528060200260200182016040528015610c90578160200160208202803683370190505b509550955050505061076f565b610ca78882611666565b6000606080610cbb8e8e8e8e8e8e8e61175a565b925092509250610ccb8c8461201a565b610cd582856117d7565b610cdf81856111ec565b909550935061076f915050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916104d89185906106819086610d72565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60606105b7611c94565b80610d61816120b0565b5050565b610d618183146067610f13565b60008282016105a18482101583610f13565b6000610d94838311156001610f13565b50900390565b6001600160a01b0380841660008181526001602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610df59085906145a1565b60405180910390a3505050565b6000610e196000356001600160e01b031916610797565b90506104f3610e288233612129565b610191610f13565b8015610e5057610e4b610e41610ecb565b4210610193610f13565b610e65565b610e65610e5b610eef565b42106101a9610f13565b6006805460ff19168215151790556040517f9e3a5e37224532dea67b89face185703738a228a6e8a23dee546960180d3be6490610ea390839061457e565b60405180910390a150565b6000610eb8610eef565b4211806105b757505060065460ff161590565b7f000000000000000000000000000000000000000000000000000000000000000090565b7f000000000000000000000000000000000000000000000000000000000000000090565b81610d6157610d6181612219565b6001600160a01b038316600090815260208190526040902054610f4982821015610196610f13565b610f606001600160a01b0384161515610199610f13565b6001600160a01b03808516600090815260208190526040808220858503905591851681522054610f909083610d72565b6001600160a01b0380851660008181526020819052604090819020939093559151908616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610fe29086906145a1565b60405180910390a350505050565b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061105d61226c565b306040516020016110729594939291906145fd565b60405160208183030381529060405280519060200120905090565b6110a0611098610eae565b610192610f13565b565b6110b564e8d4a5100082101560cb610f13565b6110cb67016345785d8a000082111560ca610f13565b60078190556040517fa9ba3ffe0b6c366b81232caab38605a0699ad5398d6cce76f91ee809e322dafc90610ea39083906145a1565b7f000000000000000000000000000000000000000000000000000000000000000090565b60006060806060611133611c94565b905061113d610eae565b1561117457600061114e828a611ef1565b905061115f8983600854848b612270565b925061116e8984610d84612380565b506111c0565b61117c611100565b67ffffffffffffffff8111801561119257600080fd5b506040519080825280602002602001820160405280156111bc578160200160208202803683370190505b5091505b6111cb8882876123eb565b90945092506111db888483612458565b600855509750975097945050505050565b60005b6111f7611100565b81101561124d5761122e83828151811061120d57fe5b602002602001015183838151811061122157fe5b6020026020010151612471565b83828151811061123a57fe5b60209081029190910101526001016111ef565b505050565b333014611310576000306001600160a01b0316600036604051611276929190614507565b6000604051808303816000865af19150503d80600081146112b3576040519150601f19603f3d011682016040523d82523d6000602084013e6112b8565b606091505b5050905080600081146112c757fe5b60046000803e6000516001600160e01b0319166343adbafb60e01b81146112f2573d6000803e3d6000fd5b506020600460003e604060205260243d03602460403e601c3d016000f35b606061131a6113e9565b90506113268782611666565b6000606061133d8c8c8c8c8c8c8c8c63ffffffff16565b509150915061135081848663ffffffff16565b8051601f1982018390526343adbafb603f1983015260200260231982016044820181fd5b60008282026105a184158061139157508385838161138e57fe5b04145b6003610f13565b60006113a78215156004610f13565b826113b4575060006104dc565b670de0b6b3a7640000838102906113d7908583816113ce57fe5b04146005610f13565b8281816113e057fe5b049150506104dc565b606060006113f5611100565b905060608167ffffffffffffffff8111801561141057600080fd5b5060405190808252806020026020018201604052801561143a578160200160208202803683370190505b5090508115611482577f00000000000000000000000000000000000000000000000000000000000000008160008151811061147157fe5b60200260200101818152505061148b565b91506104c89050565b6001821115611482577f0000000000000000000000000000000000000000000000000000000000000000816001815181106114c257fe5b6020026020010181815250506002821115611482577f00000000000000000000000000000000000000000000000000000000000000008160028151811061150557fe5b6020026020010181815250506003821115611482577f00000000000000000000000000000000000000000000000000000000000000008160038151811061154857fe5b6020026020010181815250506004821115611482577f00000000000000000000000000000000000000000000000000000000000000008160048151811061158b57fe5b6020026020010181815250506005821115611482577f0000000000000000000000000000000000000000000000000000000000000000816005815181106115ce57fe5b6020026020010181815250506006821115611482577f00000000000000000000000000000000000000000000000000000000000000008160068151811061161157fe5b6020026020010181815250506007821115611482577f00000000000000000000000000000000000000000000000000000000000000008160078151811061165457fe5b60200260200101818152505091505090565b60005b611671611100565b81101561124d576116a883828151811061168757fe5b602002602001015183838151811061169b57fe5b6020026020010151611374565b8382815181106116b457fe5b6020908102919091010152600101611669565b6001600160a01b0382166000908152602081905260409020546116ef82821015610196610f13565b6001600160a01b038316600090815260208190526040902082820390556002546117199083610d84565b6002556040516000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610df59086906145a1565b600060608061176761108d565b6060611771611c94565b9050600061177f828a611ef1565b905060606117928a84600854858c612270565b90506117a18a82610d84612380565b600060606117b08c868b612491565b915091506117bf8c82876124eb565b600855909e909d50909b509950505050505050505050565b60005b6117e2611100565b81101561124d576118198382815181106117f857fe5b602002602001015183838151811061180c57fe5b60200260200101516124fa565b83828151811061182557fe5b60209081029190910101526001016117da565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561189b57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156118fc57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561195d57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156119be57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611a1f57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611a8057507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611ae157507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611b4257507f00000000000000000000000000000000000000000000000000000000000000006106d5565b6106d5610135612219565b600080611b656007548461252d90919063ffffffff16565b90506105a18382610d84565b60006105a18383611374565b6000611b8761108d565b611bb083611b988660200151612571565b84611ba68860400151612571565b886060015161287b565b949350505050565b60006105a18383612471565b6000611bce61108d565b611bb083611bdf8660200151612571565b84611bed8860400151612571565b88606001516128f6565b60006105a183836124fa565b60006104dc611c1360075461296c565b8390612992565b6000611c24610833565b6001600160a01b031663aaabadc56040518163ffffffff1660e01b815260040160206040518083038186803b158015611c5c57600080fd5b505afa158015611c70573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b79190614270565b60606000611ca0611100565b905060608167ffffffffffffffff81118015611cbb57600080fd5b50604051908082528060200260200182016040528015611ce5578160200160208202803683370190505b5090508115611482577f000000000000000000000000000000000000000000000000000000000000000081600081518110611d1c57fe5b6020026020010181815250506001821115611482577f000000000000000000000000000000000000000000000000000000000000000081600181518110611d5f57fe5b6020026020010181815250506002821115611482577f000000000000000000000000000000000000000000000000000000000000000081600281518110611da257fe5b6020026020010181815250506003821115611482577f000000000000000000000000000000000000000000000000000000000000000081600381518110611de557fe5b6020026020010181815250506004821115611482577f000000000000000000000000000000000000000000000000000000000000000081600481518110611e2857fe5b6020026020010181815250506005821115611482577f000000000000000000000000000000000000000000000000000000000000000081600581518110611e6b57fe5b6020026020010181815250506006821115611482577f000000000000000000000000000000000000000000000000000000000000000081600681518110611eae57fe5b6020026020010181815250506007821115611482577f00000000000000000000000000000000000000000000000000000000000000008160078151811061165457fe5b670de0b6b3a764000060005b8351811015611f5357611f49611f42858381518110611f1857fe5b6020026020010151858481518110611f2c57fe5b60200260200101516129d490919063ffffffff16565b8390612a23565b9150600101611efd565b506104dc60008211610137610f13565b6000611f6d610ff0565b826040516020016107cc929190614517565b60006060611f8b61108d565b6000611f9684612a4f565b9050611fb16000826002811115611fa957fe5b1460ce610f13565b6060611fbc85612a65565b9050611fd0611fc9611100565b8251610d65565b611fdc81610a5e6113e9565b6060611fe6611c94565b90506000611ff48284611ef1565b90506000612004826106b0611100565b6008929092555099919850909650505050505050565b6001600160a01b03821660009081526020819052604090205461203d9082610d72565b6001600160a01b0383166000908152602081905260409020556002546120639082610d72565b6002556040516001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906120a49085906145a1565b60405180910390a35050565b6002815110156120bf576104f3565b6000816000815181106120ce57fe5b602002602001015190506000600190505b825181101561124d5760008382815181106120f657fe5b6020026020010151905061211f816001600160a01b0316846001600160a01b0316106065610f13565b91506001016120df565b600073ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1b61214861080f565b6001600160a01b031614158015612163575061216383612a7b565b1561218b5761217061080f565b6001600160a01b0316336001600160a01b03161490506104dc565b612193611c1a565b6001600160a01b0316639be2a8848484306040518463ffffffff1660e01b81526004016121c2939291906145aa565b60206040518083038186803b1580156121da57600080fd5b505afa1580156121ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612212919061412f565b90506104dc565b62461bcd60e51b6000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b4690565b60608061227b611100565b67ffffffffffffffff8111801561229157600080fd5b506040519080825280602002602001820160405280156122bb578160200160208202803683370190505b509050826122ca579050612377565b61233d877f0000000000000000000000000000000000000000000000000000000000000000815181106122f957fe5b6020026020010151877f00000000000000000000000000000000000000000000000000000000000000008151811061232d57fe5b6020026020010151878787612a95565b817f00000000000000000000000000000000000000000000000000000000000000008151811061236957fe5b602090810291909101015290505b95945050505050565b60005b61238b611100565b8110156123e5576123c68482815181106123a157fe5b60200260200101518483815181106123b557fe5b60200260200101518463ffffffff16565b8482815181106123d257fe5b6020908102919091010152600101612383565b50505050565b6000606060006123fa84612a4f565b9050600081600281111561240a57fe5b14156124255761241b868686612b0d565b9250925050612450565b600181600281111561243357fe5b14156124435761241b8685612beb565b61241b868686612c1d565b505b935093915050565b60006124678484610d84612380565b611bb08285611ef1565b60006124808215156004610f13565b81838161248957fe5b049392505050565b6000606060006124a084612a4f565b905060018160028111156124b057fe5b14156124c15761241b868686612c88565b60028160028111156124cf57fe5b14156124e05761241b868686612ce2565b61244e610136612219565b60006124678484610d72612380565b60006125098215156004610f13565b82612516575060006104dc565b81600184038161252257fe5b0460010190506104dc565b600082820261254784158061139157508385838161138e57fe5b806125565760009150506104dc565b670de0b6b3a764000060001982015b046001019150506104dc565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156125d457507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561263557507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561269657507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156126f757507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561275857507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156127b957507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561281a57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611b4257507f00000000000000000000000000000000000000000000000000000000000000006106d5565b600061289d61289287670429d069189e0000612a23565b831115610130610f13565b60006128a98784610d72565b905060006128b78883612992565b905060006128c58887611398565b905060006128d38383612d8a565b90506128e86128e18261296c565b8990612a23565b9a9950505050505050505050565b600061291861290d85670429d069189e0000612a23565b831115610131610f13565b600061292e6129278685610d84565b8690612992565b9050600061293c8588612992565b9050600061294a8383612d8a565b9050600061296082670de0b6b3a7640000610d84565b90506128e88a8261252d565b6000670de0b6b3a764000082106129845760006104dc565b50670de0b6b3a76400000390565b60006129a18215156004610f13565b826129ae575060006104dc565b670de0b6b3a7640000838102906129c8908583816113ce57fe5b82600182038161256557fe5b6000806129e18484612db6565b905060006129fb6129f48361271061252d565b6001610d72565b905080821015612a10576000925050506104dc565b612a1a8282610d84565b925050506104dc565b6000828202612a3d84158061139157508385838161138e57fe5b670de0b6b3a764000090049392505050565b6000818060200190518101906104dc919061428c565b6060818060200190518101906105a19190614352565b6000612a8d631c74c91760e11b610797565b909114919050565b6000838311612aa657506000612377565b6000612ab28585612992565b90506000612ac8670de0b6b3a764000088611398565b9050612adc826709b6e64a8ec60000612ec1565b91506000612aea8383612d8a565b90506000612b01612afa8361296c565b8b90612a23565b90506128e88187612a23565b60006060612b1961108d565b600080612b2585612ed8565b91509150612b3d612b34611100565b82106064610f13565b6060612b47611100565b67ffffffffffffffff81118015612b5d57600080fd5b50604051908082528060200260200182016040528015612b87578160200160208202803683370190505b509050612bc6888381518110612b9957fe5b6020026020010151888481518110612bad57fe5b602002602001015185612bbe6104f6565b600754612efa565b818381518110612bd257fe5b6020908102919091010152919791965090945050505050565b600060606000612bfa84612fb7565b90506060612c108683612c0b6104f6565b612fcd565b9196919550909350505050565b60006060612c2961108d565b60606000612c368561307f565b91509150612c478251610610611100565b612c5382610a5e6113e9565b6000612c6b888885612c636104f6565b600754613097565b9050612c7b8282111560cf610f13565b9791965090945050505050565b60006060806000612c988561307f565b91509150612cae612ca7611100565b8351610d65565b612cba82610a5e6113e9565b6000612cd2888885612cca6104f6565b6007546132bc565b9050612c7b8282101560d0610f13565b60006060600080612cf285612ed8565b91509150612d01612b34611100565b6060612d0b611100565b67ffffffffffffffff81118015612d2157600080fd5b50604051908082528060200260200182016040528015612d4b578160200160208202803683370190505b509050612bc6888381518110612d5d57fe5b6020026020010151888481518110612d7157fe5b602002602001015185612d826104f6565b6007546134cd565b600080612d978484612db6565b90506000612daa6129f48361271061252d565b90506123778282610d72565b600081612dcc5750670de0b6b3a76400006104dc565b82612dd9575060006104dc565b612dea600160ff1b84106006610f13565b82612e10770bce5086492111aea88f4bb1ca6bcf584181ea8059f7653284106007610f13565b826000670c7d713b49da000083138015612e315750670f43fc2c04ee000083125b15612e68576000612e418461356f565b9050670de0b6b3a764000080820784020583670de0b6b3a764000083050201915050612e76565b81612e7284613696565b0290505b670de0b6b3a76400009005612eae680238fd42c5cf03ffff198212801590612ea7575068070c1cc73b00c800008213155b6008610f13565b612eb781613a44565b9695505050505050565b600081831015612ed157816105a1565b5090919050565b60008082806020019051810190612eef919061431c565b909590945092505050565b600080612f1184612f0b8188610d84565b90612992565b9050612f2a6709b6e64a8ec60000821015610132610f13565b6000612f48612f41670de0b6b3a764000089611398565b8390612d8a565b90506000612f5f612f588361296c565b8a90612a23565b90506000612f6c8961296c565b90506000612f7a838361252d565b90506000612f888483610d84565b9050612fa7612fa0612f998a61296c565b8490612a23565b8290610d72565b9c9b505050505050505050505050565b6000818060200190518101906105a191906142ef565b60606000612fdb8484611398565b90506060855167ffffffffffffffff81118015612ff757600080fd5b50604051908082528060200260200182016040528015613021578160200160208202803683370190505b50905060005b8651811015613075576130568388838151811061304057fe5b6020026020010151612a2390919063ffffffff16565b82828151811061306257fe5b6020908102919091010152600101613027565b5095945050505050565b6060600082806020019051810190612eef91906142a8565b60006060845167ffffffffffffffff811180156130b357600080fd5b506040519080825280602002602001820160405280156130dd578160200160208202803683370190505b5090506000805b88518110156131a25761313d8982815181106130fc57fe5b6020026020010151612f0b89848151811061311357fe5b60200260200101518c858151811061312757fe5b6020026020010151610d8490919063ffffffff16565b83828151811061314957fe5b60200260200101818152505061319861319189838151811061316757fe5b602002602001015185848151811061317b57fe5b602002602001015161252d90919063ffffffff16565b8390610d72565b91506001016130e4565b50670de0b6b3a764000060005b895181101561329b5760008482815181106131c657fe5b602002602001015184111561321d5760006131ef6131e38661296c565b8d858151811061304057fe5b90506000613203828c868151811061312757fe5b9050613214613191611c138b61296c565b92505050613234565b88828151811061322957fe5b602002602001015190505b600061325d8c848151811061324557fe5b60200260200101516106b5848f878151811061312757fe5b905061328f6132888c858151811061327157fe5b6020026020010151836129d490919063ffffffff16565b8590612a23565b935050506001016131af565b506132af6132a88261296c565b879061252d565b9998505050505050505050565b60006060845167ffffffffffffffff811180156132d857600080fd5b50604051908082528060200260200182016040528015613302578160200160208202803683370190505b5090506000805b88518110156133aa5761336289828151811061332157fe5b60200260200101516106b589848151811061333857fe5b60200260200101518c858151811061334c57fe5b6020026020010151610d7290919063ffffffff16565b83828151811061336e57fe5b6020026020010181815250506133a061319189838151811061338c57fe5b602002602001015185848151811061304057fe5b9150600101613309565b50670de0b6b3a764000060005b895181101561348b576000838583815181106133cf57fe5b6020026020010151111561342b5760006133f46131e386670de0b6b3a7640000610d84565b90506000613408828c868151811061312757fe5b9050613422613191611f42670de0b6b3a76400008c610d84565b92505050613442565b88828151811061343757fe5b602002602001015190505b600061346b8c848151811061345357fe5b60200260200101516106b5848f878151811061334c57fe5b905061347f6132888c858151811061327157fe5b935050506001016133b7565b50670de0b6b3a764000081106134c1576134b76134b082670de0b6b3a7640000610d84565b8790612a23565b9350505050612377565b60009350505050612377565b6000806134de84612f0b8188610d72565b90506134f76729a2241af62c0000821115610133610f13565b600061350e612f41670de0b6b3a764000089612992565b9050600061352e61352783670de0b6b3a7640000610d84565b8a9061252d565b9050600061353b8961296c565b90506000613549838361252d565b905060006135578483610d84565b9050612fa7612fa06135688a61296c565b8490612992565b670de0b6b3a7640000026000806ec097ce7bc90715b34b9f1000000000808401906ec097ce7bc90715b34b9f0fffffffff19850102816135ab57fe5b05905060006ec097ce7bc90715b34b9f100000000082800205905081806ec097ce7bc90715b34b9f100000000081840205915060038205016ec097ce7bc90715b34b9f100000000082840205915060058205016ec097ce7bc90715b34b9f100000000082840205915060078205016ec097ce7bc90715b34b9f100000000082840205915060098205016ec097ce7bc90715b34b9f1000000000828402059150600b8205016ec097ce7bc90715b34b9f1000000000828402059150600d8205016ec097ce7bc90715b34b9f1000000000828402059150600f826002919005919091010295945050505050565b60006136a6600083136064610f13565b670de0b6b3a76400008212156136e1576136d7826ec097ce7bc90715b34b9f1000000000816136d157fe5b05613696565b60000390506106d5565b60007e1600ef3172e58d2e933ec884fde10064c63b5372d805e203c0000000000000831261373257770195e54c5dd42177f53a27172fa9ec630262827000000000830592506806f05b59d3b2000000015b73011798004d755d3c8bc8e03204cf44619e000000831261376a576b1425982cf597cd205cef7380830592506803782dace9d9000000015b606492830292026e01855144814a7ff805980ff008400083126137b2576e01855144814a7ff805980ff008400068056bc75e2d63100000840205925068ad78ebc5ac62000000015b6b02df0ab5a80a22c61ab5a70083126137ed576b02df0ab5a80a22c61ab5a70068056bc75e2d6310000084020592506856bc75e2d631000000015b693f1fce3da636ea5cf850831261382457693f1fce3da636ea5cf85068056bc75e2d631000008402059250682b5e3af16b18800000015b690127fa27722cc06cc5e2831261385b57690127fa27722cc06cc5e268056bc75e2d6310000084020592506815af1d78b58c400000015b68280e60114edb805d0383126138905768280e60114edb805d0368056bc75e2d631000008402059250680ad78ebc5ac6200000015b680ebc5fb4174612111083126138bb57680ebc5fb4174612111068056bc75e2d631000009384020592015b6808f00f760a4b2db55d83126138f0576808f00f760a4b2db55d68056bc75e2d6310000084020592506802b5e3af16b1880000015b6806f5f17757889379378312613925576806f5f177578893793768056bc75e2d63100000840205925068015af1d78b58c40000015b6806248f33704b2866038312613959576806248f33704b28660368056bc75e2d63100000840205925067ad78ebc5ac620000015b6805c548670b9510e7ac831261398d576805c548670b9510e7ac68056bc75e2d6310000084020592506756bc75e2d6310000015b600068056bc75e2d63100000840168056bc75e2d6310000080860302816139b057fe5b059050600068056bc75e2d63100000828002059050818068056bc75e2d63100000818402059150600382050168056bc75e2d63100000828402059150600582050168056bc75e2d63100000828402059150600782050168056bc75e2d63100000828402059150600982050168056bc75e2d63100000828402059150600b820501600202606485820105979650505050505050565b6000613a73680238fd42c5cf03ffff198312158015613a6c575068070c1cc73b00c800008313155b6009610f13565b6000821215613aa757613a8882600003613a44565b6ec097ce7bc90715b34b9f100000000081613a9f57fe5b0590506106d5565b60006806f05b59d3b20000008312613ae757506806f05b59d3b1ffffff1990910190770195e54c5dd42177f53a27172fa9ec630262827000000000613b1d565b6803782dace9d90000008312613b1957506803782dace9d8ffffff19909101906b1425982cf597cd205cef7380613b1d565b5060015b6064929092029168056bc75e2d6310000068ad78ebc5ac620000008412613b6d5768ad78ebc5ac61ffffff199093019268056bc75e2d631000006e01855144814a7ff805980ff008400082020590505b6856bc75e2d6310000008412613ba9576856bc75e2d630ffffff199093019268056bc75e2d631000006b02df0ab5a80a22c61ab5a70082020590505b682b5e3af16b188000008412613be357682b5e3af16b187fffff199093019268056bc75e2d63100000693f1fce3da636ea5cf85082020590505b6815af1d78b58c4000008412613c1d576815af1d78b58c3fffff199093019268056bc75e2d63100000690127fa27722cc06cc5e282020590505b680ad78ebc5ac62000008412613c5657680ad78ebc5ac61fffff199093019268056bc75e2d6310000068280e60114edb805d0382020590505b68056bc75e2d631000008412613c8f5768056bc75e2d630fffff199093019268056bc75e2d63100000680ebc5fb4174612111082020590505b6802b5e3af16b18800008412613cc8576802b5e3af16b187ffff199093019268056bc75e2d631000006808f00f760a4b2db55d82020590505b68015af1d78b58c400008412613d015768015af1d78b58c3ffff199093019268056bc75e2d631000006806f5f177578893793782020590505b68056bc75e2d631000008481019085906002908280020505918201919050600368056bc75e2d631000008783020505918201919050600468056bc75e2d631000008783020505918201919050600568056bc75e2d631000008783020505918201919050600668056bc75e2d631000008783020505918201919050600768056bc75e2d631000008783020505918201919050600868056bc75e2d631000008783020505918201919050600968056bc75e2d631000008783020505918201919050600a68056bc75e2d631000008783020505918201919050600b68056bc75e2d631000008783020505918201919050600c68056bc75e2d631000008783020505918201919050606468056bc75e2d63100000848402058502059695505050505050565b80356104dc81614708565b600082601f830112613e3d578081fd5b8151613e50613e4b826146e8565b6146c1565b818152915060208083019084810181840286018201871015613e7157600080fd5b60005b84811015613e9057815184529282019290820190600101613e74565b505050505092915050565b600082601f830112613eab578081fd5b813567ffffffffffffffff811115613ec1578182fd5b613ed4601f8201601f19166020016146c1565b9150808252836020828501011115613eeb57600080fd5b8060208401602084013760009082016020015292915050565b8035600281106104dc57600080fd5b600060208284031215613f24578081fd5b81356105a181614708565b60008060408385031215613f41578081fd5b8235613f4c81614708565b91506020830135613f5c81614708565b809150509250929050565b600080600060608486031215613f7b578081fd5b8335613f8681614708565b92506020840135613f9681614708565b929592945050506040919091013590565b600080600080600080600060e0888a031215613fc1578283fd5b8735613fcc81614708565b96506020880135613fdc81614708565b95506040880135945060608801359350608088013560ff81168114613fff578384fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561402e578182fd5b823561403981614708565b946020939093013593505050565b60008060006060848603121561405b578081fd5b835167ffffffffffffffff80821115614072578283fd5b818601915086601f830112614085578283fd5b8151614093613e4b826146e8565b80828252602080830192508086018b8283870289010111156140b3578788fd5b8796505b848710156140de5780516140ca81614708565b8452600196909601959281019281016140b7565b5089015190975093505050808211156140f5578283fd5b5061410286828701613e2d565b925050604084015190509250925092565b600060208284031215614124578081fd5b81356105a18161471d565b600060208284031215614140578081fd5b81516105a18161471d565b600080600080600080600060e0888a031215614165578081fd5b8735965060208089013561417881614708565b9650604089013561418881614708565b9550606089013567ffffffffffffffff808211156141a4578384fd5b818b0191508b601f8301126141b7578384fd5b81356141c5613e4b826146e8565b8082825285820191508585018f8788860288010111156141e3578788fd5b8795505b838610156142055780358352600195909501949186019186016141e7565b509850505060808b0135955060a08b0135945060c08b013592508083111561422b578384fd5b50506142398a828b01613e9b565b91505092959891949750929550565b600060208284031215614259578081fd5b81356001600160e01b0319811681146105a1578182fd5b600060208284031215614281578081fd5b81516105a181614708565b60006020828403121561429d578081fd5b81516105a18161472b565b6000806000606084860312156142bc578081fd5b83516142c78161472b565b602085015190935067ffffffffffffffff8111156142e3578182fd5b61410286828701613e2d565b60008060408385031215614301578182fd5b825161430c8161472b565b6020939093015192949293505050565b600080600060608486031215614330578081fd5b835161433b8161472b565b602085015160409095015190969495509392505050565b60008060408385031215614364578182fd5b825161436f8161472b565b602084015190925067ffffffffffffffff81111561438b578182fd5b61439785828601613e2d565b9150509250929050565b6000806000606084860312156143b5578081fd5b833567ffffffffffffffff808211156143cc578283fd5b81860191506101208083890312156143e2578384fd5b6143eb816146c1565b90506143f78884613f04565b81526144068860208501613e22565b60208201526144188860408501613e22565b6040820152606083013560608201526080830135608082015260a083013560a08201526144488860c08501613e22565b60c082015261445a8860e08501613e22565b60e08201526101008084013583811115614472578586fd5b61447e8a828701613e9b565b9183019190915250976020870135975060409096013595945050505050565b6000602082840312156144ae578081fd5b5035919050565b6000815180845260208085019450808401835b838110156144e4578151875295820195908201906001016144c8565b509495945050505050565b9182526001600160e01b031916602082015260240190565b6000828483379101908152919050565b61190160f01b81526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6000602082526105a160208301846144b5565b60006040825261456c60408301856144b5565b828103602084015261237781856144b5565b901515815260200190565b92151583526020830191909152604082015260600190565b90815260200190565b9283526001600160a01b03918216602084015216604082015260600190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b6000602080835283518082850152825b8181101561467357858101830151858201604001528201614657565b818111156146845783604083870101525b50601f01601f1916929092016040019392505050565b600083825260406020830152611bb060408301846144b5565b60ff91909116815260200190565b60405181810167ffffffffffffffff811182821017156146e057600080fd5b604052919050565b600067ffffffffffffffff8211156146fe578081fd5b5060209081020190565b6001600160a01b03811681146104f357600080fd5b80151581146104f357600080fd5b600381106104f357600080fdfea2646970667358221220a2c3b62e0bc50507598395387e1557612d7ad59e817ddae4d5279907402fedb464736f6c63430007010033a26469706673582212201bcb3a953b00c5c4dcf4d3cf74f047f69d25320298f41e6f635cb029516f583764736f6c63430007010033", + "deployedBytecode": "", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/utils/contracts/balancerV2.ts b/utils/contracts/balancerV2.ts new file mode 100644 index 000000000..cb0655c99 --- /dev/null +++ b/utils/contracts/balancerV2.ts @@ -0,0 +1,3 @@ +// External Balancer V2 Contracts +export { BVault } from "../../typechain/BVault"; +export { WeightedPoolFactory } from "../../typechain/WeightedPoolFactory"; \ No newline at end of file diff --git a/utils/deploys/deployExternal.ts b/utils/deploys/deployExternal.ts index 5982514d7..157f0c7f7 100644 --- a/utils/deploys/deployExternal.ts +++ b/utils/deploys/deployExternal.ts @@ -1,6 +1,8 @@ import { Signer } from "ethers"; import { BigNumberish, BigNumber } from "@ethersproject/bignumber"; import { ether } from "../common"; +import { ADDRESS_ZERO, ZERO } from "@utils/constants"; +import { Address } from "./../types"; import { CompoundPriceOracleMock, @@ -21,8 +23,6 @@ import { DelegateRegistry } from "./../contracts"; -import { Address } from "./../types"; - import { CERc20__factory } from "../../typechain/factories/CERc20__factory"; import { CEther__factory } from "../../typechain/factories/CEther__factory"; import { CompoundPriceOracleMock__factory } from "../../typechain/factories/CompoundPriceOracleMock__factory"; @@ -202,6 +202,13 @@ import { AaveGovernanceV2__factory } from "../../typechain/factories/AaveGoverna import { Executor__factory } from "../../typechain/factories/Executor__factory"; import { GovernanceStrategy__factory } from "../../typechain/factories/GovernanceStrategy__factory"; +import { + BVault, + WeightedPoolFactory +} from "../contracts/balancerV2"; +import { BVault__factory } from "../../typechain/factories/BVault__factory"; +import { WeightedPoolFactory__factory } from "../../typechain/factories/WeightedPoolFactory__factory"; + export default class DeployExternalContracts { private _deployerSigner: Signer; @@ -772,4 +779,13 @@ export default class DeployExternalContracts { public async deployNFTDescriptor(): Promise { return await new NFTDescriptor__factory(this._deployerSigner).deploy(); } + + // Balancer V2 + public async deployBVault(weth: Address): Promise { + return await new BVault__factory(this._deployerSigner).deploy(ADDRESS_ZERO, weth, ZERO, ZERO); + } + + public async deployWeightedPoolFactory(vault: Address): Promise { + return await new WeightedPoolFactory__factory(this._deployerSigner).deploy(vault); + } } From 057da943b428a7482e0620b643e0e0e21318f66a Mon Sep 17 00:00:00 2001 From: ncitron Date: Fri, 10 Sep 2021 21:32:42 -0400 Subject: [PATCH 2/9] add BalancerV2Fixture --- external/abi/balancer/v2/BPoolV2.json | 8 +++ test/fixtures/balancerV2.spec.ts | 77 +++++++++++++++++++++++++++ utils/fixtures/balancerV2Fixture.ts | 66 +++++++++++++++++++++++ utils/fixtures/index.ts | 1 + utils/test/index.ts | 2 + 5 files changed, 154 insertions(+) create mode 100644 external/abi/balancer/v2/BPoolV2.json create mode 100644 test/fixtures/balancerV2.spec.ts create mode 100644 utils/fixtures/balancerV2Fixture.ts diff --git a/external/abi/balancer/v2/BPoolV2.json b/external/abi/balancer/v2/BPoolV2.json new file mode 100644 index 000000000..f049e9203 --- /dev/null +++ b/external/abi/balancer/v2/BPoolV2.json @@ -0,0 +1,8 @@ +{ + "contractName": "BPoolV2", + "abi":[{"inputs":[{"internalType":"contract IVault","name":"vault","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"normalizedWeights","type":"uint256[]"},{"internalType":"uint256","name":"swapFeePercentage","type":"uint256"},{"internalType":"uint256","name":"pauseWindowDuration","type":"uint256"},{"internalType":"uint256","name":"bufferPeriodDuration","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"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":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"PausedStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"swapFeePercentage","type":"uint256"}],"name":"SwapFeePercentageChanged","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":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","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":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"decreaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"getActionId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAuthorizer","outputs":[{"internalType":"contract IAuthorizer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInvariant","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastInvariant","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNormalizedWeights","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPausedState","outputs":[{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"uint256","name":"pauseWindowEndTime","type":"uint256"},{"internalType":"uint256","name":"bufferPeriodEndTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPoolId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSwapFeePercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVault","outputs":[{"internalType":"contract IVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"increaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"uint256","name":"protocolSwapFeePercentage","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"onExitPool","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"uint256","name":"protocolSwapFeePercentage","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"onJoinPool","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"enum IVault.SwapKind","name":"kind","type":"uint8"},{"internalType":"contract IERC20","name":"tokenIn","type":"address"},{"internalType":"contract IERC20","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"userData","type":"bytes"}],"internalType":"struct IPoolSwapStructs.SwapRequest","name":"request","type":"tuple"},{"internalType":"uint256","name":"balanceTokenIn","type":"uint256"},{"internalType":"uint256","name":"balanceTokenOut","type":"uint256"}],"name":"onSwap","outputs":[{"internalType":"uint256","name":"","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":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"uint256","name":"protocolSwapFeePercentage","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"queryExit","outputs":[{"internalType":"uint256","name":"bptIn","type":"uint256"},{"internalType":"uint256[]","name":"amountsOut","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"uint256","name":"protocolSwapFeePercentage","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"queryJoin","outputs":[{"internalType":"uint256","name":"bptOut","type":"uint256"},{"internalType":"uint256[]","name":"amountsIn","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"swapFeePercentage","type":"uint256"}],"name":"setSwapFeePercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}], + "bytecode": "6105006040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9610120523480156200003757600080fd5b50604051620058b6380380620058b68339810160408190526200005a9162000cf2565b88888888878787878785516002146200007557600162000078565b60025b6040805180820190915260018152603160f81b6020808301918252336080526001600160601b0319606087901b1660a0528b51908c0190812060c0529151902060e0527f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6101005289518a918a918a918a918a918a918a91849184918a918a9162000107916003919062000abb565b5080516200011d90600490602084019062000abb565b50620001359150506276a70083111561019462000865565b6200014962278d0082111561019562000865565b42909101610140819052016101605284516200016b906002111560c862000865565b6200018360088651111560c96200086560201b60201c565b62000199856200087a60201b62000d571760201c565b620001a48462000886565b6040516309b2760f60e01b81526000906001600160a01b038b16906309b2760f90620001d5908c9060040162000eab565b602060405180830381600087803b158015620001f057600080fd5b505af115801562000205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022b919062000cd9565b9050896001600160a01b03166366a9c7d2828889516001600160401b03811180156200025657600080fd5b5060405190808252806020026020018201604052801562000281578160200160208202803683370190505b506040518463ffffffff1660e01b8152600401620002a29392919062000e0f565b600060405180830381600087803b158015620002bd57600080fd5b505af1158015620002d2573d6000803e3d6000fd5b5050506001600160601b031960608c901b1661018052506101a081905285516101c0528551620003045760006200031b565b856000815181106200031257fe5b60200260200101515b60601b6001600160601b0319166101e05285516001106200033e57600062000355565b856001815181106200034c57fe5b60200260200101515b60601b6001600160601b031916610200528551600210620003785760006200038f565b856002815181106200038657fe5b60200260200101515b60601b6001600160601b031916610220528551600310620003b2576000620003c9565b85600381518110620003c057fe5b60200260200101515b60601b6001600160601b031916610240528551600410620003ec57600062000403565b85600481518110620003fa57fe5b60200260200101515b60601b6001600160601b031916610260528551600510620004265760006200043d565b856005815181106200043457fe5b60200260200101515b60601b6001600160601b0319166102805285516006106200046057600062000477565b856006815181106200046e57fe5b60200260200101515b60601b6001600160601b0319166102a05285516007106200049a576000620004b1565b85600781518110620004a857fe5b60200260200101515b60601b6001600160601b0319166102c0528551620004d1576000620004f7565b620004f786600081518110620004e357fe5b6020026020010151620008f560201b60201c565b6102e05285516001106200050d5760006200051f565b6200051f86600181518110620004e357fe5b6103005285516002106200053557600062000547565b6200054786600281518110620004e357fe5b6103205285516003106200055d5760006200056f565b6200056f86600381518110620004e357fe5b6103405285516004106200058557600062000597565b6200059786600481518110620004e357fe5b610360528551600510620005ad576000620005bf565b620005bf86600581518110620004e357fe5b610380528551600610620005d5576000620005e7565b620005e786600681518110620004e357fe5b6103a0528551600710620005fd5760006200060f565b6200060f86600781518110620004e357fe5b6103c08181525050505050505050505050505050505050505050600086519050620006478187516200099760201b62000d651760201c565b6000806000805b848160ff161015620006cd5760008a8260ff16815181106200066c57fe5b6020026020010151905062000694662386f26fc1000082101561012e6200086560201b60201c565b620006ae8186620009a660201b62000d721790919060201c565b945082811115620006c3578160ff1693508092505b506001016200064e565b50620006e6670de0b6b3a7640000841461013462000865565b6103e08290528851620006fb57600062000712565b886000815181106200070957fe5b60200260200101515b610400528851600110620007285760006200073f565b886001815181106200073657fe5b60200260200101515b610420528851600210620007555760006200076c565b886002815181106200076357fe5b60200260200101515b6104405288516003106200078257600062000799565b886003815181106200079057fe5b60200260200101515b610460528851600410620007af576000620007c6565b88600481518110620007bd57fe5b60200260200101515b610480528851600510620007dc576000620007f3565b88600581518110620007ea57fe5b60200260200101515b6104a05288516006106200080957600062000820565b886006815181106200081757fe5b60200260200101515b6104c0528851600710620008365760006200084d565b886007815181106200084457fe5b60200260200101515b6104e0525062000f329b505050505050505050505050565b8162000876576200087681620009c3565b5050565b80620008768162000a16565b6200089b64e8d4a5100082101560cb62000865565b620008b367016345785d8a000082111560ca62000865565b60078190556040517fa9ba3ffe0b6c366b81232caab38605a0699ad5398d6cce76f91ee809e322dafc90620008ea90839062000ec0565b60405180910390a150565b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156200093257600080fd5b505afa15801562000947573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200096d919062000dec565b60ff16905060006200098c60128362000aa360201b62000d841760201c565b600a0a949350505050565b62000876828214606762000865565b6000828201620009ba848210158362000865565b90505b92915050565b62461bcd60e51b6000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b60028151101562000a275762000aa0565b60008160008151811062000a3757fe5b602002602001015190506000600190505b825181101562000a9d57600083828151811062000a6157fe5b6020026020010151905062000a92816001600160a01b0316846001600160a01b03161060656200086560201b60201c565b915060010162000a48565b50505b50565b600062000ab583831115600162000865565b50900390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1062000afe57805160ff191683800117855562000b2e565b8280016001018555821562000b2e579182015b8281111562000b2e57825182559160200191906001019062000b11565b5062000b3c92915062000b40565b5090565b5b8082111562000b3c576000815560010162000b41565b8051620009bd8162000f1c565b600082601f83011262000b75578081fd5b815162000b8c62000b868262000ef0565b62000ec9565b81815291506020808301908481018184028601820187101562000bae57600080fd5b60005b8481101562000bda57815162000bc78162000f1c565b8452928201929082019060010162000bb1565b505050505092915050565b600082601f83011262000bf6578081fd5b815162000c0762000b868262000ef0565b81815291506020808301908481018184028601820187101562000c2957600080fd5b60005b8481101562000bda5781518452928201929082019060010162000c2c565b600082601f83011262000c5b578081fd5b81516001600160401b0381111562000c71578182fd5b602062000c87601f8301601f1916820162000ec9565b9250818352848183860101111562000c9e57600080fd5b60005b8281101562000cbe57848101820151848201830152810162000ca1565b8281111562000cd05760008284860101525b50505092915050565b60006020828403121562000ceb578081fd5b5051919050565b60008060008060008060008060006101208a8c03121562000d11578485fd5b62000d1d8b8b62000b57565b60208b01519099506001600160401b038082111562000d3a578687fd5b62000d488d838e0162000c4a565b995060408c015191508082111562000d5e578687fd5b62000d6c8d838e0162000c4a565b985060608c015191508082111562000d82578687fd5b62000d908d838e0162000b64565b975060808c015191508082111562000da6578687fd5b5062000db58c828d0162000be5565b95505060a08a0151935060c08a0151925060e08a0151915062000ddd8b6101008c0162000b57565b90509295985092959850929598565b60006020828403121562000dfe578081fd5b815160ff81168114620009ba578182fd5b60006060820185835260206060818501528186518084526080860191508288019350845b8181101562000e5b5762000e48855162000f10565b8352938301939183019160010162000e33565b505084810360408601528551808252908201925081860190845b8181101562000e9d5762000e8a835162000f10565b8552938301939183019160010162000e75565b509298975050505050505050565b602081016003831062000eba57fe5b91905290565b90815260200190565b6040518181016001600160401b038111828210171562000ee857600080fd5b604052919050565b60006001600160401b0382111562000f06578081fd5b5060209081020190565b6001600160a01b031690565b6001600160a01b038116811462000aa057600080fd5b60805160a05160601c60c05160e051610100516101205161014051610160516101805160601c6101a0516101c0516101e05160601c6102005160601c6102205160601c6102405160601c6102605160601c6102805160601c6102a05160601c6102c05160601c6102e05161030051610320516103405161036051610380516103a0516103c0516103e05161040051610420516104405161046051610480516104a0516104c0516104e05161476e6200114860003980611ec55280612857525080611e8252806127f6525080611e3f5280612795525080611dfc5280612734525080611db952806126d3525080611d765280612672525080611d335280612611525080611cf052806125b05250806122d0528061230452806123405250806116285280611b1e5250806115e55280611abd5250806115a25280611a5c52508061155f52806119fb52508061151c528061199a5250806114d9528061193952508061149652806118d85250806114455280611877525080611ae3528061281c525080611a8252806127bb525080611a21528061275a5250806119c052806126f952508061195f52806126985250806118fe528061263752508061189d52806125d652508061183c52806125755250806111025250806105d7525080610835525080610ef1525080610ecd525080610ab5525080610ff452508061103652508061101552508061081152508061079b525061476e6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80637ecebe001161010f578063a9059cbb116100a2578063d5c096c411610071578063d5c096c4146103e6578063d73dd623146103f9578063dd62ed3e1461040c578063f89f27ed1461041f576101f0565b8063a9059cbb146103b0578063aaabadc5146103c3578063c0ff1a15146103cb578063d505accf146103d3576101f0565b80638d928af8116100de5780638d928af81461038557806395d89b411461038d5780639b02cdde146103955780639d2c110c1461039d576101f0565b80637ecebe0014610337578063851c1bb31461034a57806387ec68171461035d578063893d20e814610370576101f0565b806338e9922e11610187578063661884631161015657806366188463146102e8578063679aefce146102fb57806370a082311461030357806374f3b00914610316576101f0565b806338e9922e146102a457806338fff2d0146102b757806355c67628146102bf5780636028bfd4146102c7576101f0565b80631c0de051116101c35780631c0de0511461025d57806323b872dd14610274578063313ce567146102875780633644e5151461029c576101f0565b806306fdde03146101f5578063095ea7b31461021357806316c38b3c1461023357806318160ddd14610248575b600080fd5b6101fd610434565b60405161020a9190614647565b60405180910390f35b61022661022136600461401c565b6104cb565b60405161020a919061457e565b610246610241366004614113565b6104e2565b005b6102506104f6565b60405161020a91906145a1565b6102656104fc565b60405161020a93929190614589565b610226610282366004613f67565b610525565b61028f6105a8565b60405161020a91906146b3565b6102506105ad565b6102466102b236600461449d565b6105bc565b6102506105d5565b6102506105f9565b6102da6102d536600461414b565b6105ff565b60405161020a92919061469a565b6102266102f636600461401c565b610636565b610250610690565b610250610311366004613f13565b6106bb565b61032961032436600461414b565b6106da565b60405161020a929190614559565b610250610345366004613f13565b61077c565b610250610358366004614248565b610797565b6102da61036b36600461414b565b6107e9565b61037861080f565b60405161020a9190614532565b610378610833565b6101fd610857565b6102506108b8565b6102506103ab3660046143a1565b6108be565b6102266103be36600461401c565b6109a5565b6103786109b2565b6102506109bc565b6102466103e1366004613fa7565b610a80565b6103296103f436600461414b565b610bc9565b61022661040736600461401c565b610cec565b61025061041a366004613f2f565b610d22565b610427610d4d565b60405161020a9190614546565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104c05780601f10610495576101008083540402835291602001916104c0565b820191906000526020600020905b8154815290600101906020018083116104a357829003601f168201915b505050505090505b90565b60006104d8338484610d9a565b5060015b92915050565b6104ea610e02565b6104f381610e30565b50565b60025490565b6000806000610509610eae565b159250610514610ecb565b915061051e610eef565b9050909192565b6001600160a01b0383166000818152600160209081526040808320338085529252822054919261056391148061055b5750838210155b610197610f13565b61056e858585610f21565b336001600160a01b0386161480159061058957506000198114155b1561059b5761059b8533858403610d9a565b60019150505b9392505050565b601290565b60006105b7610ff0565b905090565b6105c4610e02565b6105cc61108d565b6104f3816110a2565b7f000000000000000000000000000000000000000000000000000000000000000090565b60075490565b600060606106158651610610611100565b610d65565b61062a898989898989896111246111ec611252565b97509795505050505050565b3360009081526001602090815260408083206001600160a01b03861684529091528120548083106106725761066d33856000610d9a565b610686565b61068633856106818487610d84565b610d9a565b5060019392505050565b60006105b761069d6104f6565b6106b56106a86109bc565b6106b0611100565b611374565b90611398565b6001600160a01b0381166000908152602081905260409020545b919050565b606080886107046106e9610833565b6001600160a01b0316336001600160a01b03161460cd610f13565b61071961070f6105d5565b82146101f4610f13565b60606107236113e9565b905061072f8882611666565b60006060806107438e8e8e8e8e8e8e611124565b9250925092506107538d846116c7565b61075d82856111ec565b61076781856111ec565b909550935050505b5097509795505050505050565b6001600160a01b031660009081526005602052604090205490565b60007f0000000000000000000000000000000000000000000000000000000000000000826040516020016107cc9291906144ef565b604051602081830303815290604052805190602001209050919050565b600060606107fa8651610610611100565b61062a8989898989898961175a6117d7611252565b7f000000000000000000000000000000000000000000000000000000000000000090565b7f000000000000000000000000000000000000000000000000000000000000000090565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104c05780601f10610495576101008083540402835291602001916104c0565b60085490565b6000806108ce8560200151611838565b905060006108df8660400151611838565b90506000865160018111156108f057fe5b1415610956576109038660600151611b4d565b60608701526109128583611b71565b945061091e8482611b71565b935061092e866060015183611b71565b60608701526000610940878787611b7d565b905061094c8183611bb8565b93505050506105a1565b6109608583611b71565b945061096c8482611b71565b935061097c866060015182611b71565b6060870152600061098e878787611bc4565b905061099a8184611bf7565b905061094c81611c03565b60006104d8338484610f21565b60006105b7611c1a565b600060606109c8610833565b6001600160a01b031663f94d46686109de6105d5565b6040518263ffffffff1660e01b81526004016109fa91906145a1565b60006040518083038186803b158015610a1257600080fd5b505afa158015610a26573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a4e9190810190614047565b50915050610a6381610a5e6113e9565b611666565b6060610a6d611c94565b9050610a798183611ef1565b9250505090565b610a8e8442111560d1610f13565b6001600160a01b0387166000908152600560209081526040808320549051909291610ae5917f0000000000000000000000000000000000000000000000000000000000000000918c918c918c9188918d91016145c9565b6040516020818303038152906040528051906020012090506000610b0882611f63565b9050600060018288888860405160008152602001604052604051610b2f9493929190614629565b6020604051602081039080840390855afa158015610b51573d6000803e3d6000fd5b5050604051601f1901519150610b9390506001600160a01b03821615801590610b8b57508b6001600160a01b0316826001600160a01b0316145b6101f8610f13565b6001600160a01b038b166000908152600560205260409020600185019055610bbc8b8b8b610d9a565b5050505050505050505050565b60608088610bd86106e9610833565b610be361070f6105d5565b6060610bed6113e9565b9050610bf76104f6565b610c9d5760006060610c0b8d8d8d8a611f7f565b91509150610c20620f424083101560cc610f13565b610c2e6000620f424061201a565b610c3d8b620f4240840361201a565b610c4781846117d7565b80610c50611100565b67ffffffffffffffff81118015610c6657600080fd5b50604051908082528060200260200182016040528015610c90578160200160208202803683370190505b509550955050505061076f565b610ca78882611666565b6000606080610cbb8e8e8e8e8e8e8e61175a565b925092509250610ccb8c8461201a565b610cd582856117d7565b610cdf81856111ec565b909550935061076f915050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916104d89185906106819086610d72565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60606105b7611c94565b80610d61816120b0565b5050565b610d618183146067610f13565b60008282016105a18482101583610f13565b6000610d94838311156001610f13565b50900390565b6001600160a01b0380841660008181526001602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610df59085906145a1565b60405180910390a3505050565b6000610e196000356001600160e01b031916610797565b90506104f3610e288233612129565b610191610f13565b8015610e5057610e4b610e41610ecb565b4210610193610f13565b610e65565b610e65610e5b610eef565b42106101a9610f13565b6006805460ff19168215151790556040517f9e3a5e37224532dea67b89face185703738a228a6e8a23dee546960180d3be6490610ea390839061457e565b60405180910390a150565b6000610eb8610eef565b4211806105b757505060065460ff161590565b7f000000000000000000000000000000000000000000000000000000000000000090565b7f000000000000000000000000000000000000000000000000000000000000000090565b81610d6157610d6181612219565b6001600160a01b038316600090815260208190526040902054610f4982821015610196610f13565b610f606001600160a01b0384161515610199610f13565b6001600160a01b03808516600090815260208190526040808220858503905591851681522054610f909083610d72565b6001600160a01b0380851660008181526020819052604090819020939093559151908616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610fe29086906145a1565b60405180910390a350505050565b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061105d61226c565b306040516020016110729594939291906145fd565b60405160208183030381529060405280519060200120905090565b6110a0611098610eae565b610192610f13565b565b6110b564e8d4a5100082101560cb610f13565b6110cb67016345785d8a000082111560ca610f13565b60078190556040517fa9ba3ffe0b6c366b81232caab38605a0699ad5398d6cce76f91ee809e322dafc90610ea39083906145a1565b7f000000000000000000000000000000000000000000000000000000000000000090565b60006060806060611133611c94565b905061113d610eae565b1561117457600061114e828a611ef1565b905061115f8983600854848b612270565b925061116e8984610d84612380565b506111c0565b61117c611100565b67ffffffffffffffff8111801561119257600080fd5b506040519080825280602002602001820160405280156111bc578160200160208202803683370190505b5091505b6111cb8882876123eb565b90945092506111db888483612458565b600855509750975097945050505050565b60005b6111f7611100565b81101561124d5761122e83828151811061120d57fe5b602002602001015183838151811061122157fe5b6020026020010151612471565b83828151811061123a57fe5b60209081029190910101526001016111ef565b505050565b333014611310576000306001600160a01b0316600036604051611276929190614507565b6000604051808303816000865af19150503d80600081146112b3576040519150601f19603f3d011682016040523d82523d6000602084013e6112b8565b606091505b5050905080600081146112c757fe5b60046000803e6000516001600160e01b0319166343adbafb60e01b81146112f2573d6000803e3d6000fd5b506020600460003e604060205260243d03602460403e601c3d016000f35b606061131a6113e9565b90506113268782611666565b6000606061133d8c8c8c8c8c8c8c8c63ffffffff16565b509150915061135081848663ffffffff16565b8051601f1982018390526343adbafb603f1983015260200260231982016044820181fd5b60008282026105a184158061139157508385838161138e57fe5b04145b6003610f13565b60006113a78215156004610f13565b826113b4575060006104dc565b670de0b6b3a7640000838102906113d7908583816113ce57fe5b04146005610f13565b8281816113e057fe5b049150506104dc565b606060006113f5611100565b905060608167ffffffffffffffff8111801561141057600080fd5b5060405190808252806020026020018201604052801561143a578160200160208202803683370190505b5090508115611482577f00000000000000000000000000000000000000000000000000000000000000008160008151811061147157fe5b60200260200101818152505061148b565b91506104c89050565b6001821115611482577f0000000000000000000000000000000000000000000000000000000000000000816001815181106114c257fe5b6020026020010181815250506002821115611482577f00000000000000000000000000000000000000000000000000000000000000008160028151811061150557fe5b6020026020010181815250506003821115611482577f00000000000000000000000000000000000000000000000000000000000000008160038151811061154857fe5b6020026020010181815250506004821115611482577f00000000000000000000000000000000000000000000000000000000000000008160048151811061158b57fe5b6020026020010181815250506005821115611482577f0000000000000000000000000000000000000000000000000000000000000000816005815181106115ce57fe5b6020026020010181815250506006821115611482577f00000000000000000000000000000000000000000000000000000000000000008160068151811061161157fe5b6020026020010181815250506007821115611482577f00000000000000000000000000000000000000000000000000000000000000008160078151811061165457fe5b60200260200101818152505091505090565b60005b611671611100565b81101561124d576116a883828151811061168757fe5b602002602001015183838151811061169b57fe5b6020026020010151611374565b8382815181106116b457fe5b6020908102919091010152600101611669565b6001600160a01b0382166000908152602081905260409020546116ef82821015610196610f13565b6001600160a01b038316600090815260208190526040902082820390556002546117199083610d84565b6002556040516000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610df59086906145a1565b600060608061176761108d565b6060611771611c94565b9050600061177f828a611ef1565b905060606117928a84600854858c612270565b90506117a18a82610d84612380565b600060606117b08c868b612491565b915091506117bf8c82876124eb565b600855909e909d50909b509950505050505050505050565b60005b6117e2611100565b81101561124d576118198382815181106117f857fe5b602002602001015183838151811061180c57fe5b60200260200101516124fa565b83828151811061182557fe5b60209081029190910101526001016117da565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561189b57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156118fc57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561195d57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156119be57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611a1f57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611a8057507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611ae157507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611b4257507f00000000000000000000000000000000000000000000000000000000000000006106d5565b6106d5610135612219565b600080611b656007548461252d90919063ffffffff16565b90506105a18382610d84565b60006105a18383611374565b6000611b8761108d565b611bb083611b988660200151612571565b84611ba68860400151612571565b886060015161287b565b949350505050565b60006105a18383612471565b6000611bce61108d565b611bb083611bdf8660200151612571565b84611bed8860400151612571565b88606001516128f6565b60006105a183836124fa565b60006104dc611c1360075461296c565b8390612992565b6000611c24610833565b6001600160a01b031663aaabadc56040518163ffffffff1660e01b815260040160206040518083038186803b158015611c5c57600080fd5b505afa158015611c70573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b79190614270565b60606000611ca0611100565b905060608167ffffffffffffffff81118015611cbb57600080fd5b50604051908082528060200260200182016040528015611ce5578160200160208202803683370190505b5090508115611482577f000000000000000000000000000000000000000000000000000000000000000081600081518110611d1c57fe5b6020026020010181815250506001821115611482577f000000000000000000000000000000000000000000000000000000000000000081600181518110611d5f57fe5b6020026020010181815250506002821115611482577f000000000000000000000000000000000000000000000000000000000000000081600281518110611da257fe5b6020026020010181815250506003821115611482577f000000000000000000000000000000000000000000000000000000000000000081600381518110611de557fe5b6020026020010181815250506004821115611482577f000000000000000000000000000000000000000000000000000000000000000081600481518110611e2857fe5b6020026020010181815250506005821115611482577f000000000000000000000000000000000000000000000000000000000000000081600581518110611e6b57fe5b6020026020010181815250506006821115611482577f000000000000000000000000000000000000000000000000000000000000000081600681518110611eae57fe5b6020026020010181815250506007821115611482577f00000000000000000000000000000000000000000000000000000000000000008160078151811061165457fe5b670de0b6b3a764000060005b8351811015611f5357611f49611f42858381518110611f1857fe5b6020026020010151858481518110611f2c57fe5b60200260200101516129d490919063ffffffff16565b8390612a23565b9150600101611efd565b506104dc60008211610137610f13565b6000611f6d610ff0565b826040516020016107cc929190614517565b60006060611f8b61108d565b6000611f9684612a4f565b9050611fb16000826002811115611fa957fe5b1460ce610f13565b6060611fbc85612a65565b9050611fd0611fc9611100565b8251610d65565b611fdc81610a5e6113e9565b6060611fe6611c94565b90506000611ff48284611ef1565b90506000612004826106b0611100565b6008929092555099919850909650505050505050565b6001600160a01b03821660009081526020819052604090205461203d9082610d72565b6001600160a01b0383166000908152602081905260409020556002546120639082610d72565b6002556040516001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906120a49085906145a1565b60405180910390a35050565b6002815110156120bf576104f3565b6000816000815181106120ce57fe5b602002602001015190506000600190505b825181101561124d5760008382815181106120f657fe5b6020026020010151905061211f816001600160a01b0316846001600160a01b0316106065610f13565b91506001016120df565b600073ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1b61214861080f565b6001600160a01b031614158015612163575061216383612a7b565b1561218b5761217061080f565b6001600160a01b0316336001600160a01b03161490506104dc565b612193611c1a565b6001600160a01b0316639be2a8848484306040518463ffffffff1660e01b81526004016121c2939291906145aa565b60206040518083038186803b1580156121da57600080fd5b505afa1580156121ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612212919061412f565b90506104dc565b62461bcd60e51b6000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b4690565b60608061227b611100565b67ffffffffffffffff8111801561229157600080fd5b506040519080825280602002602001820160405280156122bb578160200160208202803683370190505b509050826122ca579050612377565b61233d877f0000000000000000000000000000000000000000000000000000000000000000815181106122f957fe5b6020026020010151877f00000000000000000000000000000000000000000000000000000000000000008151811061232d57fe5b6020026020010151878787612a95565b817f00000000000000000000000000000000000000000000000000000000000000008151811061236957fe5b602090810291909101015290505b95945050505050565b60005b61238b611100565b8110156123e5576123c68482815181106123a157fe5b60200260200101518483815181106123b557fe5b60200260200101518463ffffffff16565b8482815181106123d257fe5b6020908102919091010152600101612383565b50505050565b6000606060006123fa84612a4f565b9050600081600281111561240a57fe5b14156124255761241b868686612b0d565b9250925050612450565b600181600281111561243357fe5b14156124435761241b8685612beb565b61241b868686612c1d565b505b935093915050565b60006124678484610d84612380565b611bb08285611ef1565b60006124808215156004610f13565b81838161248957fe5b049392505050565b6000606060006124a084612a4f565b905060018160028111156124b057fe5b14156124c15761241b868686612c88565b60028160028111156124cf57fe5b14156124e05761241b868686612ce2565b61244e610136612219565b60006124678484610d72612380565b60006125098215156004610f13565b82612516575060006104dc565b81600184038161252257fe5b0460010190506104dc565b600082820261254784158061139157508385838161138e57fe5b806125565760009150506104dc565b670de0b6b3a764000060001982015b046001019150506104dc565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156125d457507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561263557507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561269657507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156126f757507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561275857507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156127b957507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561281a57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611b4257507f00000000000000000000000000000000000000000000000000000000000000006106d5565b600061289d61289287670429d069189e0000612a23565b831115610130610f13565b60006128a98784610d72565b905060006128b78883612992565b905060006128c58887611398565b905060006128d38383612d8a565b90506128e86128e18261296c565b8990612a23565b9a9950505050505050505050565b600061291861290d85670429d069189e0000612a23565b831115610131610f13565b600061292e6129278685610d84565b8690612992565b9050600061293c8588612992565b9050600061294a8383612d8a565b9050600061296082670de0b6b3a7640000610d84565b90506128e88a8261252d565b6000670de0b6b3a764000082106129845760006104dc565b50670de0b6b3a76400000390565b60006129a18215156004610f13565b826129ae575060006104dc565b670de0b6b3a7640000838102906129c8908583816113ce57fe5b82600182038161256557fe5b6000806129e18484612db6565b905060006129fb6129f48361271061252d565b6001610d72565b905080821015612a10576000925050506104dc565b612a1a8282610d84565b925050506104dc565b6000828202612a3d84158061139157508385838161138e57fe5b670de0b6b3a764000090049392505050565b6000818060200190518101906104dc919061428c565b6060818060200190518101906105a19190614352565b6000612a8d631c74c91760e11b610797565b909114919050565b6000838311612aa657506000612377565b6000612ab28585612992565b90506000612ac8670de0b6b3a764000088611398565b9050612adc826709b6e64a8ec60000612ec1565b91506000612aea8383612d8a565b90506000612b01612afa8361296c565b8b90612a23565b90506128e88187612a23565b60006060612b1961108d565b600080612b2585612ed8565b91509150612b3d612b34611100565b82106064610f13565b6060612b47611100565b67ffffffffffffffff81118015612b5d57600080fd5b50604051908082528060200260200182016040528015612b87578160200160208202803683370190505b509050612bc6888381518110612b9957fe5b6020026020010151888481518110612bad57fe5b602002602001015185612bbe6104f6565b600754612efa565b818381518110612bd257fe5b6020908102919091010152919791965090945050505050565b600060606000612bfa84612fb7565b90506060612c108683612c0b6104f6565b612fcd565b9196919550909350505050565b60006060612c2961108d565b60606000612c368561307f565b91509150612c478251610610611100565b612c5382610a5e6113e9565b6000612c6b888885612c636104f6565b600754613097565b9050612c7b8282111560cf610f13565b9791965090945050505050565b60006060806000612c988561307f565b91509150612cae612ca7611100565b8351610d65565b612cba82610a5e6113e9565b6000612cd2888885612cca6104f6565b6007546132bc565b9050612c7b8282101560d0610f13565b60006060600080612cf285612ed8565b91509150612d01612b34611100565b6060612d0b611100565b67ffffffffffffffff81118015612d2157600080fd5b50604051908082528060200260200182016040528015612d4b578160200160208202803683370190505b509050612bc6888381518110612d5d57fe5b6020026020010151888481518110612d7157fe5b602002602001015185612d826104f6565b6007546134cd565b600080612d978484612db6565b90506000612daa6129f48361271061252d565b90506123778282610d72565b600081612dcc5750670de0b6b3a76400006104dc565b82612dd9575060006104dc565b612dea600160ff1b84106006610f13565b82612e10770bce5086492111aea88f4bb1ca6bcf584181ea8059f7653284106007610f13565b826000670c7d713b49da000083138015612e315750670f43fc2c04ee000083125b15612e68576000612e418461356f565b9050670de0b6b3a764000080820784020583670de0b6b3a764000083050201915050612e76565b81612e7284613696565b0290505b670de0b6b3a76400009005612eae680238fd42c5cf03ffff198212801590612ea7575068070c1cc73b00c800008213155b6008610f13565b612eb781613a44565b9695505050505050565b600081831015612ed157816105a1565b5090919050565b60008082806020019051810190612eef919061431c565b909590945092505050565b600080612f1184612f0b8188610d84565b90612992565b9050612f2a6709b6e64a8ec60000821015610132610f13565b6000612f48612f41670de0b6b3a764000089611398565b8390612d8a565b90506000612f5f612f588361296c565b8a90612a23565b90506000612f6c8961296c565b90506000612f7a838361252d565b90506000612f888483610d84565b9050612fa7612fa0612f998a61296c565b8490612a23565b8290610d72565b9c9b505050505050505050505050565b6000818060200190518101906105a191906142ef565b60606000612fdb8484611398565b90506060855167ffffffffffffffff81118015612ff757600080fd5b50604051908082528060200260200182016040528015613021578160200160208202803683370190505b50905060005b8651811015613075576130568388838151811061304057fe5b6020026020010151612a2390919063ffffffff16565b82828151811061306257fe5b6020908102919091010152600101613027565b5095945050505050565b6060600082806020019051810190612eef91906142a8565b60006060845167ffffffffffffffff811180156130b357600080fd5b506040519080825280602002602001820160405280156130dd578160200160208202803683370190505b5090506000805b88518110156131a25761313d8982815181106130fc57fe5b6020026020010151612f0b89848151811061311357fe5b60200260200101518c858151811061312757fe5b6020026020010151610d8490919063ffffffff16565b83828151811061314957fe5b60200260200101818152505061319861319189838151811061316757fe5b602002602001015185848151811061317b57fe5b602002602001015161252d90919063ffffffff16565b8390610d72565b91506001016130e4565b50670de0b6b3a764000060005b895181101561329b5760008482815181106131c657fe5b602002602001015184111561321d5760006131ef6131e38661296c565b8d858151811061304057fe5b90506000613203828c868151811061312757fe5b9050613214613191611c138b61296c565b92505050613234565b88828151811061322957fe5b602002602001015190505b600061325d8c848151811061324557fe5b60200260200101516106b5848f878151811061312757fe5b905061328f6132888c858151811061327157fe5b6020026020010151836129d490919063ffffffff16565b8590612a23565b935050506001016131af565b506132af6132a88261296c565b879061252d565b9998505050505050505050565b60006060845167ffffffffffffffff811180156132d857600080fd5b50604051908082528060200260200182016040528015613302578160200160208202803683370190505b5090506000805b88518110156133aa5761336289828151811061332157fe5b60200260200101516106b589848151811061333857fe5b60200260200101518c858151811061334c57fe5b6020026020010151610d7290919063ffffffff16565b83828151811061336e57fe5b6020026020010181815250506133a061319189838151811061338c57fe5b602002602001015185848151811061304057fe5b9150600101613309565b50670de0b6b3a764000060005b895181101561348b576000838583815181106133cf57fe5b6020026020010151111561342b5760006133f46131e386670de0b6b3a7640000610d84565b90506000613408828c868151811061312757fe5b9050613422613191611f42670de0b6b3a76400008c610d84565b92505050613442565b88828151811061343757fe5b602002602001015190505b600061346b8c848151811061345357fe5b60200260200101516106b5848f878151811061334c57fe5b905061347f6132888c858151811061327157fe5b935050506001016133b7565b50670de0b6b3a764000081106134c1576134b76134b082670de0b6b3a7640000610d84565b8790612a23565b9350505050612377565b60009350505050612377565b6000806134de84612f0b8188610d72565b90506134f76729a2241af62c0000821115610133610f13565b600061350e612f41670de0b6b3a764000089612992565b9050600061352e61352783670de0b6b3a7640000610d84565b8a9061252d565b9050600061353b8961296c565b90506000613549838361252d565b905060006135578483610d84565b9050612fa7612fa06135688a61296c565b8490612992565b670de0b6b3a7640000026000806ec097ce7bc90715b34b9f1000000000808401906ec097ce7bc90715b34b9f0fffffffff19850102816135ab57fe5b05905060006ec097ce7bc90715b34b9f100000000082800205905081806ec097ce7bc90715b34b9f100000000081840205915060038205016ec097ce7bc90715b34b9f100000000082840205915060058205016ec097ce7bc90715b34b9f100000000082840205915060078205016ec097ce7bc90715b34b9f100000000082840205915060098205016ec097ce7bc90715b34b9f1000000000828402059150600b8205016ec097ce7bc90715b34b9f1000000000828402059150600d8205016ec097ce7bc90715b34b9f1000000000828402059150600f826002919005919091010295945050505050565b60006136a6600083136064610f13565b670de0b6b3a76400008212156136e1576136d7826ec097ce7bc90715b34b9f1000000000816136d157fe5b05613696565b60000390506106d5565b60007e1600ef3172e58d2e933ec884fde10064c63b5372d805e203c0000000000000831261373257770195e54c5dd42177f53a27172fa9ec630262827000000000830592506806f05b59d3b2000000015b73011798004d755d3c8bc8e03204cf44619e000000831261376a576b1425982cf597cd205cef7380830592506803782dace9d9000000015b606492830292026e01855144814a7ff805980ff008400083126137b2576e01855144814a7ff805980ff008400068056bc75e2d63100000840205925068ad78ebc5ac62000000015b6b02df0ab5a80a22c61ab5a70083126137ed576b02df0ab5a80a22c61ab5a70068056bc75e2d6310000084020592506856bc75e2d631000000015b693f1fce3da636ea5cf850831261382457693f1fce3da636ea5cf85068056bc75e2d631000008402059250682b5e3af16b18800000015b690127fa27722cc06cc5e2831261385b57690127fa27722cc06cc5e268056bc75e2d6310000084020592506815af1d78b58c400000015b68280e60114edb805d0383126138905768280e60114edb805d0368056bc75e2d631000008402059250680ad78ebc5ac6200000015b680ebc5fb4174612111083126138bb57680ebc5fb4174612111068056bc75e2d631000009384020592015b6808f00f760a4b2db55d83126138f0576808f00f760a4b2db55d68056bc75e2d6310000084020592506802b5e3af16b1880000015b6806f5f17757889379378312613925576806f5f177578893793768056bc75e2d63100000840205925068015af1d78b58c40000015b6806248f33704b2866038312613959576806248f33704b28660368056bc75e2d63100000840205925067ad78ebc5ac620000015b6805c548670b9510e7ac831261398d576805c548670b9510e7ac68056bc75e2d6310000084020592506756bc75e2d6310000015b600068056bc75e2d63100000840168056bc75e2d6310000080860302816139b057fe5b059050600068056bc75e2d63100000828002059050818068056bc75e2d63100000818402059150600382050168056bc75e2d63100000828402059150600582050168056bc75e2d63100000828402059150600782050168056bc75e2d63100000828402059150600982050168056bc75e2d63100000828402059150600b820501600202606485820105979650505050505050565b6000613a73680238fd42c5cf03ffff198312158015613a6c575068070c1cc73b00c800008313155b6009610f13565b6000821215613aa757613a8882600003613a44565b6ec097ce7bc90715b34b9f100000000081613a9f57fe5b0590506106d5565b60006806f05b59d3b20000008312613ae757506806f05b59d3b1ffffff1990910190770195e54c5dd42177f53a27172fa9ec630262827000000000613b1d565b6803782dace9d90000008312613b1957506803782dace9d8ffffff19909101906b1425982cf597cd205cef7380613b1d565b5060015b6064929092029168056bc75e2d6310000068ad78ebc5ac620000008412613b6d5768ad78ebc5ac61ffffff199093019268056bc75e2d631000006e01855144814a7ff805980ff008400082020590505b6856bc75e2d6310000008412613ba9576856bc75e2d630ffffff199093019268056bc75e2d631000006b02df0ab5a80a22c61ab5a70082020590505b682b5e3af16b188000008412613be357682b5e3af16b187fffff199093019268056bc75e2d63100000693f1fce3da636ea5cf85082020590505b6815af1d78b58c4000008412613c1d576815af1d78b58c3fffff199093019268056bc75e2d63100000690127fa27722cc06cc5e282020590505b680ad78ebc5ac62000008412613c5657680ad78ebc5ac61fffff199093019268056bc75e2d6310000068280e60114edb805d0382020590505b68056bc75e2d631000008412613c8f5768056bc75e2d630fffff199093019268056bc75e2d63100000680ebc5fb4174612111082020590505b6802b5e3af16b18800008412613cc8576802b5e3af16b187ffff199093019268056bc75e2d631000006808f00f760a4b2db55d82020590505b68015af1d78b58c400008412613d015768015af1d78b58c3ffff199093019268056bc75e2d631000006806f5f177578893793782020590505b68056bc75e2d631000008481019085906002908280020505918201919050600368056bc75e2d631000008783020505918201919050600468056bc75e2d631000008783020505918201919050600568056bc75e2d631000008783020505918201919050600668056bc75e2d631000008783020505918201919050600768056bc75e2d631000008783020505918201919050600868056bc75e2d631000008783020505918201919050600968056bc75e2d631000008783020505918201919050600a68056bc75e2d631000008783020505918201919050600b68056bc75e2d631000008783020505918201919050600c68056bc75e2d631000008783020505918201919050606468056bc75e2d63100000848402058502059695505050505050565b80356104dc81614708565b600082601f830112613e3d578081fd5b8151613e50613e4b826146e8565b6146c1565b818152915060208083019084810181840286018201871015613e7157600080fd5b60005b84811015613e9057815184529282019290820190600101613e74565b505050505092915050565b600082601f830112613eab578081fd5b813567ffffffffffffffff811115613ec1578182fd5b613ed4601f8201601f19166020016146c1565b9150808252836020828501011115613eeb57600080fd5b8060208401602084013760009082016020015292915050565b8035600281106104dc57600080fd5b600060208284031215613f24578081fd5b81356105a181614708565b60008060408385031215613f41578081fd5b8235613f4c81614708565b91506020830135613f5c81614708565b809150509250929050565b600080600060608486031215613f7b578081fd5b8335613f8681614708565b92506020840135613f9681614708565b929592945050506040919091013590565b600080600080600080600060e0888a031215613fc1578283fd5b8735613fcc81614708565b96506020880135613fdc81614708565b95506040880135945060608801359350608088013560ff81168114613fff578384fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561402e578182fd5b823561403981614708565b946020939093013593505050565b60008060006060848603121561405b578081fd5b835167ffffffffffffffff80821115614072578283fd5b818601915086601f830112614085578283fd5b8151614093613e4b826146e8565b80828252602080830192508086018b8283870289010111156140b3578788fd5b8796505b848710156140de5780516140ca81614708565b8452600196909601959281019281016140b7565b5089015190975093505050808211156140f5578283fd5b5061410286828701613e2d565b925050604084015190509250925092565b600060208284031215614124578081fd5b81356105a18161471d565b600060208284031215614140578081fd5b81516105a18161471d565b600080600080600080600060e0888a031215614165578081fd5b8735965060208089013561417881614708565b9650604089013561418881614708565b9550606089013567ffffffffffffffff808211156141a4578384fd5b818b0191508b601f8301126141b7578384fd5b81356141c5613e4b826146e8565b8082825285820191508585018f8788860288010111156141e3578788fd5b8795505b838610156142055780358352600195909501949186019186016141e7565b509850505060808b0135955060a08b0135945060c08b013592508083111561422b578384fd5b50506142398a828b01613e9b565b91505092959891949750929550565b600060208284031215614259578081fd5b81356001600160e01b0319811681146105a1578182fd5b600060208284031215614281578081fd5b81516105a181614708565b60006020828403121561429d578081fd5b81516105a18161472b565b6000806000606084860312156142bc578081fd5b83516142c78161472b565b602085015190935067ffffffffffffffff8111156142e3578182fd5b61410286828701613e2d565b60008060408385031215614301578182fd5b825161430c8161472b565b6020939093015192949293505050565b600080600060608486031215614330578081fd5b835161433b8161472b565b602085015160409095015190969495509392505050565b60008060408385031215614364578182fd5b825161436f8161472b565b602084015190925067ffffffffffffffff81111561438b578182fd5b61439785828601613e2d565b9150509250929050565b6000806000606084860312156143b5578081fd5b833567ffffffffffffffff808211156143cc578283fd5b81860191506101208083890312156143e2578384fd5b6143eb816146c1565b90506143f78884613f04565b81526144068860208501613e22565b60208201526144188860408501613e22565b6040820152606083013560608201526080830135608082015260a083013560a08201526144488860c08501613e22565b60c082015261445a8860e08501613e22565b60e08201526101008084013583811115614472578586fd5b61447e8a828701613e9b565b9183019190915250976020870135975060409096013595945050505050565b6000602082840312156144ae578081fd5b5035919050565b6000815180845260208085019450808401835b838110156144e4578151875295820195908201906001016144c8565b509495945050505050565b9182526001600160e01b031916602082015260240190565b6000828483379101908152919050565b61190160f01b81526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6000602082526105a160208301846144b5565b60006040825261456c60408301856144b5565b828103602084015261237781856144b5565b901515815260200190565b92151583526020830191909152604082015260600190565b90815260200190565b9283526001600160a01b03918216602084015216604082015260600190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b6000602080835283518082850152825b8181101561467357858101830151858201604001528201614657565b818111156146845783604083870101525b50601f01601f1916929092016040019392505050565b600083825260406020830152611bb060408301846144b5565b60ff91909116815260200190565b60405181810167ffffffffffffffff811182821017156146e057600080fd5b604052919050565b600067ffffffffffffffff8211156146fe578081fd5b5060209081020190565b6001600160a01b03811681146104f357600080fd5b80151581146104f357600080fd5b600381106104f357600080fdfea2646970667358221220a2c3b62e0bc50507598395387e1557612d7ad59e817ddae4d5279907402fedb464736f6c63430007010033", + "deployedBytecode": "", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/test/fixtures/balancerV2.spec.ts b/test/fixtures/balancerV2.spec.ts new file mode 100644 index 000000000..d1dc470e2 --- /dev/null +++ b/test/fixtures/balancerV2.spec.ts @@ -0,0 +1,77 @@ +import "module-alias/register"; + +import { Account } from "@utils/test/types"; + +import { + addSnapshotBeforeRestoreAfterEach, + getAccounts, + getSystemFixture, + getBalancerV2Fixture, +} from "@utils/test/index"; +import { SystemFixture, BalancerV2Fixture } from "@utils/fixtures"; +import { expect } from "chai"; +import { BigNumber } from "@ethersproject/bignumber"; +import { Address } from "@utils/types"; +import { ether } from "@utils/index"; + + +describe("BalancerFixture", () => { + let owner: Account; + + let setup: SystemFixture; + let balancerSetup: BalancerV2Fixture; + + before(async () => { + [ + owner, + ] = await getAccounts(); + + setup = getSystemFixture(owner.address); + balancerSetup = getBalancerV2Fixture(owner.address); + + await setup.initialize(); + }); + + addSnapshotBeforeRestoreAfterEach(); + + describe("#initialize", async () => { + async function subject(): Promise { + await balancerSetup.initialize(owner, setup.weth, setup.dai); + } + + it("should deploy core balancer V2 contacts", async () => { + await subject(); + + expect(balancerSetup.vault).to.exist; + expect(balancerSetup.weightedPoolFactory).to.exist; + }); + + it("should create a WETH-DAI pool", async () => { + await subject(); + + expect(balancerSetup.wethDaiPoolId).to.exist; + }); + }); + + describe("#createPool", async () => { + let subjectTokens: Address[]; + let subjectWeights: BigNumber[]; + + beforeEach(async () => { + await balancerSetup.initialize(owner, setup.weth, setup.dai); + + subjectTokens = [setup.wbtc.address, setup.weth.address]; + subjectWeights = [ether(0.3), ether(0.7)]; + }); + + async function subject(): Promise { + return await balancerSetup.createPool(subjectTokens, subjectWeights); + } + + it("should return a pool id", async () => { + const id = await subject(); + + expect(id).to.not.eq(""); + }); + }); +}); \ No newline at end of file diff --git a/utils/fixtures/balancerV2Fixture.ts b/utils/fixtures/balancerV2Fixture.ts new file mode 100644 index 000000000..6fc9fd85d --- /dev/null +++ b/utils/fixtures/balancerV2Fixture.ts @@ -0,0 +1,66 @@ +import { Signer } from "@ethersproject/abstract-signer"; +import { JsonRpcProvider, Web3Provider } from "@ethersproject/providers"; +import { ether } from "@utils/common"; +import DeployHelper from "@utils/deploys"; +import { Account } from "@utils/test/types"; +import { Address } from "@utils/types"; + +import { StandardTokenMock, WETH9 } from "../contracts/index"; +import { BVault, WeightedPoolFactory } from "../contracts/balancerV2"; +import { BPoolV2__factory } from "../../typechain/factories/BPoolV2__factory"; +import { BigNumber } from "@ethersproject/bignumber"; + +export class BalancerV2Fixture { + private _deployer: DeployHelper; + private _ownerSigner: Signer; + + public owner: Account; + + public vault: BVault; + public weightedPoolFactory: WeightedPoolFactory; + public wethDaiPoolId: string; + + constructor(provider: Web3Provider | JsonRpcProvider, ownerAddress: Address) { + this._ownerSigner = provider.getSigner(ownerAddress); + this._deployer = new DeployHelper(this._ownerSigner); + } + + public async initialize(_owner: Account, _weth: WETH9, _dai: StandardTokenMock): Promise { + this.owner = _owner; + + this.vault = await this._deployer.external.deployBVault(_weth.address); + this.weightedPoolFactory = await this._deployer.external.deployWeightedPoolFactory(this.vault.address); + + const tokens = [ _weth.address, _dai.address ]; + tokens.sort((a, b) => parseInt(a) - parseInt(b)); + + this.wethDaiPoolId = await this.createPool( + [ _weth.address, _dai.address ], + [ ether(0.5), ether(0.5) ] + ); + } + + public async createPool(tokens: Address[], weights: BigNumber[]): Promise { + + const tokenAndWeights = tokens.map((token, i) => { return {address: token, weight: weights[i]}; }); + tokenAndWeights.sort((a, b) => parseInt(a.address) - parseInt(b.address)); + + const tx = await this.weightedPoolFactory.create( + "name", + "symbol", + tokenAndWeights.map(tw => tw.address), + tokenAndWeights.map(tw => tw.weight), + ether(0.001), + this.owner.address + ); + + const receipt = await tx.wait(); + const events = receipt.events?.filter(e => e.event === "PoolCreated"); + if (events) { + const poolAddress = events[0].args?.pool; + return await new BPoolV2__factory(this._ownerSigner).attach(poolAddress).getPoolId(); + } + + return ""; + } +} \ No newline at end of file diff --git a/utils/fixtures/index.ts b/utils/fixtures/index.ts index 7bd918025..2377a791a 100644 --- a/utils/fixtures/index.ts +++ b/utils/fixtures/index.ts @@ -1,6 +1,7 @@ export { AaveFixture } from "./aaveFixture"; export { AaveV2Fixture } from "./aaveV2Fixture"; export { BalancerFixture } from "./balancerFixture"; +export { BalancerV2Fixture } from "./balancerV2Fixture"; export { CompoundFixture } from "./compoundFixture"; export { CurveFixture } from "./curveFixture"; export { KyberV3DMMFixture } from "./kyberV3DMMFixture"; diff --git a/utils/test/index.ts b/utils/test/index.ts index c5c760f3c..5ef0ee8df 100644 --- a/utils/test/index.ts +++ b/utils/test/index.ts @@ -6,6 +6,7 @@ import { AaveFixture, AaveV2Fixture, BalancerFixture, + BalancerV2Fixture, CompoundFixture, CurveFixture, KyberV3DMMFixture, @@ -24,6 +25,7 @@ export const getBlockchainUtils = () => new Blockchain(provider); export const getAaveFixture = (ownerAddress: Address) => new AaveFixture(provider, ownerAddress); export const getAaveV2Fixture = (ownerAdderss: Address) => new AaveV2Fixture(provider, ownerAdderss); export const getBalancerFixture = (ownerAddress: Address) => new BalancerFixture(provider, ownerAddress); +export const getBalancerV2Fixture = (ownerAddress: Address) => new BalancerV2Fixture(provider, ownerAddress); export const getCurveFixture = (ownerAddress: Address) => new CurveFixture(provider, ownerAddress); export const getCompoundFixture = (ownerAddress: Address) => new CompoundFixture(provider, ownerAddress); export const getKyberV3DMMFixture = (ownerAddress: Address) => new KyberV3DMMFixture(provider, ownerAddress); From fbc2106d038ffb7b1546aa92699858c481a74153 Mon Sep 17 00:00:00 2001 From: ncitron Date: Fri, 10 Sep 2021 22:01:01 -0400 Subject: [PATCH 3/9] add BalancerV2IndexExchangeAdapter --- contracts/interfaces/external/IBVault.sol | 30 +++++ .../BalancerV2IndexExchangeAdapter.sol | 124 ++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 contracts/interfaces/external/IBVault.sol create mode 100644 contracts/protocol/integration/index-exchange/BalancerV2IndexExchangeAdapter.sol diff --git a/contracts/interfaces/external/IBVault.sol b/contracts/interfaces/external/IBVault.sol new file mode 100644 index 000000000..111f3c068 --- /dev/null +++ b/contracts/interfaces/external/IBVault.sol @@ -0,0 +1,30 @@ +pragma solidity 0.6.10; +pragma experimental ABIEncoderV2; + +interface IBVault { + + enum SwapKind { GIVEN_IN, GIVEN_OUT } + + function swap( + SingleSwap memory singleSwap, + FundManagement memory funds, + uint256 limit, + uint256 deadline + ) external payable returns (uint256); + + struct SingleSwap { + bytes32 poolId; + SwapKind kind; + address assetIn; + address assetOut; + uint256 amount; + bytes userData; + } + + struct FundManagement { + address sender; + bool fromInternalBalance; + address payable recipient; + bool toInternalBalance; + } +} \ No newline at end of file diff --git a/contracts/protocol/integration/index-exchange/BalancerV2IndexExchangeAdapter.sol b/contracts/protocol/integration/index-exchange/BalancerV2IndexExchangeAdapter.sol new file mode 100644 index 000000000..2d68443de --- /dev/null +++ b/contracts/protocol/integration/index-exchange/BalancerV2IndexExchangeAdapter.sol @@ -0,0 +1,124 @@ +/* + Copyright 2021 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 { IBVault } from "../../../interfaces/external/IBVault.sol"; +import { IIndexExchangeAdapter } from "../../../interfaces/IIndexExchangeAdapter.sol"; + +/** + * @title BalancerV2IndexExchangeAdapter + * @author Set Protocol + * + * A Balancer V2 exchange adapter that returns calldata for trading with GeneralIndexModule, allows trading a fixed input amount or for a fixed + * output amount. + */ +contract BalancerV2IndexExchangeAdapter is IIndexExchangeAdapter { + + /* ============ State Variables ============ */ + + // Address of Balancer V2 vault contract + address public immutable vault; + + // Balancer V2 swap function + string internal constant SWAP = "swap((bytes32,enum,address,address,uint256,bytes),(address,bool,address,bool),uint256,unit256)"; + + + /* ============ Constructor ============ */ + + /** + * Set state variables + * + * @param _vault balancer vault address + */ + constructor(address _vault) public { + vault = _vault; + } + + /* ============ External Getter Functions ============ */ + + /** + * Return calldata for Balancer Vault, _isSendTokenFixed indicates whether a fixed amount of token should be sold for an unfixed amount, or + * if an unfixed amount of token should be spent for a fixed amount. + * + * Note: When _isSendTokenFixed is false, _sourceQuantity is defined as the max token quantity you are willing to trade, and + * _destinationQuantity is the exact quantity of token you are receiving. + * + * @param _sourceToken Address of source token to be sold + * @param _destinationToken Address of destination token to buy + * @param _isSendTokenFixed Boolean indicating if the send quantity is fixed, used to determine correct trade interface + * @param _sourceQuantity Fixed/Max amount of source token to sell + * @param _destinationQuantity Min/Fixed amount of destination tokens to receive + * + * @return address Target contract address + * @return uint256 Call value + * @return bytes Trade calldata + */ + function getTradeCalldata( + address _sourceToken, + address _destinationToken, + address _destinationAddress, + bool _isSendTokenFixed, + uint256 _sourceQuantity, + uint256 _destinationQuantity, + bytes memory _data + ) + external + view + override + returns (address, uint256, bytes memory) + { + bytes32 poolId = abi.decode(_data, (bytes32)); + + IBVault.SingleSwap memory singleSwap = IBVault.SingleSwap({ + poolId: poolId, + kind: _isSendTokenFixed ? IBVault.SwapKind.GIVEN_IN : IBVault.SwapKind.GIVEN_OUT, + assetIn: _sourceToken, + assetOut: _destinationToken, + amount: _isSendTokenFixed ? _sourceQuantity : _destinationQuantity, + userData: "" + }); + + IBVault.FundManagement memory funds = IBVault.FundManagement({ + sender: msg.sender, + fromInternalBalance: false, + recipient: payable(_destinationAddress), + toInternalBalance: false + }); + + bytes memory callData = abi.encodeWithSignature( + SWAP, + singleSwap, + funds, + _isSendTokenFixed ? _destinationQuantity : _sourceQuantity, + uint256(-1) + ); + + return (vault, 0, callData); + } + + /** + * Returns the address to approve source tokens to for trading. This is the Balancer V2 Vault address + * + * @return address Address of the contract to approve tokens to + */ + function getSpender() external view override returns (address) { + return vault; + } +} \ No newline at end of file From dd82c0b7f56d5d3a2957c076a9595bf985ce48b5 Mon Sep 17 00:00:00 2001 From: ncitron Date: Fri, 10 Sep 2021 23:17:55 -0400 Subject: [PATCH 4/9] add calldata tests --- .../BalancerV2IndexExchangeAdapter.sol | 18 +- external/abi/balancer/v2/BVault.json | 1182 ++++++++++++++++- .../balancerV2IndexExchangeAdapter.spec.ts | 194 +++ utils/contracts/index.ts | 1 + utils/deploys/deployAdapters.ts | 6 + 5 files changed, 1389 insertions(+), 12 deletions(-) create mode 100644 test/protocol/integration/index-exchange/balancerV2IndexExchangeAdapter.spec.ts diff --git a/contracts/protocol/integration/index-exchange/BalancerV2IndexExchangeAdapter.sol b/contracts/protocol/integration/index-exchange/BalancerV2IndexExchangeAdapter.sol index 2d68443de..c4db91ccc 100644 --- a/contracts/protocol/integration/index-exchange/BalancerV2IndexExchangeAdapter.sol +++ b/contracts/protocol/integration/index-exchange/BalancerV2IndexExchangeAdapter.sol @@ -36,10 +36,6 @@ contract BalancerV2IndexExchangeAdapter is IIndexExchangeAdapter { // Address of Balancer V2 vault contract address public immutable vault; - // Balancer V2 swap function - string internal constant SWAP = "swap((bytes32,enum,address,address,uint256,bytes),(address,bool,address,bool),uint256,unit256)"; - - /* ============ Constructor ============ */ /** @@ -102,12 +98,14 @@ contract BalancerV2IndexExchangeAdapter is IIndexExchangeAdapter { toInternalBalance: false }); - bytes memory callData = abi.encodeWithSignature( - SWAP, - singleSwap, - funds, - _isSendTokenFixed ? _destinationQuantity : _sourceQuantity, - uint256(-1) + bytes memory callData = abi.encodePacked( + IBVault.swap.selector, + abi.encode( + singleSwap, + funds, + _isSendTokenFixed ? _destinationQuantity : _sourceQuantity, + uint256(-1) + ) ); return (vault, 0, callData); diff --git a/external/abi/balancer/v2/BVault.json b/external/abi/balancer/v2/BVault.json index 8cbaef130..f443f1411 100644 --- a/external/abi/balancer/v2/BVault.json +++ b/external/abi/balancer/v2/BVault.json @@ -1,8 +1,1186 @@ { "contractName": "BVault", - "abi": [{"inputs":[{"internalType":"contract IAuthorizer","name":"authorizer","type":"address"},{"internalType":"contract IWETH","name":"weth","type":"address"},{"internalType":"uint256","name":"pauseWindowDuration","type":"uint256"},{"internalType":"uint256","name":"bufferPeriodDuration","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IAuthorizer","name":"newAuthorizer","type":"address"}],"name":"AuthorizerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ExternalBalanceTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IFlashLoanRecipient","name":"recipient","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeAmount","type":"uint256"}],"name":"FlashLoan","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"int256","name":"delta","type":"int256"}],"name":"InternalBalanceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"PausedStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"liquidityProvider","type":"address"},{"indexed":false,"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"indexed":false,"internalType":"int256[]","name":"deltas","type":"int256[]"},{"indexed":false,"internalType":"uint256[]","name":"protocolFeeAmounts","type":"uint256[]"}],"name":"PoolBalanceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"assetManager","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"int256","name":"cashDelta","type":"int256"},{"indexed":false,"internalType":"int256","name":"managedDelta","type":"int256"}],"name":"PoolBalanceManaged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"poolAddress","type":"address"},{"indexed":false,"internalType":"enum IVault.PoolSpecialization","name":"specialization","type":"uint8"}],"name":"PoolRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"relayer","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"RelayerApprovalChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":true,"internalType":"contract IERC20","name":"tokenIn","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"contract IERC20[]","name":"tokens","type":"address[]"}],"name":"TokensDeregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"assetManagers","type":"address[]"}],"name":"TokensRegistered","type":"event"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum IVault.SwapKind","name":"kind","type":"uint8"},{"components":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"uint256","name":"assetInIndex","type":"uint256"},{"internalType":"uint256","name":"assetOutIndex","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"internalType":"struct IVault.BatchSwapStep[]","name":"swaps","type":"tuple[]"},{"internalType":"contract IAsset[]","name":"assets","type":"address[]"},{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"bool","name":"fromInternalBalance","type":"bool"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"bool","name":"toInternalBalance","type":"bool"}],"internalType":"struct IVault.FundManagement","name":"funds","type":"tuple"},{"internalType":"int256[]","name":"limits","type":"int256[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"batchSwap","outputs":[{"internalType":"int256[]","name":"assetDeltas","type":"int256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"}],"name":"deregisterTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address payable","name":"recipient","type":"address"},{"components":[{"internalType":"contract IAsset[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"minAmountsOut","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"},{"internalType":"bool","name":"toInternalBalance","type":"bool"}],"internalType":"struct IVault.ExitPoolRequest","name":"request","type":"tuple"}],"name":"exitPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IFlashLoanRecipient","name":"recipient","type":"address"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"flashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"getActionId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAuthorizer","outputs":[{"internalType":"contract IAuthorizer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDomainSeparator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"}],"name":"getInternalBalance","outputs":[{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getNextNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPausedState","outputs":[{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"uint256","name":"pauseWindowEndTime","type":"uint256"},{"internalType":"uint256","name":"bufferPeriodEndTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"}],"name":"getPool","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"enum IVault.PoolSpecialization","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"getPoolTokenInfo","outputs":[{"internalType":"uint256","name":"cash","type":"uint256"},{"internalType":"uint256","name":"managed","type":"uint256"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"address","name":"assetManager","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"}],"name":"getPoolTokens","outputs":[{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProtocolFeesCollector","outputs":[{"internalType":"contract ProtocolFeesCollector","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"relayer","type":"address"}],"name":"hasApprovedRelayer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"components":[{"internalType":"contract IAsset[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"maxAmountsIn","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"},{"internalType":"bool","name":"fromInternalBalance","type":"bool"}],"internalType":"struct IVault.JoinPoolRequest","name":"request","type":"tuple"}],"name":"joinPool","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"enum IVault.PoolBalanceOpKind","name":"kind","type":"uint8"},{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IVault.PoolBalanceOp[]","name":"ops","type":"tuple[]"}],"name":"managePoolBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"enum IVault.UserBalanceOpKind","name":"kind","type":"uint8"},{"internalType":"contract IAsset","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct IVault.UserBalanceOp[]","name":"ops","type":"tuple[]"}],"name":"manageUserBalance","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"enum IVault.SwapKind","name":"kind","type":"uint8"},{"components":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"uint256","name":"assetInIndex","type":"uint256"},{"internalType":"uint256","name":"assetOutIndex","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"internalType":"struct IVault.BatchSwapStep[]","name":"swaps","type":"tuple[]"},{"internalType":"contract IAsset[]","name":"assets","type":"address[]"},{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"bool","name":"fromInternalBalance","type":"bool"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"bool","name":"toInternalBalance","type":"bool"}],"internalType":"struct IVault.FundManagement","name":"funds","type":"tuple"}],"name":"queryBatchSwap","outputs":[{"internalType":"int256[]","name":"","type":"int256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum IVault.PoolSpecialization","name":"specialization","type":"uint8"}],"name":"registerPool","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"address[]","name":"assetManagers","type":"address[]"}],"name":"registerTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IAuthorizer","name":"newAuthorizer","type":"address"}],"name":"setAuthorizer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"relayer","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setRelayerApproval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"enum IVault.SwapKind","name":"kind","type":"uint8"},{"internalType":"contract IAsset","name":"assetIn","type":"address"},{"internalType":"contract IAsset","name":"assetOut","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"internalType":"struct IVault.SingleSwap","name":"singleSwap","type":"tuple"},{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"bool","name":"fromInternalBalance","type":"bool"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"bool","name":"toInternalBalance","type":"bool"}],"internalType":"struct IVault.FundManagement","name":"funds","type":"tuple"},{"internalType":"uint256","name":"limit","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swap","outputs":[{"internalType":"uint256","name":"amountCalculated","type":"uint256"}],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}], + "abi": [ + { + "inputs": [ + { + "internalType": "contract IAuthorizer", + "name": "authorizer", + "type": "address" + }, + { + "internalType": "contract IWETH", + "name": "weth", + "type": "address" + }, + { + "internalType": "uint256", + "name": "pauseWindowDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "bufferPeriodDuration", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IAuthorizer", + "name": "newAuthorizer", + "type": "address" + } + ], + "name": "AuthorizerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ExternalBalanceTransfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IFlashLoanRecipient", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + } + ], + "name": "FlashLoan", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "delta", + "type": "int256" + } + ], + "name": "InternalBalanceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "PausedStateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "liquidityProvider", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "int256[]", + "name": "deltas", + "type": "int256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "protocolFeeAmounts", + "type": "uint256[]" + } + ], + "name": "PoolBalanceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "assetManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "cashDelta", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "managedDelta", + "type": "int256" + } + ], + "name": "PoolBalanceManaged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "enum IVault.PoolSpecialization", + "name": "specialization", + "type": "uint8" + } + ], + "name": "PoolRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "RelayerApprovalChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "tokenIn", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "tokenOut", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "TokensDeregistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "assetManagers", + "type": "address[]" + } + ], + "name": "TokensRegistered", + "type": "event" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [ + { + "internalType": "contract IWETH", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum IVault.SwapKind", + "name": "kind", + "type": "uint8" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "assetInIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assetOutIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + } + ], + "internalType": "struct IVault.BatchSwapStep[]", + "name": "swaps", + "type": "tuple[]" + }, + { + "internalType": "contract IAsset[]", + "name": "assets", + "type": "address[]" + }, + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bool", + "name": "fromInternalBalance", + "type": "bool" + }, + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "toInternalBalance", + "type": "bool" + } + ], + "internalType": "struct IVault.FundManagement", + "name": "funds", + "type": "tuple" + }, + { + "internalType": "int256[]", + "name": "limits", + "type": "int256[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "batchSwap", + "outputs": [ + { + "internalType": "int256[]", + "name": "assetDeltas", + "type": "int256[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "deregisterTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract IAsset[]", + "name": "assets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "minAmountsOut", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + }, + { + "internalType": "bool", + "name": "toInternalBalance", + "type": "bool" + } + ], + "internalType": "struct IVault.ExitPoolRequest", + "name": "request", + "type": "tuple" + } + ], + "name": "exitPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IFlashLoanRecipient", + "name": "recipient", + "type": "address" + }, + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + } + ], + "name": "flashLoan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "selector", + "type": "bytes4" + } + ], + "name": "getActionId", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAuthorizer", + "outputs": [ + { + "internalType": "contract IAuthorizer", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDomainSeparator", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "getInternalBalance", + "outputs": [ + { + "internalType": "uint256[]", + "name": "balances", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getNextNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPausedState", + "outputs": [ + { + "internalType": "bool", + "name": "paused", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "pauseWindowEndTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "bufferPeriodEndTime", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + } + ], + "name": "getPool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "enum IVault.PoolSpecialization", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "getPoolTokenInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "managed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastChangeBlock", + "type": "uint256" + }, + { + "internalType": "address", + "name": "assetManager", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + } + ], + "name": "getPoolTokens", + "outputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "balances", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "lastChangeBlock", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProtocolFeesCollector", + "outputs": [ + { + "internalType": "contract ProtocolFeesCollector", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "hasApprovedRelayer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract IAsset[]", + "name": "assets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "maxAmountsIn", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + }, + { + "internalType": "bool", + "name": "fromInternalBalance", + "type": "bool" + } + ], + "internalType": "struct IVault.JoinPoolRequest", + "name": "request", + "type": "tuple" + } + ], + "name": "joinPool", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum IVault.PoolBalanceOpKind", + "name": "kind", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct IVault.PoolBalanceOp[]", + "name": "ops", + "type": "tuple[]" + } + ], + "name": "managePoolBalance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum IVault.UserBalanceOpKind", + "name": "kind", + "type": "uint8" + }, + { + "internalType": "contract IAsset", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + } + ], + "internalType": "struct IVault.UserBalanceOp[]", + "name": "ops", + "type": "tuple[]" + } + ], + "name": "manageUserBalance", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum IVault.SwapKind", + "name": "kind", + "type": "uint8" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "assetInIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assetOutIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + } + ], + "internalType": "struct IVault.BatchSwapStep[]", + "name": "swaps", + "type": "tuple[]" + }, + { + "internalType": "contract IAsset[]", + "name": "assets", + "type": "address[]" + }, + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bool", + "name": "fromInternalBalance", + "type": "bool" + }, + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "toInternalBalance", + "type": "bool" + } + ], + "internalType": "struct IVault.FundManagement", + "name": "funds", + "type": "tuple" + } + ], + "name": "queryBatchSwap", + "outputs": [ + { + "internalType": "int256[]", + "name": "", + "type": "int256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum IVault.PoolSpecialization", + "name": "specialization", + "type": "uint8" + } + ], + "name": "registerPool", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "assetManagers", + "type": "address[]" + } + ], + "name": "registerTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IAuthorizer", + "name": "newAuthorizer", + "type": "address" + } + ], + "name": "setAuthorizer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "setPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "relayer", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setRelayerApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "internalType": "enum IVault.SwapKind", + "name": "kind", + "type": "uint8" + }, + { + "internalType": "contract IAsset", + "name": "assetIn", + "type": "address" + }, + { + "internalType": "contract IAsset", + "name": "assetOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + } + ], + "internalType": "struct IVault.SingleSwap", + "name": "singleSwap", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bool", + "name": "fromInternalBalance", + "type": "bool" + }, + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "toInternalBalance", + "type": "bool" + } + ], + "internalType": "struct IVault.FundManagement", + "name": "funds", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "uint256", + "name": "amountCalculated", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], "bytecode": "6101806040523480156200001257600080fd5b5060405162006ed638038062006ed6833981016040819052620000359162000253565b8382826040518060400160405280601181526020017010985b185b98d95c88158c8815985d5b1d607a1b81525080604051806040016040528060018152602001603160f81b815250306001600160a01b031660001b89806001600160a01b03166080816001600160a01b031660601b815250505030604051620000b89062000245565b620000c491906200029f565b604051809103906000f080158015620000e1573d6000803e3d6000fd5b5060601b6001600160601b03191660a052600160005560c052815160209283012060e052805191012061010052507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61012052620001486276a70083111561019462000181565b6200015c62278d0082111561019562000181565b429091016101408190520161016052620001768162000196565b5050505050620002cc565b8162000192576200019281620001f2565b5050565b6040516001600160a01b038216907f94b979b6831a51293e2641426f97747feed46f17779fed9cd18d1ecefcfe92ef90600090a2600380546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b62461bcd60e51b6000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b610be680620062f083390190565b6000806000806080858703121562000269578384fd5b84516200027681620002b3565b60208601519094506200028981620002b3565b6040860151606090960151949790965092505050565b6001600160a01b0391909116815260200190565b6001600160a01b0381168114620002c957600080fd5b50565b60805160601c60a05160601c60c05160e05161010051610120516101405161016051615fc06200033060003980611aed525080611ac952508061289f5250806128e15250806128c05250806110fd5250806113b15250806105285250615fc06000f3fe6080604052600436106101a55760003560e01c8063945bcec9116100e1578063e6c460921161008a578063f84d066e11610064578063f84d066e1461048a578063f94d4668146104aa578063fa6e671d146104d9578063fec90d72146104f9576101d3565b8063e6c4609214610427578063ed24911d14610447578063f6c009271461045c576101d3565b8063b05f8e48116100bb578063b05f8e48146103cf578063b95cac28146103ff578063d2946c2b14610412576101d3565b8063945bcec914610385578063aaabadc514610398578063ad5c4648146103ba576101d3565b806352bbbe291161014e5780637d3aeb96116101285780637d3aeb9614610305578063851c1bb3146103255780638bdb39131461034557806390193b7c14610365576101d3565b806352bbbe29146102b25780635c38449e146102c557806366a9c7d2146102e5576101d3565b80630f5a6efa1161017f5780630f5a6efa1461024157806316c38b3c1461026e5780631c0de0511461028e576101d3565b8063058a628f146101d857806309b2760f146101f85780630e8e3e841461022e576101d3565b366101d3576101d16101b5610526565b6001600160a01b0316336001600160a01b03161461020661054b565b005b600080fd5b3480156101e457600080fd5b506101d16101f3366004615157565b61055d565b34801561020457600080fd5b506102186102133660046156e6565b610581565b6040516102259190615d3e565b60405180910390f35b6101d161023c36600461531e565b610634565b34801561024d57600080fd5b5061026161025c3660046151f5565b610770565b6040516102259190615d08565b34801561027a57600080fd5b506101d161028936600461545c565b610806565b34801561029a57600080fd5b506102a361081f565b60405161022593929190615d26565b6102186102c036600461588f565b610848565b3480156102d157600080fd5b506101d16102e036600461565b565b6109e9565b3480156102f157600080fd5b506101d1610300366004615545565b610e06565b34801561031157600080fd5b506101d1610320366004615516565b610fa5565b34801561033157600080fd5b50610218610340366004615633565b6110f9565b34801561035157600080fd5b506101d16103603660046154ac565b61114b565b34801561037157600080fd5b50610218610380366004615157565b611161565b610261610393366004615786565b61117c565b3480156103a457600080fd5b506103ad6112b0565b6040516102259190615b63565b3480156103c657600080fd5b506103ad6112c4565b3480156103db57600080fd5b506103ef6103ea36600461560f565b6112d3565b6040516102259493929190615eb9565b6101d161040d3660046154ac565b611396565b34801561041e57600080fd5b506103ad6113af565b34801561043357600080fd5b506101d1610442366004615243565b6113d3565b34801561045357600080fd5b506102186114ef565b34801561046857600080fd5b5061047c610477366004615494565b6114f9565b604051610225929190615b9b565b34801561049657600080fd5b506102616104a5366004615702565b611523565b3480156104b657600080fd5b506104ca6104c5366004615494565b611620565b60405161022593929190615cd2565b3480156104e557600080fd5b506101d16104f43660046151ab565b611654565b34801561050557600080fd5b50610519610514366004615173565b6116e6565b6040516102259190615d1b565b7f00000000000000000000000000000000000000000000000000000000000000005b90565b8161055957610559816116fb565b5050565b610565611768565b61056d611781565b610576816117af565b61057e611822565b50565b600061058b611768565b610593611829565b60006105a2338460065461183e565b6000818152600560205260409020549091506105c49060ff16156101f461054b565b60008181526005602052604090819020805460ff1916600190811790915560068054909101905551339082907f3c13bc30b8e878c53fd2a36b679409c073afd75950be43d8858768e956fbc20e9061061d908790615e3a565b60405180910390a3905061062f611822565b919050565b61063c611768565b6000806000805b845181101561075b5760008060008060006106718a878151811061066357fe5b60200260200101518961187d565b9c50939850919650945092509050600185600381111561068d57fe5b14156106a45761069f848383866118f5565b61074a565b866106b6576106b1611829565b600196505b60008560038111156106c457fe5b14156106f5576106d684838386611918565b6106df84611938565b1561069f576106ee8984611945565b985061074a565b61070a61070185611938565b1561020761054b565b600061071585610548565b9050600286600381111561072557fe5b141561073c5761073781848487611957565b610748565b61074881848487611970565b505b505060019093019250610643915050565b50610765836119de565b50505061057e611822565b6060815167ffffffffffffffff8111801561078a57600080fd5b506040519080825280602002602001820160405280156107b4578160200160208202803683370190505b50905060005b82518110156107ff576107e0848483815181106107d357fe5b6020026020010151611a01565b8282815181106107ec57fe5b60209081029190910101526001016107ba565b5092915050565b61080e611768565b610816611781565b61057681611a2c565b600080600061082c611aaa565b159250610837611ac7565b9150610841611aeb565b9050909192565b6000610852611768565b61085a611829565b835161086581611b0f565b610874834211156101fc61054b565b61088760008760800151116101fe61054b565b60006108968760400151611b41565b905060006108a78860600151611b41565b90506108ca816001600160a01b0316836001600160a01b031614156101fd61054b565b6108d2614ce1565b885160808201526020890151819060018111156108eb57fe5b908160018111156108f857fe5b9052506001600160a01b03808416602083015282811660408084019190915260808b0151606084015260a08b01516101008401528951821660c08401528901511660e082015260008061094a83611b66565b9198509250905061098160008c60200151600181111561096657fe5b146109745789831115610979565b898210155b6101fb61054b565b6109998b60400151838c600001518d60200151611c5a565b6109b18b60600151828c604001518d60600151611d38565b6109d36109c18c60400151611938565b6109cc5760006109ce565b825b6119de565b5050505050506109e1611822565b949350505050565b6109f1611768565b6109f9611829565b610a0583518351611e12565b6060835167ffffffffffffffff81118015610a1f57600080fd5b50604051908082528060200260200182016040528015610a49578160200160208202803683370190505b5090506060845167ffffffffffffffff81118015610a6657600080fd5b50604051908082528060200260200182016040528015610a90578160200160208202803683370190505b5090506000805b8651811015610c09576000878281518110610aae57fe5b602002602001015190506000878381518110610ac657fe5b60200260200101519050610b11846001600160a01b0316836001600160a01b03161160006001600160a01b0316846001600160a01b031614610b09576066610b0c565b60685b61054b565b819350816001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610b409190615b63565b60206040518083038186803b158015610b5857600080fd5b505afa158015610b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b909190615968565b858481518110610b9c57fe5b602002602001018181525050610bb181611e1f565b868481518110610bbd57fe5b602002602001018181525050610beb81868581518110610bd957fe5b6020026020010151101561021061054b565b610bff6001600160a01b0383168b83611ea6565b5050600101610a97565b506040517ff04f27070000000000000000000000000000000000000000000000000000000081526001600160a01b0388169063f04f270790610c55908990899088908a90600401615c85565b600060405180830381600087803b158015610c6f57600080fd5b505af1158015610c83573d6000803e3d6000fd5b5050505060005b8651811015610df4576000878281518110610ca157fe5b602002602001015190506000848381518110610cb957fe5b602002602001015190506000826001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610cf19190615b63565b60206040518083038186803b158015610d0957600080fd5b505afa158015610d1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d419190615968565b9050610d528282101561020361054b565b60008282039050610d7b888681518110610d6857fe5b602002602001015182101561025a61054b565b610d858482611f11565b836001600160a01b03168c6001600160a01b03167f0d7d75e01ab95780d3cd1c8ec0dd6c2ce19e3a20427eec8bf53283b6fb8e95f08c8881518110610dc657fe5b602002602001015184604051610ddd929190615e4d565b60405180910390a350505050806001019050610c8a565b50505050610e00611822565b50505050565b610e0e611768565b610e16611829565b82610e2081611f33565b610e2c83518351611e12565b60005b8351811015610eca576000848281518110610e4657fe5b60200260200101519050610e7260006001600160a01b0316826001600160a01b0316141561013561054b565b838281518110610e7e57fe5b6020908102919091018101516000888152600a835260408082206001600160a01b0395861683529093529190912080546001600160a01b03191692909116919091179055600101610e2f565b506000610ed685611f64565b90506002816002811115610ee657fe5b1415610f3457610efc845160021461020c61054b565b610f2f8585600081518110610f0d57fe5b602002602001015186600181518110610f2257fe5b6020026020010151611f7e565b610f5c565b6001816002811115610f4257fe5b1415610f5257610f2f858561202a565b610f5c8585612082565b847ff5847d3f2197b16cdcd2098ec95d0905cd1abdaf415f07bb7cef2bba8ac5dec48585604051610f8e929190615bed565b60405180910390a25050610fa0611822565b505050565b610fad611768565b610fb5611829565b81610fbf81611f33565b6000610fca84611f64565b90506002816002811115610fda57fe5b141561102857610ff0835160021461020c61054b565b611023848460008151811061100157fe5b60200260200101518560018151811061101657fe5b60200260200101516120d7565b611050565b600181600281111561103657fe5b1415611046576110238484612145565b61105084846121ff565b60005b83518110156110b657600a6000868152602001908152602001600020600085838151811061107d57fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055600101611053565b50837f7dcdc6d02ef40c7c1a7046a011b058bd7f988fa14e20a66344f9d4e60657d610846040516110e79190615bda565b60405180910390a25050610559611822565b60007f00000000000000000000000000000000000000000000000000000000000000008260405160200161112e929190615ac2565b604051602081830303815290604052805190602001209050919050565b610e00600185858561115c86612262565b61226e565b6001600160a01b031660009081526002602052604090205490565b6060611186611768565b61118e611829565b835161119981611b0f565b6111a8834211156101fc61054b565b6111b486518551611e12565b6111c08787878b6123f4565b91506000805b87518110156112925760008882815181106111dd57fe5b6020026020010151905060008583815181106111f557fe5b6020026020010151905061122188848151811061120e57fe5b60200260200101518213156101fb61054b565b600081131561126157885160208a015182916112409185918491611c5a565b61124983611938565b1561125b576112588582611945565b94505b50611288565b600081121561128857600081600003905061128683828c604001518d60600151611d38565b505b50506001016111c6565b5061129c816119de565b50506112a6611822565b9695505050505050565b60035461010090046001600160a01b031690565b60006112ce610526565b905090565b600080600080856112e381612683565b6000806112ef89611f64565b905060028160028111156112ff57fe5b14156113165761130f89896126a1565b9150611341565b600181600281111561132457fe5b14156113345761130f898961271b565b61133e8989612789565b91505b61134a826127a1565b9650611355826127b4565b9550611360826127ca565b6000998a52600a60209081526040808c206001600160a01b039b8c168d5290915290992054969995989796909616955050505050565b61139e611829565b610e00600085858561115c86612262565b7f000000000000000000000000000000000000000000000000000000000000000090565b6113db611768565b6113e3611829565b6113eb614d31565b60005b82518110156114e55782818151811061140357fe5b6020026020010151915060008260200151905061141f81612683565b604083015161143961143183836127d0565b61020961054b565b6000828152600a602090815260408083206001600160a01b03858116855292529091205461146c911633146101f661054b565b835160608501516000806114828487878661282c565b91509150846001600160a01b0316336001600160a01b0316877f6edcaf6241105b4c94c2efdbf3a6b12458eb3d07be3a0e81d24b13c44045fe7a85856040516114cc929190615e4d565b60405180910390a45050505050508060010190506113ee565b505061057e611822565b60006112ce61289b565b6000808261150681612683565b61150f84612938565b61151885611f64565b925092505b50915091565b60603330146115f6576000306001600160a01b0316600036604051611549929190615ada565b6000604051808303816000865af19150503d8060008114611586576040519150601f19603f3d011682016040523d82523d6000602084013e61158b565b606091505b50509050806000811461159a57fe5b60046000803e6000516001600160e01b0319167ffa61cc120000000000000000000000000000000000000000000000000000000081146115de573d6000803e3d6000fd5b50602060005260043d0380600460203e602081016000f35b6060611604858585896123f4565b9050602081510263fa61cc126020830352600482036024820181fd5b60608060008361162f81612683565b606061163a8661293e565b9095509050611648816129a0565b95979096509350505050565b61165c611768565b611664611829565b8261166e81611b0f565b6001600160a01b0384811660008181526004602090815260408083209488168084529490915290819020805460ff1916861515179055519091907f46961fdb4502b646d5095fba7600486a8ac05041d55cdf0f16ed677180b5cad8906116d5908690615d1b565b60405180910390a350610fa0611822565b60006116f28383612a4f565b90505b92915050565b7f08c379a0000000000000000000000000000000000000000000000000000000006000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b61177a6002600054141561019061054b565b6002600055565b60006117986000356001600160e01b0319166110f9565b905061057e6117a78233612a7d565b61019161054b565b6040516001600160a01b038216907f94b979b6831a51293e2641426f97747feed46f17779fed9cd18d1ecefcfe92ef90600090a2600380546001600160a01b03909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b6001600055565b61183c611834611aaa565b61019261054b565b565b600069ffffffffffffffffffff8216605084600281111561185b57fe5b901b17606085901b6bffffffffffffffffffffffff19161790505b9392505050565b600080600080600080600088606001519050336001600160a01b0316816001600160a01b0316146118cf57876118ba576118b5611781565b600197505b6118cf6118c78233612a4f565b6101f761054b565b885160208a015160408b01516080909b0151919b909a9992985090965090945092505050565b61190a8361190286611b41565b836000612b20565b50610e008482846000611d38565b61192b8261192586611b41565b83612b76565b610e008482856000611c5a565b6001600160a01b03161590565b60008282016116f2848210158361054b565b6119648385836000612b20565b50610e00828583612b76565b8015610e005761198b6001600160a01b038516848484612ba6565b826001600160a01b0316846001600160a01b03167f540a1a3f28340caec336c81d8d7b3df139ee5cdc1839a4f283d7ebb7eaae2d5c84846040516119d0929190615bc1565b60405180910390a350505050565b6119ed8134101561020461054b565b348190038015610559576105593382612bc7565b6001600160a01b039182166000908152600b6020908152604080832093909416825291909152205490565b8015611a4c57611a47611a3d611ac7565b421061019361054b565b611a61565b611a61611a57611aeb565b42106101a961054b565b6003805460ff19168215151790556040517f9e3a5e37224532dea67b89face185703738a228a6e8a23dee546960180d3be6490611a9f908390615d1b565b60405180910390a150565b6000611ab4611aeb565b4211806112ce57505060035460ff161590565b7f000000000000000000000000000000000000000000000000000000000000000090565b7f000000000000000000000000000000000000000000000000000000000000000090565b336001600160a01b0382161461057e57611b27611781565b611b318133612a4f565b61057e5761057e816101f7612c41565b6000611b4c82611938565b611b5e57611b5982610548565b6116f5565b6116f5610526565b600080600080611b798560800151612938565b90506000611b8a8660800151611f64565b90506002816002811115611b9a57fe5b1415611bb157611baa8683612c75565b9450611bdc565b6001816002811115611bbf57fe5b1415611bcf57611baa8683612d25565b611bd98683612db8565b94505b611bef8660000151876060015187612ff7565b809450819550505085604001516001600160a01b031686602001516001600160a01b031687608001517f2170c741c41531aec20e7c107c24eecfdd15e69c9bb0a8dd37b1840b9e0b207b8787604051611c49929190615e4d565b60405180910390a450509193909250565b82611c6457610e00565b611c6d84611938565b15611cee57611c7f811561020261054b565b611c8e8347101561020461054b565b611c96610526565b6001600160a01b031663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b158015611cd057600080fd5b505af1158015611ce4573d6000803e3d6000fd5b5050505050610e00565b6000611cf985610548565b90508115611d16576000611d108483876001612b20565b90940393505b8315611d3157611d316001600160a01b038216843087612ba6565b5050505050565b82611d4257610e00565b611d4b84611938565b15611ddb57611d5d811561020261054b565b611d65610526565b6001600160a01b0316632e1a7d4d846040518263ffffffff1660e01b8152600401611d909190615d3e565b600060405180830381600087803b158015611daa57600080fd5b505af1158015611dbe573d6000803e3d6000fd5b50611dd6925050506001600160a01b03831684612bc7565b610e00565b6000611de685610548565b90508115611dfe57611df9838286612b76565b611d31565b611d316001600160a01b0382168486611ea6565b610559818314606761054b565b600080611e2a6113af565b6001600160a01b031663d877845c6040518163ffffffff1660e01b815260040160206040518083038186803b158015611e6257600080fd5b505afa158015611e76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9a9190615968565b90506118768382613025565b610fa08363a9059cbb60e01b8484604051602401611ec5929190615bc1565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b031990931692909217909152613072565b801561055957610559611f226113af565b6001600160a01b0384169083611ea6565b611f3c81612683565b61057e611f4882612938565b6001600160a01b0316336001600160a01b0316146101f561054b565b600061ffff605083901c166116f5600382106101f461054b565b611f9f816001600160a01b0316836001600160a01b0316141561020a61054b565b611fbe816001600160a01b0316836001600160a01b031610606661054b565b60008381526009602052604090208054611ffb906001600160a01b0316158015611ff3575060018201546001600160a01b0316155b61020b61054b565b80546001600160a01b039384166001600160a01b03199182161782556001909101805492909316911617905550565b6000828152600860205260408120905b8251811015610e0057600061206b84838151811061205457fe5b60200260200101518461311290919063ffffffff16565b90506120798161020a61054b565b5060010161203a565b6000828152600160205260408120905b8251811015610e005760006120c08483815181106120ac57fe5b602090810291909101015184906000613175565b90506120ce8161020a61054b565b50600101612092565b60008060006120e7868686613222565b9250925092506121116120f9846132e9565b80156121095750612109836132e9565b61020d61054b565b600095865260096020526040862080546001600160a01b031990811682556001909101805490911690559490945550505050565b6000828152600860205260408120905b8251811015610e0057600083828151811061216c57fe5b602002602001015190506121b8612109600760008881526020019081526020016000206000846001600160a01b03166001600160a01b03168152602001908152602001600020546132e9565b60008581526007602090815260408083206001600160a01b038516845290915281208190556121e7848361330b565b90506121f58161020961054b565b5050600101612155565b6000828152600160205260408120905b8251811015610e0057600083828151811061222657fe5b60200260200101519050600061223c8483613412565b905061224a612109826132e9565b6122548483613421565b50505080600101905061220f565b61226a614d5a565b5090565b612276611768565b8361228081612683565b8361228a81611b0f565b61229e836000015151846020015151611e12565b60606122ad84600001516134c3565b905060606122bb8883613552565b905060608060606122d08c8c8c8c8c896135e3565b92509250925060006122e18c611f64565b905060028160028111156122f157fe5b1415612359576123548c8760008151811061230857fe5b60200260200101518660008151811061231d57fe5b60200260200101518960018151811061233257fe5b60200260200101518860018151811061234757fe5b60200260200101516137a8565b612382565b600181600281111561236757fe5b1415612378576123548c87866137e7565b6123828c85613854565b6000808e600181111561239157fe5b1490508b6001600160a01b03168d7fe5ce249087ce04f05a957192435400fd97868dba0e6a4b4c049abf8af80dae78896123cb888661389d565b876040516123db93929190615c4c565b60405180910390a3505050505050505050611d31611822565b6060835167ffffffffffffffff8111801561240e57600080fd5b50604051908082528060200260200182016040528015612438578160200160208202803683370190505b509050612443614d84565b61244b614ce1565b60008060005b89518110156126765789818151811061246657fe5b6020026020010151945060008951866020015110801561248a575089518660400151105b905061249781606461054b565b60006124b98b8860200151815181106124ac57fe5b6020026020010151611b41565b905060006124d08c8960400151815181106124ac57fe5b90506124f3816001600160a01b0316836001600160a01b031614156101fd61054b565b60608801516125435761250b600085116101fe61054b565b60006125188b8484613945565b6001600160a01b0316876001600160a01b031614905061253a816101ff61054b565b50606088018590525b87516080880152868a600181111561255757fe5b9081600181111561256457fe5b9052506001600160a01b0380831660208901528181166040808a01919091526060808b0151908a015260808a01516101008a01528c51821660c08a01528c01511660e08801526000806125b689611b66565b919850925090506125c88c8585613967565b97506125fc6125d683613981565b8c8c60200151815181106125e657fe5b60200260200101516139b190919063ffffffff16565b8b8b602001518151811061260c57fe5b60200260200101818152505061264a61262482613981565b8c8c604001518151811061263457fe5b60200260200101516139e590919063ffffffff16565b8b8b604001518151811061265a57fe5b6020026020010181815250505050505050806001019050612451565b5050505050949350505050565b60008181526005602052604090205461057e9060ff166101f461054b565b60008060008060006126b287613a19565b945094509450945050836001600160a01b0316866001600160a01b031614156126e157829450505050506116f5565b816001600160a01b0316866001600160a01b031614156127065793506116f592505050565b6127116102096116fb565b5050505092915050565b60008281526007602090815260408083206001600160a01b03851684529091528120548161274882613a8f565b80612766575060008581526008602052604090206127669085613aa1565b9050806127815761277685612683565b6127816102096116fb565b509392505050565b60008281526001602052604081206109e18184613412565b6dffffffffffffffffffffffffffff1690565b60701c6dffffffffffffffffffffffffffff1690565b60e01c90565b6000806127dc84611f64565b905060028160028111156127ec57fe5b1415612804576127fc8484613ac2565b9150506116f5565b600181600281111561281257fe5b1415612822576127fc8484613b13565b6127fc8484613b2b565b600080600061283a86611f64565b9050600087600281111561284a57fe5b14156128665761285c86828787613b43565b9250925050612892565b600187600281111561287457fe5b14156128865761285c86828787613bbe565b61285c86828787613c3a565b94509492505050565b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612908613c9d565b3060405160200161291d959493929190615df0565b60405160208183030381529060405280519060200120905090565b60601c90565b606080600061294c84611f64565b9050600281600281111561295c57fe5b14156129755761296b84613ca1565b925092505061299b565b600181600281111561298357fe5b14156129925761296b84613dd6565b61296b84613efd565b915091565b60606000825167ffffffffffffffff811180156129bc57600080fd5b506040519080825280602002602001820160405280156129e6578160200160208202803683370190505b5091506000905060005b825181101561151d576000848281518110612a0757fe5b60200260200101519050612a1a81613ff9565b848381518110612a2657fe5b602002602001018181525050612a4483612a3f836127ca565b614014565b9250506001016129f0565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205460ff1690565b6003546040517f9be2a88400000000000000000000000000000000000000000000000000000000815260009161010090046001600160a01b031690639be2a88490612ad090869086903090600401615d47565b60206040518083038186803b158015612ae857600080fd5b505afa158015612afc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f29190615478565b600080612b2d8686611a01565b9050612b468380612b3e5750848210155b61020161054b565b612b50818561402b565b9150818103612b6c878783612b6487613981565b60000361403a565b5050949350505050565b6000612b828484611a01565b90506000612b908284611945565b9050611d31858583612ba187613981565b61403a565b610e00846323b872dd60e01b858585604051602401611ec593929190615b77565b612bd6814710156101a361054b565b6000826001600160a01b031682604051612bef90610548565b60006040518083038185875af1925050503d8060008114612c2c576040519150601f19603f3d011682016040523d82523d6000602084013e612c31565b606091505b50509050610fa0816101a461054b565b6001600160a01b0382166000908152600260205260409020805460018101909155610fa0612c6f8483614095565b8361054b565b600080600080612c92866080015187602001518860400151613222565b92509250925060008087604001516001600160a01b031688602001516001600160a01b03161015612cc7575083905082612ccd565b50829050835b612cd9888884846141bb565b60408b015160208c01519199509294509092506001600160a01b03918216911610612d0d57612d0881836142d1565b612d17565b612d1782826142d1565b909255509295945050505050565b600080612d3a8460800151856020015161271b565b90506000612d508560800151866040015161271b565b9050612d5e858584846141bb565b6080880180516000908152600760208181526040808420828e01516001600160a01b03908116865290835281852098909855935183529081528282209a830151909516815298909352919096209590955550929392505050565b60808201516000908152600160209081526040822090840151829182918290612de290839061430c565b90506000612dfd88604001518461430c90919063ffffffff16565b9050811580612e0a575080155b15612e2757612e1c8860800151612683565b612e276102096116fb565b60001991820191016000612e3a8461432b565b905060608167ffffffffffffffff81118015612e5557600080fd5b50604051908082528060200260200182016040528015612e7f578160200160208202803683370190505b50600060a08c018190529091505b82811015612eff576000612ea1878361432f565b9050612eac81613ff9565b838381518110612eb857fe5b602002602001018181525050612ed58c60a00151612a3f836127ca565b60a08d015281861415612eea57809850612ef6565b84821415612ef6578097505b50600101612e8d565b506040517f01ec954a0000000000000000000000000000000000000000000000000000000081526001600160a01b038a16906301ec954a90612f4b908d90859089908990600401615e5b565b602060405180830381600087803b158015612f6557600080fd5b505af1158015612f79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f9d9190615968565b9750600080612fb58c600001518d606001518c612ff7565b9092509050612fc48983614345565b9850612fd08882614376565b9750612fdd87878b61438c565b612fe887868a61438c565b50505050505050505092915050565b6000808085600181111561300757fe5b141561301757508290508161301d565b50819050825b935093915050565b600082820261304984158061304257508385838161303f57fe5b04145b600361054b565b806130585760009150506116f5565b670de0b6b3a76400006000198201046001019150506116f5565b60006060836001600160a01b03168360405161308e9190615aea565b6000604051808303816000865af19150503d80600081146130cb576040519150601f19603f3d011682016040523d82523d6000602084013e6130d0565b606091505b509150915060008214156130e8573d6000803e3d6000fd5b610e0081516000148061310a57508180602001905181019061310a9190615478565b6101a261054b565b600061311e8383613aa1565b61316d57508154600180820184556000848152602080822090930180546001600160a01b0319166001600160a01b038616908117909155855490825282860190935260409020919091556116f5565b5060006116f5565b6001600160a01b03821660009081526002840160205260408120548061320257505082546040805180820182526001600160a01b03858116808352602080840187815260008781526001808c018452878220965187546001600160a01b03191696169590951786559051948401949094559482018089559083526002880190945291902091909155611876565b600019016000908152600180860160205260408220018390559050611876565b600080600080600061323487876143a4565b91509150600061324483836143d5565b60008a81526009602090815260408083208484526002019091528120805460018201549197509293509061327783613a8f565b80613286575061328682613a8f565b806132a757506132968c87613ac2565b80156132a757506132a78c86613ac2565b9050806132c2576132b78c612683565b6132c26102096116fb565b6132cc8383614408565b98506132d8838361442d565b975050505050505093509350939050565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161590565b6001600160a01b03811660009081526001830160205260408120548015613408578354600019808301919081019060009087908390811061334857fe5b60009182526020909120015487546001600160a01b039091169150819088908590811061337157fe5b600091825260208083209190910180546001600160a01b0319166001600160a01b039485161790559183168152600189810190925260409020908401905586548790806133ba57fe5b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b03881682526001898101909152604082209190915594506116f59350505050565b60009150506116f5565b60006116f28383610209614444565b6001600160a01b0381166000908152600283016020526040812054801561340857835460001990810160008181526001878101602090815260408084209587018452808420865481546001600160a01b03199081166001600160a01b0392831617835588860180549387019390935588548216875260028d018086528488209a909a5588541690975584905593895593871682529390925281205590506116f5565b606080825167ffffffffffffffff811180156134de57600080fd5b50604051908082528060200260200182016040528015613508578160200160208202803683370190505b50905060005b83518110156107ff576135268482815181106124ac57fe5b82828151811061353257fe5b6001600160a01b039092166020928302919091019091015260010161350e565b60608060606135608561293e565b9150915061357082518551611e12565b613580600083511161020f61054b565b60005b82518110156135da576135d285828151811061359b57fe5b60200260200101516001600160a01b03168483815181106135b857fe5b60200260200101516001600160a01b03161461020861054b565b600101613583565b50949350505050565b60608060608060006135f4866129a0565b9150915060006136038b612938565b905060008c600181111561361357fe5b146136b657806001600160a01b03166374f3b0098c8c8c8787613634614481565b8f604001516040518863ffffffff1660e01b815260040161365b9796959493929190615d66565b600060405180830381600087803b15801561367557600080fd5b505af1158015613689573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526136b19190810190615405565b61374f565b806001600160a01b031663d5c096c48c8c8c87876136d2614481565b8f604001516040518863ffffffff1660e01b81526004016136f99796959493929190615d66565b600060405180830381600087803b15801561371357600080fd5b505af1158015613727573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261374f9190810190615405565b80955081965050506137658751865186516144fb565b60008c600181111561377357fe5b1461378a576137858989898888614513565b613797565b6137978a8989888861465a565b955050505096509650969350505050565b60006137b485846143d5565b600087815260096020908152604080832084845260020190915290209091506137dd85846142d1565b9055505050505050565b60005b8251811015610e00578181815181106137ff57fe5b602002602001015160076000868152602001908152602001600020600085848151811061382857fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020556001016137ea565b6000828152600160205260408120905b8251811015610e00576138958184838151811061387d57fe5b60200260200101518461438c9092919063ffffffff16565b600101613864565b6060825167ffffffffffffffff811180156138b757600080fd5b506040519080825280602002602001820160405280156138e1578160200160208202803683370190505b50905060005b83518110156107ff57826139115783818151811061390157fe5b6020026020010151600003613926565b83818151811061391d57fe5b60200260200101515b82828151811061393257fe5b60209081029190910101526001016138e7565b60008084600181111561395457fe5b1461395f57816109e1565b509092915050565b60008084600181111561397657fe5b146107ff57826109e1565b600061226a7f800000000000000000000000000000000000000000000000000000000000000083106101a561054b565b60008282016116f28284128015906139c95750848212155b806139de57506000841280156139de57508482125b600061054b565b60008183036116f28284128015906139fd5750848213155b80613a125750600084128015613a1257508482135b600161054b565b6000818152600960205260408120805460018201546001600160a01b0391821692849290911690829081613a4d86856143d5565b6000818152600284016020526040902080546001820154919950919250613a748282614408565b9650613a80828261442d565b94505050505091939590929450565b6000613a9a826132e9565b1592915050565b6001600160a01b031660009081526001919091016020526040902054151590565b600082815260096020526040812080546001600160a01b0384811691161480613afa575060018101546001600160a01b038481169116145b80156109e1575050506001600160a01b03161515919050565b60008281526008602052604081206109e18184613aa1565b60008281526001602052604081206109e181846147d0565b6000806002856002811115613b5457fe5b1415613b6a57613b658685856147f1565b613b94565b6001856002811115613b7857fe5b1415613b8957613b658685856147ff565b613b9486858561480d565b8215613bae57613bae6001600160a01b0385163385611ea6565b5050600081900394909350915050565b6000806002856002811115613bcf57fe5b1415613be557613be086858561481b565b613c0f565b6001856002811115613bf357fe5b1415613c0457613be0868585614829565b613c0f868585614837565b8215613c2a57613c2a6001600160a01b038516333086612ba6565b5090946000869003945092505050565b6000806002856002811115613c4b57fe5b1415613c6357613c5c868585614845565b9050613c90565b6001856002811115613c7157fe5b1415613c8257613c5c868585614855565b613c8d868585614865565b90505b6000915094509492505050565b4690565b606080600080600080613cb387613a19565b92975090955093509150506001600160a01b0384161580613cdb57506001600160a01b038216155b15613d04575050604080516000808252602082019081528183019092529450925061299b915050565b60408051600280825260608201835290916020830190803683370190505095508386600081518110613d3257fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508186600181518110613d6057fe5b6001600160a01b03929092166020928302919091018201526040805160028082526060820183529092909190830190803683370190505094508285600081518110613da757fe5b6020026020010181815250508085600181518110613dc157fe5b60200260200101818152505050505050915091565b60008181526008602052604090206060908190613df28161432b565b67ffffffffffffffff81118015613e0857600080fd5b50604051908082528060200260200182016040528015613e32578160200160208202803683370190505b509250825167ffffffffffffffff81118015613e4d57600080fd5b50604051908082528060200260200182016040528015613e77578160200160208202803683370190505b50915060005b8351811015613ef6576000613e928383614875565b905080858381518110613ea157fe5b6001600160a01b03928316602091820292909201810191909152600088815260078252604080822093851682529290915220548451859084908110613ee257fe5b602090810291909101015250600101613e7d565b5050915091565b60008181526001602052604090206060908190613f198161432b565b67ffffffffffffffff81118015613f2f57600080fd5b50604051908082528060200260200182016040528015613f59578160200160208202803683370190505b509250825167ffffffffffffffff81118015613f7457600080fd5b50604051908082528060200260200182016040528015613f9e578160200160208202803683370190505b50915060005b8351811015613ef657613fb782826148a2565b858381518110613fc357fe5b60200260200101858481518110613fd657fe5b60209081029190910101919091526001600160a01b039091169052600101613fa4565b6000614004826127b4565b61400d836127a1565b0192915050565b60008183101561402457816116f2565b5090919050565b600081831061402457816116f2565b6001600160a01b038085166000818152600b602090815260408083209488168084529490915290819020859055517f18e1ea4139e68413d7d08aa752e71568e36b2c5bf940893314c2c5b01eaa0c42906119d0908590615d3e565b6000806140a06148c6565b9050428110156140b45760009150506116f5565b60006140be6148d2565b9050806140d0576000925050506116f5565b6000816140db6149e3565b80516020918201206040516140f7939233918a91899101615dc4565b604051602081830303815290604052805190602001209050600061411a82614a32565b90506000806000614129614a4e565b9250925092506000600185858585604051600081526020016040526040516141549493929190615e1c565b6020604051602081039080840390855afa158015614176573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906141ac57508a6001600160a01b0316816001600160a01b0316145b9b9a5050505050505050505050565b6000806000806141ca86613ff9565b905060006141d786613ff9565b90506141ee6141e5886127ca565b612a3f886127ca565b60a08a01526040517f9d2c110c0000000000000000000000000000000000000000000000000000000081526001600160a01b03891690639d2c110c9061423c908c9086908690600401615e94565b602060405180830381600087803b15801561425657600080fd5b505af115801561426a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061428e9190615968565b92506000806142a68b600001518c6060015187612ff7565b90925090506142b58983614345565b96506142c18882614376565b9550505050509450945094915050565b6000806142e96142e0856127ca565b612a3f856127ca565b90506109e16142f7856127a1565b614300856127a1565b8363ffffffff16614a75565b6001600160a01b03166000908152600291909101602052604090205490565b5490565b6000908152600191820160205260409020015490565b60008061435b83614355866127a1565b90611945565b90506000614368856127b4565b9050436112a6838383614a83565b60008061435b83614386866127a1565b90614abc565b60009182526001928301602052604090912090910155565b600080826001600160a01b0316846001600160a01b0316106143c75782846143ca565b83835b915091509250929050565b600082826040516020016143ea929190615b06565b60405160208183030381529060405280519060200120905092915050565b60006116f2614416846127a1565b61441f846127a1565b614428866127ca565b614a83565b60006116f261443b846127b4565b61441f846127b4565b6001600160a01b038216600090815260028401602052604081205461446b8115158461054b565b614478856001830361432f565b95945050505050565b600061448b6113af565b6001600160a01b03166355c676286040518163ffffffff1660e01b815260040160206040518083038186803b1580156144c357600080fd5b505afa1580156144d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ce9190615968565b610fa0828414801561450c57508183145b606761054b565b6060835167ffffffffffffffff8111801561452d57600080fd5b50604051908082528060200260200182016040528015614557578160200160208202803683370190505b50905060005b85515181101561465057600084828151811061457557fe5b602002602001015190506145a58760200151838151811061459257fe5b60200260200101518210156101f961054b565b6000876000015183815181106145b757fe5b602002602001015190506145d181838b8b60600151611d38565b60008584815181106145df57fe5b602002602001015190506145fb6145f583611b41565b82611f11565b61462a6146088483611945565b89868151811061461457fe5b602002602001015161437690919063ffffffff16565b85858151811061463657fe5b60200260200101818152505050505080600101905061455d565b5095945050505050565b60606000845167ffffffffffffffff8111801561467657600080fd5b506040519080825280602002602001820160405280156146a0578160200160208202803683370190505b50915060005b8651518110156147c65760008582815181106146be57fe5b602002602001015190506146ee886020015183815181106146db57fe5b60200260200101518211156101fa61054b565b60008860000151838151811061470057fe5b6020026020010151905061471a81838c8c60600151611c5a565b61472381611938565b15614735576147328483611945565b93505b600086848151811061474357fe5b602002602001015190506147596145f583611b41565b80831015614778576147738382038a868151811061461457fe5b6147a0565b6147a08184038a868151811061478a57fe5b602002602001015161434590919063ffffffff16565b8685815181106147ac57fe5b6020026020010181815250505050508060010190506146a6565b50614650816119de565b6001600160a01b031660009081526002919091016020526040902054151590565b610e008383614ad284614b0d565b610e008383614ad284614bb8565b610e008383614ad284614c13565b610e008383614c6284614b0d565b610e008383614c6284614bb8565b610e008383614c6284614c13565b60006109e18484614c8385614b0d565b60006109e18484614c8385614bb8565b60006109e18484614c8385614c13565b600082600001828154811061488657fe5b6000918252602090912001546001600160a01b03169392505050565b600090815260019182016020526040902080549101546001600160a01b0390911691565b60006112ce6000614c9d565b6000803560e01c8063b95cac28811461491a57638bdb39138114614942576352bbbe29811461496a5763945bcec981146149925763fa6e671d81146149ba57600092506149de565b7f3f7b71252bd19113ff48c19c6e004a9bcfcca320a0d74d58e85877cbd7dcae5892506149de565b7f8bbc57f66ea936902f50a71ce12b92c43f3c5340bb40c27c4e90ab84eeae335392506149de565b7fe192dcbc143b1e244ad73b813fd3c097b832ad260a157340b4e5e5beda067abe92506149de565b7f9bfc43a4d98313c6766986ffd7c916c7481566d9f224c6819af0a53388aced3a92506149de565b7fa3f865aa351e51cfeb40f5178d1564bb629fe9030b83caf6361d1baaf5b90b5a92505b505090565b60606000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505050608010156105485760803603815290565b6000614a3c61289b565b8260405160200161112e929190615b2d565b6000806000614a5d6020614c9d565b9250614a696040614c9d565b91506108416060614c9d565b60e01b60709190911b010190565b6000838301614ab1858210801590614aa957506e01000000000000000000000000000082105b61020e61054b565b614478858585614a75565b6000614acc83831115600161054b565b50900390565b600080614ae283614386866127a1565b90506000614af384614355876127b4565b90506000614b00866127ca565b90506112a6838383614a83565b6000806000806000614b1e89613a19565b9450509350935093506000836001600160a01b0316896001600160a01b03161415614b69576000614b5384898b63ffffffff16565b9050614b5f8185614ca7565b9093509050614b8b565b6000614b7983898b63ffffffff16565b9050614b858184614ca7565b90925090505b614b9583836142d1565b8555614ba18383614cc3565b600190950194909455509192505050949350505050565b600080614bc5868661271b565b90506000614bd782858763ffffffff16565b60008881526007602090815260408083206001600160a01b038b16845290915290208190559050614c088183614ca7565b979650505050505050565b600084815260016020526040812081614c2c8287613412565b90506000614c3e82868863ffffffff16565b9050614c4b838883613175565b50614c568183614ca7565b98975050505050505050565b600080614c7283614355866127a1565b90506000614af384614386876127b4565b600080614c8f846127a1565b905043614478828583614a83565b3601607f19013590565b6000614cb2826127b4565b614cbb846127b4565b039392505050565b60006116f2614cd1846127b4565b614cda846127b4565b6000614a75565b60408051610120810190915280600081526000602082018190526040820181905260608083018290526080830182905260a0830182905260c0830182905260e08301919091526101009091015290565b604080516080810190915280600081526000602082018190526040820181905260609091015290565b60405180608001604052806060815260200160608152602001606081526020016000151581525090565b6040518060a0016040528060008019168152602001600081526020016000815260200160008152602001606081525090565b80356116f581615f5a565b600082601f830112614dd1578081fd5b8135614de4614ddf82615f04565b615edd565b818152915060208083019084810181840286018201871015614e0557600080fd5b60005b84811015614e2d578135614e1b81615f5a565b84529282019290820190600101614e08565b505050505092915050565b600082601f830112614e48578081fd5b8135614e56614ddf82615f04565b818152915060208083019084810160005b84811015614e2d578135870160a080601f19838c03011215614e8857600080fd5b614e9181615edd565b85830135815260408084013587830152606080850135828401526080915081850135818401525082840135925067ffffffffffffffff831115614ed357600080fd5b614ee18c8885870101614fc0565b90820152865250509282019290820190600101614e67565b600082601f830112614f09578081fd5b8135614f17614ddf82615f04565b818152915060208083019084810181840286018201871015614f3857600080fd5b60005b84811015614e2d57813584529282019290820190600101614f3b565b600082601f830112614f67578081fd5b8151614f75614ddf82615f04565b818152915060208083019084810181840286018201871015614f9657600080fd5b60005b84811015614e2d57815184529282019290820190600101614f99565b80356116f581615f6f565b600082601f830112614fd0578081fd5b813567ffffffffffffffff811115614fe6578182fd5b614ff9601f8201601f1916602001615edd565b915080825283602082850101111561501057600080fd5b8060208401602084013760009082016020015292915050565b80356116f581615f7d565b8035600281106116f557600080fd5b8035600481106116f557600080fd5b600060808284031215615063578081fd5b61506d6080615edd565b9050813567ffffffffffffffff8082111561508757600080fd5b61509385838601614dc1565b835260208401359150808211156150a957600080fd5b6150b585838601614ef9565b602084015260408401359150808211156150ce57600080fd5b506150db84828501614fc0565b6040830152506150ee8360608401614fb5565b606082015292915050565b60006080828403121561510a578081fd5b6151146080615edd565b9050813561512181615f5a565b8152602082013561513181615f6f565b6020820152604082013561514481615f5a565b604082015260608201356150ee81615f6f565b600060208284031215615168578081fd5b81356116f281615f5a565b60008060408385031215615185578081fd5b823561519081615f5a565b915060208301356151a081615f5a565b809150509250929050565b6000806000606084860312156151bf578081fd5b83356151ca81615f5a565b925060208401356151da81615f5a565b915060408401356151ea81615f6f565b809150509250925092565b60008060408385031215615207578182fd5b823561521281615f5a565b9150602083013567ffffffffffffffff81111561522d578182fd5b61523985828601614dc1565b9150509250929050565b60006020808385031215615255578182fd5b823567ffffffffffffffff81111561526b578283fd5b8301601f8101851361527b578283fd5b8035615289614ddf82615f04565b818152838101908385016080808502860187018a10156152a7578788fd5b8795505b848610156153105780828b0312156152c1578788fd5b6152ca81615edd565b6152d48b84615029565b8152878301358882015260406152ec8c828601614db6565b908201526060838101359082015284526001959095019492860192908101906152ab565b509098975050505050505050565b60006020808385031215615330578182fd5b823567ffffffffffffffff811115615346578283fd5b8301601f81018513615356578283fd5b8035615364614ddf82615f04565b8181528381019083850160a0808502860187018a1015615382578788fd5b8795505b848610156153105780828b03121561539c578788fd5b6153a581615edd565b6153af8b84615043565b81526153bd8b898501614db6565b818901526040838101359082015260606153d98c828601614db6565b9082015260806153eb8c858301614db6565b908201528452600195909501949286019290810190615386565b60008060408385031215615417578182fd5b825167ffffffffffffffff8082111561542e578384fd5b61543a86838701614f57565b9350602085015191508082111561544f578283fd5b5061523985828601614f57565b60006020828403121561546d578081fd5b81356116f281615f6f565b600060208284031215615489578081fd5b81516116f281615f6f565b6000602082840312156154a5578081fd5b5035919050565b600080600080608085870312156154c1578182fd5b8435935060208501356154d381615f5a565b925060408501356154e381615f5a565b9150606085013567ffffffffffffffff8111156154fe578182fd5b61550a87828801615052565b91505092959194509250565b60008060408385031215615528578182fd5b82359150602083013567ffffffffffffffff81111561522d578182fd5b600080600060608486031215615559578081fd5b8335925060208085013567ffffffffffffffff80821115615578578384fd5b61558488838901614dc1565b94506040870135915080821115615599578384fd5b508501601f810187136155aa578283fd5b80356155b8614ddf82615f04565b81815283810190838501858402850186018b10156155d4578687fd5b8694505b838510156155ff5780356155eb81615f5a565b8352600194909401939185019185016155d8565b5080955050505050509250925092565b60008060408385031215615621578182fd5b8235915060208301356151a081615f5a565b600060208284031215615644578081fd5b81356001600160e01b0319811681146116f2578182fd5b60008060008060808587031215615670578182fd5b843561567b81615f5a565b9350602085013567ffffffffffffffff80821115615697578384fd5b6156a388838901614dc1565b945060408701359150808211156156b8578384fd5b6156c488838901614ef9565b935060608701359150808211156156d9578283fd5b5061550a87828801614fc0565b6000602082840312156156f7578081fd5b81356116f281615f7d565b60008060008060e08587031215615717578182fd5b6157218686615034565b9350602085013567ffffffffffffffff8082111561573d578384fd5b61574988838901614e38565b9450604087013591508082111561575e578384fd5b5061576b87828801614dc1565b92505061577b86606087016150f9565b905092959194509250565b600080600080600080610120878903121561579f578384fd5b6157a98888615034565b955060208088013567ffffffffffffffff808211156157c6578687fd5b6157d28b838c01614e38565b975060408a01359150808211156157e7578687fd5b6157f38b838c01614dc1565b96506158028b60608c016150f9565b955060e08a0135915080821115615817578485fd5b508801601f81018a13615828578384fd5b8035615836614ddf82615f04565b81815283810190838501858402850186018e1015615852578788fd5b8794505b83851015615874578035835260019490940193918501918501615856565b50809650505050505061010087013590509295509295509295565b60008060008060e085870312156158a4578182fd5b843567ffffffffffffffff808211156158bb578384fd5b9086019060c082890312156158ce578384fd5b6158d860c0615edd565b823581526158e98960208501615034565b602082015260408301356158fc81615f5a565b604082015261590e8960608501614db6565b60608201526080830135608082015260a08301358281111561592e578586fd5b61593a8a828601614fc0565b60a08301525080965050505061595386602087016150f9565b939693955050505060a08201359160c0013590565b600060208284031215615979578081fd5b5051919050565b6001600160a01b03169052565b6000815180845260208085019450808401835b838110156159c55781516001600160a01b0316875295820195908201906001016159a0565b509495945050505050565b6000815180845260208085019450808401835b838110156159c5578151875295820195908201906001016159e3565b60008151808452615a17816020860160208601615f24565b601f01601f19169290920160200192915050565b6000610120825160028110615a3c57fe5b808552506020830151615a526020860182615980565b506040830151615a656040860182615980565b50606083015160608501526080830151608085015260a083015160a085015260c0830151615a9660c0860182615980565b5060e0830151615aa960e0860182615980565b506101008084015182828701526112a6838701826159ff565b9182526001600160e01b031916602082015260240190565b6000828483379101908152919050565b60008251615afc818460208701615f24565b9190910192915050565b6bffffffffffffffffffffffff19606093841b811682529190921b16601482015260280190565b7f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b038316815260408101615bb483615f50565b8260208301529392505050565b6001600160a01b03929092168252602082015260400190565b6000602082526116f2602083018461598d565b600060408252615c00604083018561598d565b828103602084810191909152845180835285820192820190845b81811015615c3f5784516001600160a01b031683529383019391830191600101615c1a565b5090979650505050505050565b600060608252615c5f606083018661598d565b8281036020840152615c7181866159d0565b905082810360408401526112a681856159d0565b600060808252615c98608083018761598d565b8281036020840152615caa81876159d0565b90508281036040840152615cbe81866159d0565b90508281036060840152614c0881856159ff565b600060608252615ce5606083018661598d565b8281036020840152615cf781866159d0565b915050826040830152949350505050565b6000602082526116f260208301846159d0565b901515815260200190565b92151583526020830191909152604082015260600190565b90815260200190565b9283526001600160a01b03918216602084015216604082015260600190565b60008882526001600160a01b03808916602084015280881660408401525060e06060830152615d9860e08301876159d0565b8560808401528460a084015282810360c0840152615db681856159ff565b9a9950505050505050505050565b94855260208501939093526001600160a01b039190911660408401526060830152608082015260a00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b60208101615e4783615f50565b91905290565b918252602082015260400190565b600060808252615e6e6080830187615a2b565b8281036020840152615e8081876159d0565b604084019590955250506060015292915050565b600060608252615ea76060830186615a2b565b60208301949094525060400152919050565b938452602084019290925260408301526001600160a01b0316606082015260800190565b60405181810167ffffffffffffffff81118282101715615efc57600080fd5b604052919050565b600067ffffffffffffffff821115615f1a578081fd5b5060209081020190565b60005b83811015615f3f578181015183820152602001615f27565b83811115610e005750506000910152565b6003811061057e57fe5b6001600160a01b038116811461057e57600080fd5b801515811461057e57600080fd5b6003811061057e57600080fdfea2646970667358221220201e4f926e390fed8dd5318c58846af735c2bebc61b80693ae936a5fe76dcf1464736f6c6343000701003360c060405234801561001057600080fd5b50604051610be6380380610be683398101604081905261002f9161004d565b30608052600160005560601b6001600160601b03191660a05261007b565b60006020828403121561005e578081fd5b81516001600160a01b0381168114610074578182fd5b9392505050565b60805160a05160601c610b406100a66000398061041352806105495250806102a75250610b406000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063851c1bb311610076578063d877845c1161005b578063d877845c14610129578063e42abf3514610131578063fbfa77cf14610151576100a3565b8063851c1bb314610101578063aaabadc514610114576100a3565b806338e9922e146100a857806355c67628146100bd5780636b6b9f69146100db5780636daefab6146100ee575b600080fd5b6100bb6100b636600461099c565b610159565b005b6100c56101b8565b6040516100d29190610aa6565b60405180910390f35b6100bb6100e936600461099c565b6101be565b6100bb6100fc3660046107d1565b610211565b6100c561010f366004610924565b6102a3565b61011c6102f5565b6040516100d29190610a35565b6100c5610304565b61014461013f366004610852565b61030a565b6040516100d29190610a62565b61011c610411565b610161610435565b6101786706f05b59d3b2000082111561025861047e565b60018190556040517fa9ba3ffe0b6c366b81232caab38605a0699ad5398d6cce76f91ee809e322dafc906101ad908390610aa6565b60405180910390a150565b60015490565b6101c6610435565b6101dc662386f26fc1000082111561025961047e565b60028190556040517f5a0b7386237e7f07fa741efc64e59c9387d2cccafec760efed4d53387f20e19a906101ad908390610aa6565b610219610490565b610221610435565b61022b84836104a9565b60005b8481101561029357600086868381811061024457fe5b90506020020160208101906102599190610980565b9050600085858481811061026957fe5b6020029190910135915061028990506001600160a01b03831685836104b6565b505060010161022e565b5061029c61053e565b5050505050565b60007f0000000000000000000000000000000000000000000000000000000000000000826040516020016102d89291906109cc565b604051602081830303815290604052805190602001209050919050565b60006102ff610545565b905090565b60025490565b6060815167ffffffffffffffff8111801561032457600080fd5b5060405190808252806020026020018201604052801561034e578160200160208202803683370190505b50905060005b825181101561040b5782818151811061036957fe5b60200260200101516001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161039c9190610a35565b60206040518083038186803b1580156103b457600080fd5b505afa1580156103c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ec91906109b4565b8282815181106103f857fe5b6020908102919091010152600101610354565b50919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60006104646000357fffffffff00000000000000000000000000000000000000000000000000000000166102a3565b905061047b61047382336105d8565b61019161047e565b50565b8161048c5761048c8161066a565b5050565b6104a26002600054141561019061047e565b6002600055565b61048c818314606761047e565b6105398363a9059cbb60e01b84846040516024016104d5929190610a49565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526106d7565b505050565b6001600055565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663aaabadc56040518163ffffffff1660e01b815260040160206040518083038186803b1580156105a057600080fd5b505afa1580156105b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ff9190610964565b60006105e2610545565b6001600160a01b0316639be2a8848484306040518463ffffffff1660e01b815260040161061193929190610aaf565b60206040518083038186803b15801561062957600080fd5b505afa15801561063d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066191906108fd565b90505b92915050565b7f08c379a0000000000000000000000000000000000000000000000000000000006000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b60006060836001600160a01b0316836040516106f391906109fc565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150600082141561074d573d6000803e3d6000fd5b61077781516000148061076f57508180602001905181019061076f91906108fd565b6101a261047e565b50505050565b60008083601f84011261078e578182fd5b50813567ffffffffffffffff8111156107a5578182fd5b60208301915083602080830285010111156107bf57600080fd5b9250929050565b803561066481610af5565b6000806000806000606086880312156107e8578081fd5b853567ffffffffffffffff808211156107ff578283fd5b61080b89838a0161077d565b90975095506020880135915080821115610823578283fd5b506108308882890161077d565b909450925050604086013561084481610af5565b809150509295509295909350565b60006020808385031215610864578182fd5b823567ffffffffffffffff8082111561087b578384fd5b818501915085601f83011261088e578384fd5b81358181111561089c578485fd5b83810291506108ac848301610ace565b8181528481019084860184860187018a10156108c6578788fd5b8795505b838610156108f0576108dc8a826107c6565b8352600195909501949186019186016108ca565b5098975050505050505050565b60006020828403121561090e578081fd5b8151801515811461091d578182fd5b9392505050565b600060208284031215610935578081fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461091d578182fd5b600060208284031215610975578081fd5b815161091d81610af5565b600060208284031215610991578081fd5b813561091d81610af5565b6000602082840312156109ad578081fd5b5035919050565b6000602082840312156109c5578081fd5b5051919050565b9182527fffffffff0000000000000000000000000000000000000000000000000000000016602082015260240190565b60008251815b81811015610a1c5760208186018101518583015201610a02565b81811115610a2a5782828501525b509190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015610a9a57835183529284019291840191600101610a7e565b50909695505050505050565b90815260200190565b9283526001600160a01b03918216602084015216604082015260600190565b60405181810167ffffffffffffffff81118282101715610aed57600080fd5b604052919050565b6001600160a01b038116811461047b57600080fdfea2646970667358221220be72bdf8e7a3c38606c5f954fbe2d77798347aaa1cfb76fe77ec2f6c245d24bc64736f6c63430007010033", "deployedBytecode": "", "linkReferences": {}, "deployedLinkReferences": {} -} +} \ No newline at end of file diff --git a/test/protocol/integration/index-exchange/balancerV2IndexExchangeAdapter.spec.ts b/test/protocol/integration/index-exchange/balancerV2IndexExchangeAdapter.spec.ts new file mode 100644 index 000000000..d4882d5fd --- /dev/null +++ b/test/protocol/integration/index-exchange/balancerV2IndexExchangeAdapter.spec.ts @@ -0,0 +1,194 @@ +import "module-alias/register"; + +import { BigNumber } from "@ethersproject/bignumber"; + +import { Address, Bytes } from "@utils/types"; +import { Account } from "@utils/test/types"; +import { + EMPTY_BYTES, + MAX_UINT_256, +} from "@utils/constants"; +import { BalancerV2IndexExchangeAdapter } from "@utils/contracts"; +import DeployHelper from "@utils/deploys"; +import { + ether, +} from "@utils/index"; +import { + addSnapshotBeforeRestoreAfterEach, + getAccounts, + getSystemFixture, + getBalancerV2Fixture, + getWaffleExpect +} from "@utils/test/index"; + +import { SystemFixture, BalancerV2Fixture } from "@utils/fixtures"; +import { defaultAbiCoder } from "@ethersproject/abi"; + +const expect = getWaffleExpect(); + +describe("BalancerV2IndexExchangeAdapter", () => { + let owner: Account; + let mockSetToken: Account; + let deployer: DeployHelper; + let setup: SystemFixture; + let balancerSetup: BalancerV2Fixture; + + let balancerV2ExchangeAdapter: BalancerV2IndexExchangeAdapter; + + before(async () => { + [ + owner, + mockSetToken, + ] = await getAccounts(); + + deployer = new DeployHelper(owner.wallet); + setup = getSystemFixture(owner.address); + await setup.initialize(); + + balancerSetup = getBalancerV2Fixture(owner.address); + await balancerSetup.initialize( + owner, + setup.weth, + setup.dai + ); + + balancerV2ExchangeAdapter = await deployer.adapters.deployBalancerV2IndexExchangeAdapter(balancerSetup.vault.address); + }); + + addSnapshotBeforeRestoreAfterEach(); + + describe("#constructor", async () => { + let subjectVaultAddress: Address; + + beforeEach(async () => { + subjectVaultAddress = balancerSetup.vault.address; + }); + + async function subject(): Promise { + return await deployer.adapters.deployBalancerV2IndexExchangeAdapter(subjectVaultAddress); + } + + it("should have the correct vault address", async () => { + const deployedBalancerV2ExchangeAdapter = await subject(); + + const actualVaultAddress = await deployedBalancerV2ExchangeAdapter.vault(); + expect(actualVaultAddress).to.eq(subjectVaultAddress); + }); + }); + + describe("#getSpender", async () => { + async function subject(): Promise { + return await balancerV2ExchangeAdapter.getSpender(); + } + + it("should return the correct spender address", async () => { + const spender = await subject(); + + expect(spender).to.eq(balancerSetup.vault.address); + }); + }); + + describe("#getTradeCalldata", async () => { + let sourceToken: Address; + let destinationToken: Address; + let sourceQuantity: BigNumber; + let destinationQuantity: BigNumber; + + let subjectMockSetToken: Address; + let subjectSourceToken: Address; + let subjectDestinationToken: Address; + let subjectIsSendTokenFixed: boolean; + let subjectSourceQuantity: BigNumber; + let subjectDestinationQuantity: BigNumber; + let subjectData: Bytes; + + beforeEach(async () => { + sourceToken = setup.weth.address; // WETH Address + sourceQuantity = ether(1); // Trade 1 WETH + destinationToken = setup.dai.address; // DAI Address + destinationQuantity = ether(5000); // Receive at least 5k DAI + + subjectSourceToken = sourceToken; + subjectDestinationToken = destinationToken; + subjectMockSetToken = mockSetToken.address; + subjectIsSendTokenFixed = true; + subjectSourceQuantity = sourceQuantity; + subjectDestinationQuantity = destinationQuantity; + subjectData = defaultAbiCoder.encode(["bytes32"], [balancerSetup.wethDaiPoolId]); + }); + + async function subject(): Promise<[Address, BigNumber, string]> { + return await balancerV2ExchangeAdapter.connect(mockSetToken.wallet).getTradeCalldata( + subjectSourceToken, + subjectDestinationToken, + subjectMockSetToken, + subjectIsSendTokenFixed, + subjectSourceQuantity, + subjectDestinationQuantity, + subjectData, + ); + } + + context("when boolean fixed input amount is true", async () => { + it("should return the correct trade calldata", async () => { + const [ to, value, calldata ] = await subject(); + + const expectedCalldata = balancerSetup.vault.interface.encodeFunctionData("swap", [ + { + poolId: balancerSetup.wethDaiPoolId, + kind: 0, + assetIn: subjectSourceToken, + assetOut: subjectDestinationToken, + amount: subjectSourceQuantity, + userData: EMPTY_BYTES, + }, + { + sender: mockSetToken.address, + fromInternalBalance: false, + recipient: mockSetToken.address, + toInternalBalance: false, + }, + subjectDestinationQuantity, + MAX_UINT_256, + ]); + + expect(to).to.eq(balancerSetup.vault.address); + expect(value).to.eq(0); + expect(calldata).to.eq(expectedCalldata); + }); + }); + + context("when boolean fixed input amount is false", async () => { + beforeEach(async () => { + subjectIsSendTokenFixed = false; + }); + + it("should return the correct trade calldata", async () => { + const [ to, value, calldata ] = await subject(); + + const expectedCalldata = balancerSetup.vault.interface.encodeFunctionData("swap", [ + { + poolId: balancerSetup.wethDaiPoolId, + kind: 1, + assetIn: subjectSourceToken, + assetOut: subjectDestinationToken, + amount: subjectDestinationQuantity, + userData: EMPTY_BYTES, + }, + { + sender: mockSetToken.address, + fromInternalBalance: false, + recipient: mockSetToken.address, + toInternalBalance: false, + }, + subjectSourceQuantity, + MAX_UINT_256, + ]); + + expect(to).to.eq(balancerSetup.vault.address); + expect(value).to.eq(0); + expect(calldata).to.eq(expectedCalldata); + }); + }); + }); +}); diff --git a/utils/contracts/index.ts b/utils/contracts/index.ts index b75de1ad0..8b8217af3 100644 --- a/utils/contracts/index.ts +++ b/utils/contracts/index.ts @@ -16,6 +16,7 @@ export { AGIMigrationWrapAdapter } from "../../typechain/AGIMigrationWrapAdapter export { AssetLimitHook } from "../../typechain/AssetLimitHook"; export { AxieInfinityMigrationWrapAdapter } from "../../typechain/AxieInfinityMigrationWrapAdapter"; export { BalancerV1IndexExchangeAdapter } from "../../typechain/BalancerV1IndexExchangeAdapter"; +export { BalancerV2IndexExchangeAdapter } from "../../typechain/BalancerV2IndexExchangeAdapter"; export { BasicIssuanceModule } from "../../typechain/BasicIssuanceModule"; export { ClaimAdapterMock } from "../../typechain/ClaimAdapterMock"; export { ClaimModule } from "../../typechain/ClaimModule"; diff --git a/utils/deploys/deployAdapters.ts b/utils/deploys/deployAdapters.ts index ab737b54b..96fda27b9 100644 --- a/utils/deploys/deployAdapters.ts +++ b/utils/deploys/deployAdapters.ts @@ -7,6 +7,7 @@ import { AGIMigrationWrapAdapter, AxieInfinityMigrationWrapAdapter, BalancerV1IndexExchangeAdapter, + BalancerV2IndexExchangeAdapter, CompoundLikeGovernanceAdapter, CurveStakingAdapter, KyberExchangeAdapter, @@ -40,6 +41,7 @@ import { AaveGovernanceV2Adapter__factory } from "../../typechain/factories/Aave import { AaveV2WrapV2Adapter__factory } from "../../typechain/factories/AaveV2WrapV2Adapter__factory"; import { AxieInfinityMigrationWrapAdapter__factory } from "../../typechain/factories/AxieInfinityMigrationWrapAdapter__factory"; import { BalancerV1IndexExchangeAdapter__factory } from "../../typechain/factories/BalancerV1IndexExchangeAdapter__factory"; +import { BalancerV2IndexExchangeAdapter__factory } from "../../typechain/factories/BalancerV2IndexExchangeAdapter__factory"; import { CompoundLikeGovernanceAdapter__factory } from "../../typechain/factories/CompoundLikeGovernanceAdapter__factory"; import { CurveStakingAdapter__factory } from "../../typechain/factories/CurveStakingAdapter__factory"; import { KyberExchangeAdapter__factory } from "../../typechain/factories/KyberExchangeAdapter__factory"; @@ -242,4 +244,8 @@ export default class DeployAdapters { public async deployAaveV2WrapV2Adapter(lendingPool: Address): Promise { return await new AaveV2WrapV2Adapter__factory(this._deployerSigner).deploy(lendingPool); } + + public async deployBalancerV2IndexExchangeAdapter(vault: Address): Promise { + return await new BalancerV2IndexExchangeAdapter__factory(this._deployerSigner).deploy(vault); + } } From 5b6a8487697677b10a1d5c96964360ba6ebdc43a Mon Sep 17 00:00:00 2001 From: ncitron Date: Sat, 11 Sep 2021 01:06:00 -0400 Subject: [PATCH 5/9] add integration tests --- .../BalancerV2IndexExchangeAdapter.sol | 14 +- ...lancerV2ExchangeGeneralIndexModule.spec.ts | 303 ++++++++++++++++++ .../balancerV2IndexExchangeAdapter.spec.ts | 1 + utils/fixtures/balancerV2Fixture.ts | 28 +- 4 files changed, 344 insertions(+), 2 deletions(-) create mode 100644 test/integration/balancerV2ExchangeGeneralIndexModule.spec.ts diff --git a/contracts/protocol/integration/index-exchange/BalancerV2IndexExchangeAdapter.sol b/contracts/protocol/integration/index-exchange/BalancerV2IndexExchangeAdapter.sol index c4db91ccc..12e37707b 100644 --- a/contracts/protocol/integration/index-exchange/BalancerV2IndexExchangeAdapter.sol +++ b/contracts/protocol/integration/index-exchange/BalancerV2IndexExchangeAdapter.sol @@ -22,6 +22,8 @@ pragma experimental "ABIEncoderV2"; import { IBVault } from "../../../interfaces/external/IBVault.sol"; import { IIndexExchangeAdapter } from "../../../interfaces/IIndexExchangeAdapter.sol"; +import { console } from "hardhat/console.sol"; + /** * @title BalancerV2IndexExchangeAdapter * @author Set Protocol @@ -82,6 +84,10 @@ contract BalancerV2IndexExchangeAdapter is IIndexExchangeAdapter { { bytes32 poolId = abi.decode(_data, (bytes32)); + console.logBytes32(poolId); + console.log(_destinationAddress); + console.log(_sourceQuantity); + IBVault.SingleSwap memory singleSwap = IBVault.SingleSwap({ poolId: poolId, kind: _isSendTokenFixed ? IBVault.SwapKind.GIVEN_IN : IBVault.SwapKind.GIVEN_OUT, @@ -91,12 +97,16 @@ contract BalancerV2IndexExchangeAdapter is IIndexExchangeAdapter { userData: "" }); + console.log("a"); + IBVault.FundManagement memory funds = IBVault.FundManagement({ - sender: msg.sender, + sender: _destinationAddress, fromInternalBalance: false, recipient: payable(_destinationAddress), toInternalBalance: false }); + + console.log("b"); bytes memory callData = abi.encodePacked( IBVault.swap.selector, @@ -108,6 +118,8 @@ contract BalancerV2IndexExchangeAdapter is IIndexExchangeAdapter { ) ); + console.log("c"); + return (vault, 0, callData); } diff --git a/test/integration/balancerV2ExchangeGeneralIndexModule.spec.ts b/test/integration/balancerV2ExchangeGeneralIndexModule.spec.ts new file mode 100644 index 000000000..a83123973 --- /dev/null +++ b/test/integration/balancerV2ExchangeGeneralIndexModule.spec.ts @@ -0,0 +1,303 @@ +import "module-alias/register"; +import { BigNumber } from "@ethersproject/bignumber"; + +import { Address } from "@utils/types"; +import { Account } from "@utils/test/types"; +import { ADDRESS_ZERO, EMPTY_BYTES, MAX_UINT_256, ZERO } from "@utils/constants"; +import { + GeneralIndexModule, + SetToken, + BalancerV2IndexExchangeAdapter +} from "@utils/contracts"; +import DeployHelper from "@utils/deploys"; +import { + bitcoin, + ether, + preciseDiv, + preciseMul, +} from "@utils/index"; +import { + cacheBeforeEach, + getAccounts, + getSystemFixture, + getBalancerV2Fixture, + getWaffleExpect +} from "@utils/test/index"; +import { BalancerV2Fixture, SystemFixture } from "@utils/fixtures"; +import { ContractTransaction } from "ethers"; +import { defaultAbiCoder } from "@ethersproject/abi"; + +const expect = getWaffleExpect(); + +describe("BalancerV2ExchangeGeneralIndexModule", () => { + let owner: Account; + let trader: Account; + let positionModule: Account; + let deployer: DeployHelper; + let setup: SystemFixture; + + let balancerSetup: BalancerV2Fixture; + + let index: SetToken; + let indexModule: GeneralIndexModule; + + let exchangeAdapter: BalancerV2IndexExchangeAdapter; + let exchangeAdapterName: string; + + let indexComponents: Address[]; + let indexUnits: BigNumber[]; + + before(async () => { + [ + owner, + trader, + positionModule, + ] = await getAccounts(); + + deployer = new DeployHelper(owner.wallet); + setup = getSystemFixture(owner.address); + balancerSetup = getBalancerV2Fixture(owner.address); + + await setup.initialize(); + await balancerSetup.initialize(owner, setup.weth, setup.wbtc, setup.dai); + + indexModule = await deployer.modules.deployGeneralIndexModule( + setup.controller.address, + setup.weth.address + ); + await setup.controller.addModule(indexModule.address); + await setup.controller.addModule(positionModule.address); + + + exchangeAdapter = await deployer.adapters.deployBalancerV2IndexExchangeAdapter(balancerSetup.vault.address); + exchangeAdapterName = "BalancerV2IndexExchangeAdapter"; + + + await setup.integrationRegistry.batchAddIntegration( + [ indexModule.address ], + [ exchangeAdapterName ], + [ exchangeAdapter.address ] + ); + }); + + cacheBeforeEach(async () => { + indexComponents = [setup.wbtc.address, setup.dai.address]; + indexUnits = [ bitcoin(0.01), ether(4000) ]; + + index = await setup.createSetToken( + indexComponents, + indexUnits, + [setup.issuanceModule.address, indexModule.address, positionModule.address], + ); + + await setup.issuanceModule.initialize(index.address, ADDRESS_ZERO); + await index.connect(positionModule.wallet).initializeModule(); + + await setup.weth.connect(owner.wallet).approve(balancerSetup.vault.address, MAX_UINT_256); + await setup.dai.connect(owner.wallet).approve(balancerSetup.vault.address, MAX_UINT_256); + await setup.wbtc.connect(owner.wallet).approve(balancerSetup.vault.address, MAX_UINT_256); + + await balancerSetup.depositInitial(balancerSetup.wethDaiPoolId, owner, [setup.weth.address, setup.dai.address], [ether(100), ether(400_000)]); + await balancerSetup.depositInitial(balancerSetup.wethWbtcPoolId, owner, [setup.weth.address, setup.wbtc.address], [ether(100), bitcoin(4)]); + }); + + describe("when module is initalized", async () => { + let subjectSetToken: SetToken; + let subjectCaller: Account; + + let newComponents: Address[]; + let newTargetUnits: BigNumber[]; + let oldTargetUnits: BigNumber[]; + let issueAmount: BigNumber; + + async function initSetToken( + setToken: SetToken, components: Address[], tradeMaximums: BigNumber[], exchanges: string[], coolOffPeriods: BigNumber[] + ) { + await indexModule.initialize(setToken.address); + await indexModule.setTradeMaximums(setToken.address, components, tradeMaximums); + await indexModule.setExchanges(setToken.address, components, exchanges); + await indexModule.setCoolOffPeriods(setToken.address, components, coolOffPeriods); + await indexModule.setTraderStatus(setToken.address, [trader.address], [true]); + } + + const startRebalance = async () => { + await setup.approveAndIssueSetToken(subjectSetToken, issueAmount); + await indexModule.startRebalance( + subjectSetToken.address, + newComponents, + newTargetUnits, + oldTargetUnits, + await index.positionMultiplier() + ); + }; + + before(async () => { + newComponents = []; + oldTargetUnits = [bitcoin(0.1), ether(1)]; + newTargetUnits = []; + issueAmount = ether("20.000000000000000001"); + }); + + cacheBeforeEach(async () => { + await initSetToken( + index, + [setup.wbtc.address, setup.dai.address], + [bitcoin(1000), ether(100000)], + [exchangeAdapterName, exchangeAdapterName], + [ZERO, ZERO] + ); + }); + + describe("#trade", async () => { + let subjectComponent: Address; + let subjectEthQuantityLimit: BigNumber; + + let expectedOut: BigNumber; + + const initializeSubjectVariables = () => { + subjectSetToken = index; + subjectCaller = trader; + subjectComponent = setup.dai.address; + subjectEthQuantityLimit = ZERO; + }; + + async function subject(): Promise { + return await indexModule.connect(subjectCaller.wallet).trade( + subjectSetToken.address, + subjectComponent, + subjectEthQuantityLimit + ); + } + + beforeEach(async () => { + + initializeSubjectVariables(); + + const exchangeData = defaultAbiCoder.encode(["bytes32"], [balancerSetup.wethDaiPoolId]); + await indexModule.setExchangeData(subjectSetToken.address, [setup.dai.address], [exchangeData]); + + expectedOut = await balancerSetup.vault.connect(owner.address).callStatic.swap( + { + poolId: balancerSetup.wethDaiPoolId, + kind: 0, + assetIn: setup.dai.address, + assetOut: setup.weth.address, + amount: preciseMul(ether(3999), issueAmount), + userData: EMPTY_BYTES, + }, + { + sender: owner.address, + fromInternalBalance: false, + recipient: owner.address, + toInternalBalance: false, + }, + 0, + MAX_UINT_256, + ); + + subjectEthQuantityLimit = BigNumber.from(0); + }); + + cacheBeforeEach(startRebalance); + + it("should sell using Balancer V2", async () => { + const currentWethAmount = await setup.weth.balanceOf(subjectSetToken.address); + const totalSupply = await subjectSetToken.totalSupply(); + + await subject(); + + const expectedWethPositionUnits = preciseDiv(currentWethAmount.add(expectedOut), totalSupply); + const expectedDaiPositionUnits = ether(1); + + const wethPositionUnits = await subjectSetToken.getDefaultPositionRealUnit(setup.weth.address); + const daiPositionUnits = await subjectSetToken.getDefaultPositionRealUnit(setup.dai.address); + + expect(wethPositionUnits).to.eq(expectedWethPositionUnits); + expect(daiPositionUnits).to.eq(expectedDaiPositionUnits); + }); + }); + + describe("#tradeRemainingWETH", async () => { + + let subjectComponent: Address; + let subjectEthQuantityLimit: BigNumber; + + let expectedOut: BigNumber; + + const initializeSubjectVariables = () => { + subjectSetToken = index; + subjectCaller = trader; + subjectComponent = setup.dai.address; + subjectEthQuantityLimit = ZERO; + }; + + async function subject(): Promise { + return await indexModule.connect(subjectCaller.wallet).tradeRemainingWETH( + subjectSetToken.address, + subjectComponent, + subjectEthQuantityLimit + ); + } + + context("when using default target units", async () => { + + cacheBeforeEach(startRebalance); + + beforeEach(async () => { + initializeSubjectVariables(); + + const exchangeDataDai = defaultAbiCoder.encode(["bytes32"], [balancerSetup.wethDaiPoolId]); + await indexModule.setExchangeData(subjectSetToken.address, [setup.dai.address], [exchangeDataDai]); + + const exchangeDataWbtc = defaultAbiCoder.encode(["bytes32"], [balancerSetup.wethWbtcPoolId]); + await indexModule.setExchangeData(subjectSetToken.address, [setup.wbtc.address], [exchangeDataWbtc]); + + await indexModule.connect(subjectCaller.wallet).trade( + subjectSetToken.address, + subjectComponent, + subjectEthQuantityLimit + ); + + + expectedOut = await balancerSetup.vault.connect(owner.address).callStatic.swap( + { + poolId: balancerSetup.wethWbtcPoolId, + kind: 0, + assetIn: setup.weth.address, + assetOut: setup.wbtc.address, + amount: await setup.weth.balanceOf(subjectSetToken.address), + userData: EMPTY_BYTES, + }, + { + sender: owner.address, + fromInternalBalance: false, + recipient: owner.address, + toInternalBalance: false, + }, + 0, + MAX_UINT_256, + ); + + subjectComponent = setup.wbtc.address; + subjectEthQuantityLimit = ZERO; + }); + + it("should buy using Balancer V2", async () => { + const currentWbtcAmount = await setup.wbtc.balanceOf(subjectSetToken.address); + const totalSupply = await subjectSetToken.totalSupply(); + + await subject(); + + const expectedWbtcPositionUnits = preciseDiv(currentWbtcAmount.add(expectedOut), totalSupply); + const expectedWethPositionUnits = ether(0); + + const wethPositionUnits = await subjectSetToken.getDefaultPositionRealUnit(setup.weth.address); + const wbtcPositionUnits = await subjectSetToken.getDefaultPositionRealUnit(setup.wbtc.address); + + expect(wbtcPositionUnits).to.eq(expectedWbtcPositionUnits); + expect(wethPositionUnits).to.eq(expectedWethPositionUnits); + }); + }); + }); + }); +}); \ No newline at end of file diff --git a/test/protocol/integration/index-exchange/balancerV2IndexExchangeAdapter.spec.ts b/test/protocol/integration/index-exchange/balancerV2IndexExchangeAdapter.spec.ts index d4882d5fd..ea2862f3a 100644 --- a/test/protocol/integration/index-exchange/balancerV2IndexExchangeAdapter.spec.ts +++ b/test/protocol/integration/index-exchange/balancerV2IndexExchangeAdapter.spec.ts @@ -49,6 +49,7 @@ describe("BalancerV2IndexExchangeAdapter", () => { await balancerSetup.initialize( owner, setup.weth, + setup.wbtc, setup.dai ); diff --git a/utils/fixtures/balancerV2Fixture.ts b/utils/fixtures/balancerV2Fixture.ts index 6fc9fd85d..fffa441e9 100644 --- a/utils/fixtures/balancerV2Fixture.ts +++ b/utils/fixtures/balancerV2Fixture.ts @@ -9,6 +9,7 @@ import { StandardTokenMock, WETH9 } from "../contracts/index"; import { BVault, WeightedPoolFactory } from "../contracts/balancerV2"; import { BPoolV2__factory } from "../../typechain/factories/BPoolV2__factory"; import { BigNumber } from "@ethersproject/bignumber"; +import { defaultAbiCoder } from "@ethersproject/abi"; export class BalancerV2Fixture { private _deployer: DeployHelper; @@ -19,13 +20,14 @@ export class BalancerV2Fixture { public vault: BVault; public weightedPoolFactory: WeightedPoolFactory; public wethDaiPoolId: string; + public wethWbtcPoolId: string; constructor(provider: Web3Provider | JsonRpcProvider, ownerAddress: Address) { this._ownerSigner = provider.getSigner(ownerAddress); this._deployer = new DeployHelper(this._ownerSigner); } - public async initialize(_owner: Account, _weth: WETH9, _dai: StandardTokenMock): Promise { + public async initialize(_owner: Account, _weth: WETH9, _wbtc: StandardTokenMock, _dai: StandardTokenMock): Promise { this.owner = _owner; this.vault = await this._deployer.external.deployBVault(_weth.address); @@ -38,6 +40,11 @@ export class BalancerV2Fixture { [ _weth.address, _dai.address ], [ ether(0.5), ether(0.5) ] ); + + this.wethWbtcPoolId = await this.createPool( + [ _weth.address, _wbtc.address ], + [ ether(0.5), ether(0.5) ] + ); } public async createPool(tokens: Address[], weights: BigNumber[]): Promise { @@ -63,4 +70,23 @@ export class BalancerV2Fixture { return ""; } + + public async depositInitial(poolId: string, from: Account, tokens: Address[], amounts: BigNumber[]): Promise { + const tokenAndAmounts = tokens.map((token, i) => { return {address: token, amount: amounts[i]}; }); + tokenAndAmounts.sort((a, b) => parseInt(a.address) - parseInt(b.address)); + + const initUserData = defaultAbiCoder.encode(["uint256", "uint256[]"], [0, tokenAndAmounts.map(ta => ta.amount)]); + + await this.vault.connect(from.wallet).joinPool( + poolId, + from.address, + from.address, + { + assets: tokenAndAmounts.map(ta => ta.address), + maxAmountsIn: tokenAndAmounts.map(ta => ta.amount), + userData: initUserData, + fromInternalBalance: false, + } + ); + } } \ No newline at end of file From 913b242315deea33b0e98952216735cbe201b913 Mon Sep 17 00:00:00 2001 From: ncitron Date: Sat, 11 Sep 2021 01:07:08 -0400 Subject: [PATCH 6/9] shrink BVault.json --- external/abi/balancer/v2/BVault.json | 1182 +------------------------- 1 file changed, 2 insertions(+), 1180 deletions(-) diff --git a/external/abi/balancer/v2/BVault.json b/external/abi/balancer/v2/BVault.json index f443f1411..8cbaef130 100644 --- a/external/abi/balancer/v2/BVault.json +++ b/external/abi/balancer/v2/BVault.json @@ -1,1186 +1,8 @@ { "contractName": "BVault", - "abi": [ - { - "inputs": [ - { - "internalType": "contract IAuthorizer", - "name": "authorizer", - "type": "address" - }, - { - "internalType": "contract IWETH", - "name": "weth", - "type": "address" - }, - { - "internalType": "uint256", - "name": "pauseWindowDuration", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "bufferPeriodDuration", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "contract IAuthorizer", - "name": "newAuthorizer", - "type": "address" - } - ], - "name": "AuthorizerChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "ExternalBalanceTransfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "contract IFlashLoanRecipient", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "feeAmount", - "type": "uint256" - } - ], - "name": "FlashLoan", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "indexed": true, - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "indexed": false, - "internalType": "int256", - "name": "delta", - "type": "int256" - } - ], - "name": "InternalBalanceChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bool", - "name": "paused", - "type": "bool" - } - ], - "name": "PausedStateChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "liquidityProvider", - "type": "address" - }, - { - "indexed": false, - "internalType": "contract IERC20[]", - "name": "tokens", - "type": "address[]" - }, - { - "indexed": false, - "internalType": "int256[]", - "name": "deltas", - "type": "int256[]" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "protocolFeeAmounts", - "type": "uint256[]" - } - ], - "name": "PoolBalanceChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "assetManager", - "type": "address" - }, - { - "indexed": true, - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "indexed": false, - "internalType": "int256", - "name": "cashDelta", - "type": "int256" - }, - { - "indexed": false, - "internalType": "int256", - "name": "managedDelta", - "type": "int256" - } - ], - "name": "PoolBalanceManaged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "poolAddress", - "type": "address" - }, - { - "indexed": false, - "internalType": "enum IVault.PoolSpecialization", - "name": "specialization", - "type": "uint8" - } - ], - "name": "PoolRegistered", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "relayer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "RelayerApprovalChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "contract IERC20", - "name": "tokenIn", - "type": "address" - }, - { - "indexed": true, - "internalType": "contract IERC20", - "name": "tokenOut", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - } - ], - "name": "Swap", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "contract IERC20[]", - "name": "tokens", - "type": "address[]" - } - ], - "name": "TokensDeregistered", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "contract IERC20[]", - "name": "tokens", - "type": "address[]" - }, - { - "indexed": false, - "internalType": "address[]", - "name": "assetManagers", - "type": "address[]" - } - ], - "name": "TokensRegistered", - "type": "event" - }, - { - "inputs": [], - "name": "WETH", - "outputs": [ - { - "internalType": "contract IWETH", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "enum IVault.SwapKind", - "name": "kind", - "type": "uint8" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "assetInIndex", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "assetOutIndex", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "userData", - "type": "bytes" - } - ], - "internalType": "struct IVault.BatchSwapStep[]", - "name": "swaps", - "type": "tuple[]" - }, - { - "internalType": "contract IAsset[]", - "name": "assets", - "type": "address[]" - }, - { - "components": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "bool", - "name": "fromInternalBalance", - "type": "bool" - }, - { - "internalType": "address payable", - "name": "recipient", - "type": "address" - }, - { - "internalType": "bool", - "name": "toInternalBalance", - "type": "bool" - } - ], - "internalType": "struct IVault.FundManagement", - "name": "funds", - "type": "tuple" - }, - { - "internalType": "int256[]", - "name": "limits", - "type": "int256[]" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "batchSwap", - "outputs": [ - { - "internalType": "int256[]", - "name": "assetDeltas", - "type": "int256[]" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - }, - { - "internalType": "contract IERC20[]", - "name": "tokens", - "type": "address[]" - } - ], - "name": "deregisterTokens", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address payable", - "name": "recipient", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract IAsset[]", - "name": "assets", - "type": "address[]" - }, - { - "internalType": "uint256[]", - "name": "minAmountsOut", - "type": "uint256[]" - }, - { - "internalType": "bytes", - "name": "userData", - "type": "bytes" - }, - { - "internalType": "bool", - "name": "toInternalBalance", - "type": "bool" - } - ], - "internalType": "struct IVault.ExitPoolRequest", - "name": "request", - "type": "tuple" - } - ], - "name": "exitPool", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract IFlashLoanRecipient", - "name": "recipient", - "type": "address" - }, - { - "internalType": "contract IERC20[]", - "name": "tokens", - "type": "address[]" - }, - { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" - }, - { - "internalType": "bytes", - "name": "userData", - "type": "bytes" - } - ], - "name": "flashLoan", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "selector", - "type": "bytes4" - } - ], - "name": "getActionId", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getAuthorizer", - "outputs": [ - { - "internalType": "contract IAuthorizer", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getDomainSeparator", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "internalType": "contract IERC20[]", - "name": "tokens", - "type": "address[]" - } - ], - "name": "getInternalBalance", - "outputs": [ - { - "internalType": "uint256[]", - "name": "balances", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "user", - "type": "address" - } - ], - "name": "getNextNonce", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getPausedState", - "outputs": [ - { - "internalType": "bool", - "name": "paused", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "pauseWindowEndTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "bufferPeriodEndTime", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - } - ], - "name": "getPool", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "enum IVault.PoolSpecialization", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - }, - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - } - ], - "name": "getPoolTokenInfo", - "outputs": [ - { - "internalType": "uint256", - "name": "cash", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "managed", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lastChangeBlock", - "type": "uint256" - }, - { - "internalType": "address", - "name": "assetManager", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - } - ], - "name": "getPoolTokens", - "outputs": [ - { - "internalType": "contract IERC20[]", - "name": "tokens", - "type": "address[]" - }, - { - "internalType": "uint256[]", - "name": "balances", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "lastChangeBlock", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getProtocolFeesCollector", - "outputs": [ - { - "internalType": "contract ProtocolFeesCollector", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "internalType": "address", - "name": "relayer", - "type": "address" - } - ], - "name": "hasApprovedRelayer", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract IAsset[]", - "name": "assets", - "type": "address[]" - }, - { - "internalType": "uint256[]", - "name": "maxAmountsIn", - "type": "uint256[]" - }, - { - "internalType": "bytes", - "name": "userData", - "type": "bytes" - }, - { - "internalType": "bool", - "name": "fromInternalBalance", - "type": "bool" - } - ], - "internalType": "struct IVault.JoinPoolRequest", - "name": "request", - "type": "tuple" - } - ], - "name": "joinPool", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "enum IVault.PoolBalanceOpKind", - "name": "kind", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - }, - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "internalType": "struct IVault.PoolBalanceOp[]", - "name": "ops", - "type": "tuple[]" - } - ], - "name": "managePoolBalance", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "enum IVault.UserBalanceOpKind", - "name": "kind", - "type": "uint8" - }, - { - "internalType": "contract IAsset", - "name": "asset", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address payable", - "name": "recipient", - "type": "address" - } - ], - "internalType": "struct IVault.UserBalanceOp[]", - "name": "ops", - "type": "tuple[]" - } - ], - "name": "manageUserBalance", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "enum IVault.SwapKind", - "name": "kind", - "type": "uint8" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "assetInIndex", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "assetOutIndex", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "userData", - "type": "bytes" - } - ], - "internalType": "struct IVault.BatchSwapStep[]", - "name": "swaps", - "type": "tuple[]" - }, - { - "internalType": "contract IAsset[]", - "name": "assets", - "type": "address[]" - }, - { - "components": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "bool", - "name": "fromInternalBalance", - "type": "bool" - }, - { - "internalType": "address payable", - "name": "recipient", - "type": "address" - }, - { - "internalType": "bool", - "name": "toInternalBalance", - "type": "bool" - } - ], - "internalType": "struct IVault.FundManagement", - "name": "funds", - "type": "tuple" - } - ], - "name": "queryBatchSwap", - "outputs": [ - { - "internalType": "int256[]", - "name": "", - "type": "int256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "enum IVault.PoolSpecialization", - "name": "specialization", - "type": "uint8" - } - ], - "name": "registerPool", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - }, - { - "internalType": "contract IERC20[]", - "name": "tokens", - "type": "address[]" - }, - { - "internalType": "address[]", - "name": "assetManagers", - "type": "address[]" - } - ], - "name": "registerTokens", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract IAuthorizer", - "name": "newAuthorizer", - "type": "address" - } - ], - "name": "setAuthorizer", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bool", - "name": "paused", - "type": "bool" - } - ], - "name": "setPaused", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "relayer", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setRelayerApproval", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "poolId", - "type": "bytes32" - }, - { - "internalType": "enum IVault.SwapKind", - "name": "kind", - "type": "uint8" - }, - { - "internalType": "contract IAsset", - "name": "assetIn", - "type": "address" - }, - { - "internalType": "contract IAsset", - "name": "assetOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "userData", - "type": "bytes" - } - ], - "internalType": "struct IVault.SingleSwap", - "name": "singleSwap", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "bool", - "name": "fromInternalBalance", - "type": "bool" - }, - { - "internalType": "address payable", - "name": "recipient", - "type": "address" - }, - { - "internalType": "bool", - "name": "toInternalBalance", - "type": "bool" - } - ], - "internalType": "struct IVault.FundManagement", - "name": "funds", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "limit", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "swap", - "outputs": [ - { - "internalType": "uint256", - "name": "amountCalculated", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], + "abi": [{"inputs":[{"internalType":"contract IAuthorizer","name":"authorizer","type":"address"},{"internalType":"contract IWETH","name":"weth","type":"address"},{"internalType":"uint256","name":"pauseWindowDuration","type":"uint256"},{"internalType":"uint256","name":"bufferPeriodDuration","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IAuthorizer","name":"newAuthorizer","type":"address"}],"name":"AuthorizerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ExternalBalanceTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IFlashLoanRecipient","name":"recipient","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeAmount","type":"uint256"}],"name":"FlashLoan","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"int256","name":"delta","type":"int256"}],"name":"InternalBalanceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"PausedStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"liquidityProvider","type":"address"},{"indexed":false,"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"indexed":false,"internalType":"int256[]","name":"deltas","type":"int256[]"},{"indexed":false,"internalType":"uint256[]","name":"protocolFeeAmounts","type":"uint256[]"}],"name":"PoolBalanceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"assetManager","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"int256","name":"cashDelta","type":"int256"},{"indexed":false,"internalType":"int256","name":"managedDelta","type":"int256"}],"name":"PoolBalanceManaged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"poolAddress","type":"address"},{"indexed":false,"internalType":"enum IVault.PoolSpecialization","name":"specialization","type":"uint8"}],"name":"PoolRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"relayer","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"RelayerApprovalChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":true,"internalType":"contract IERC20","name":"tokenIn","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"contract IERC20[]","name":"tokens","type":"address[]"}],"name":"TokensDeregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"assetManagers","type":"address[]"}],"name":"TokensRegistered","type":"event"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum IVault.SwapKind","name":"kind","type":"uint8"},{"components":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"uint256","name":"assetInIndex","type":"uint256"},{"internalType":"uint256","name":"assetOutIndex","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"internalType":"struct IVault.BatchSwapStep[]","name":"swaps","type":"tuple[]"},{"internalType":"contract IAsset[]","name":"assets","type":"address[]"},{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"bool","name":"fromInternalBalance","type":"bool"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"bool","name":"toInternalBalance","type":"bool"}],"internalType":"struct IVault.FundManagement","name":"funds","type":"tuple"},{"internalType":"int256[]","name":"limits","type":"int256[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"batchSwap","outputs":[{"internalType":"int256[]","name":"assetDeltas","type":"int256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"}],"name":"deregisterTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address payable","name":"recipient","type":"address"},{"components":[{"internalType":"contract IAsset[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"minAmountsOut","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"},{"internalType":"bool","name":"toInternalBalance","type":"bool"}],"internalType":"struct IVault.ExitPoolRequest","name":"request","type":"tuple"}],"name":"exitPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IFlashLoanRecipient","name":"recipient","type":"address"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"flashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"getActionId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAuthorizer","outputs":[{"internalType":"contract IAuthorizer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDomainSeparator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"}],"name":"getInternalBalance","outputs":[{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getNextNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPausedState","outputs":[{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"uint256","name":"pauseWindowEndTime","type":"uint256"},{"internalType":"uint256","name":"bufferPeriodEndTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"}],"name":"getPool","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"enum IVault.PoolSpecialization","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"getPoolTokenInfo","outputs":[{"internalType":"uint256","name":"cash","type":"uint256"},{"internalType":"uint256","name":"managed","type":"uint256"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"address","name":"assetManager","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"}],"name":"getPoolTokens","outputs":[{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProtocolFeesCollector","outputs":[{"internalType":"contract ProtocolFeesCollector","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"relayer","type":"address"}],"name":"hasApprovedRelayer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"components":[{"internalType":"contract IAsset[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"maxAmountsIn","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"},{"internalType":"bool","name":"fromInternalBalance","type":"bool"}],"internalType":"struct IVault.JoinPoolRequest","name":"request","type":"tuple"}],"name":"joinPool","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"enum IVault.PoolBalanceOpKind","name":"kind","type":"uint8"},{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IVault.PoolBalanceOp[]","name":"ops","type":"tuple[]"}],"name":"managePoolBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"enum IVault.UserBalanceOpKind","name":"kind","type":"uint8"},{"internalType":"contract IAsset","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct IVault.UserBalanceOp[]","name":"ops","type":"tuple[]"}],"name":"manageUserBalance","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"enum IVault.SwapKind","name":"kind","type":"uint8"},{"components":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"uint256","name":"assetInIndex","type":"uint256"},{"internalType":"uint256","name":"assetOutIndex","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"internalType":"struct IVault.BatchSwapStep[]","name":"swaps","type":"tuple[]"},{"internalType":"contract IAsset[]","name":"assets","type":"address[]"},{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"bool","name":"fromInternalBalance","type":"bool"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"bool","name":"toInternalBalance","type":"bool"}],"internalType":"struct IVault.FundManagement","name":"funds","type":"tuple"}],"name":"queryBatchSwap","outputs":[{"internalType":"int256[]","name":"","type":"int256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum IVault.PoolSpecialization","name":"specialization","type":"uint8"}],"name":"registerPool","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"address[]","name":"assetManagers","type":"address[]"}],"name":"registerTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IAuthorizer","name":"newAuthorizer","type":"address"}],"name":"setAuthorizer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"relayer","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setRelayerApproval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"enum IVault.SwapKind","name":"kind","type":"uint8"},{"internalType":"contract IAsset","name":"assetIn","type":"address"},{"internalType":"contract IAsset","name":"assetOut","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"internalType":"struct IVault.SingleSwap","name":"singleSwap","type":"tuple"},{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"bool","name":"fromInternalBalance","type":"bool"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"bool","name":"toInternalBalance","type":"bool"}],"internalType":"struct IVault.FundManagement","name":"funds","type":"tuple"},{"internalType":"uint256","name":"limit","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swap","outputs":[{"internalType":"uint256","name":"amountCalculated","type":"uint256"}],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}], "bytecode": "6101806040523480156200001257600080fd5b5060405162006ed638038062006ed6833981016040819052620000359162000253565b8382826040518060400160405280601181526020017010985b185b98d95c88158c8815985d5b1d607a1b81525080604051806040016040528060018152602001603160f81b815250306001600160a01b031660001b89806001600160a01b03166080816001600160a01b031660601b815250505030604051620000b89062000245565b620000c491906200029f565b604051809103906000f080158015620000e1573d6000803e3d6000fd5b5060601b6001600160601b03191660a052600160005560c052815160209283012060e052805191012061010052507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61012052620001486276a70083111561019462000181565b6200015c62278d0082111561019562000181565b429091016101408190520161016052620001768162000196565b5050505050620002cc565b8162000192576200019281620001f2565b5050565b6040516001600160a01b038216907f94b979b6831a51293e2641426f97747feed46f17779fed9cd18d1ecefcfe92ef90600090a2600380546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b62461bcd60e51b6000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b610be680620062f083390190565b6000806000806080858703121562000269578384fd5b84516200027681620002b3565b60208601519094506200028981620002b3565b6040860151606090960151949790965092505050565b6001600160a01b0391909116815260200190565b6001600160a01b0381168114620002c957600080fd5b50565b60805160601c60a05160601c60c05160e05161010051610120516101405161016051615fc06200033060003980611aed525080611ac952508061289f5250806128e15250806128c05250806110fd5250806113b15250806105285250615fc06000f3fe6080604052600436106101a55760003560e01c8063945bcec9116100e1578063e6c460921161008a578063f84d066e11610064578063f84d066e1461048a578063f94d4668146104aa578063fa6e671d146104d9578063fec90d72146104f9576101d3565b8063e6c4609214610427578063ed24911d14610447578063f6c009271461045c576101d3565b8063b05f8e48116100bb578063b05f8e48146103cf578063b95cac28146103ff578063d2946c2b14610412576101d3565b8063945bcec914610385578063aaabadc514610398578063ad5c4648146103ba576101d3565b806352bbbe291161014e5780637d3aeb96116101285780637d3aeb9614610305578063851c1bb3146103255780638bdb39131461034557806390193b7c14610365576101d3565b806352bbbe29146102b25780635c38449e146102c557806366a9c7d2146102e5576101d3565b80630f5a6efa1161017f5780630f5a6efa1461024157806316c38b3c1461026e5780631c0de0511461028e576101d3565b8063058a628f146101d857806309b2760f146101f85780630e8e3e841461022e576101d3565b366101d3576101d16101b5610526565b6001600160a01b0316336001600160a01b03161461020661054b565b005b600080fd5b3480156101e457600080fd5b506101d16101f3366004615157565b61055d565b34801561020457600080fd5b506102186102133660046156e6565b610581565b6040516102259190615d3e565b60405180910390f35b6101d161023c36600461531e565b610634565b34801561024d57600080fd5b5061026161025c3660046151f5565b610770565b6040516102259190615d08565b34801561027a57600080fd5b506101d161028936600461545c565b610806565b34801561029a57600080fd5b506102a361081f565b60405161022593929190615d26565b6102186102c036600461588f565b610848565b3480156102d157600080fd5b506101d16102e036600461565b565b6109e9565b3480156102f157600080fd5b506101d1610300366004615545565b610e06565b34801561031157600080fd5b506101d1610320366004615516565b610fa5565b34801561033157600080fd5b50610218610340366004615633565b6110f9565b34801561035157600080fd5b506101d16103603660046154ac565b61114b565b34801561037157600080fd5b50610218610380366004615157565b611161565b610261610393366004615786565b61117c565b3480156103a457600080fd5b506103ad6112b0565b6040516102259190615b63565b3480156103c657600080fd5b506103ad6112c4565b3480156103db57600080fd5b506103ef6103ea36600461560f565b6112d3565b6040516102259493929190615eb9565b6101d161040d3660046154ac565b611396565b34801561041e57600080fd5b506103ad6113af565b34801561043357600080fd5b506101d1610442366004615243565b6113d3565b34801561045357600080fd5b506102186114ef565b34801561046857600080fd5b5061047c610477366004615494565b6114f9565b604051610225929190615b9b565b34801561049657600080fd5b506102616104a5366004615702565b611523565b3480156104b657600080fd5b506104ca6104c5366004615494565b611620565b60405161022593929190615cd2565b3480156104e557600080fd5b506101d16104f43660046151ab565b611654565b34801561050557600080fd5b50610519610514366004615173565b6116e6565b6040516102259190615d1b565b7f00000000000000000000000000000000000000000000000000000000000000005b90565b8161055957610559816116fb565b5050565b610565611768565b61056d611781565b610576816117af565b61057e611822565b50565b600061058b611768565b610593611829565b60006105a2338460065461183e565b6000818152600560205260409020549091506105c49060ff16156101f461054b565b60008181526005602052604090819020805460ff1916600190811790915560068054909101905551339082907f3c13bc30b8e878c53fd2a36b679409c073afd75950be43d8858768e956fbc20e9061061d908790615e3a565b60405180910390a3905061062f611822565b919050565b61063c611768565b6000806000805b845181101561075b5760008060008060006106718a878151811061066357fe5b60200260200101518961187d565b9c50939850919650945092509050600185600381111561068d57fe5b14156106a45761069f848383866118f5565b61074a565b866106b6576106b1611829565b600196505b60008560038111156106c457fe5b14156106f5576106d684838386611918565b6106df84611938565b1561069f576106ee8984611945565b985061074a565b61070a61070185611938565b1561020761054b565b600061071585610548565b9050600286600381111561072557fe5b141561073c5761073781848487611957565b610748565b61074881848487611970565b505b505060019093019250610643915050565b50610765836119de565b50505061057e611822565b6060815167ffffffffffffffff8111801561078a57600080fd5b506040519080825280602002602001820160405280156107b4578160200160208202803683370190505b50905060005b82518110156107ff576107e0848483815181106107d357fe5b6020026020010151611a01565b8282815181106107ec57fe5b60209081029190910101526001016107ba565b5092915050565b61080e611768565b610816611781565b61057681611a2c565b600080600061082c611aaa565b159250610837611ac7565b9150610841611aeb565b9050909192565b6000610852611768565b61085a611829565b835161086581611b0f565b610874834211156101fc61054b565b61088760008760800151116101fe61054b565b60006108968760400151611b41565b905060006108a78860600151611b41565b90506108ca816001600160a01b0316836001600160a01b031614156101fd61054b565b6108d2614ce1565b885160808201526020890151819060018111156108eb57fe5b908160018111156108f857fe5b9052506001600160a01b03808416602083015282811660408084019190915260808b0151606084015260a08b01516101008401528951821660c08401528901511660e082015260008061094a83611b66565b9198509250905061098160008c60200151600181111561096657fe5b146109745789831115610979565b898210155b6101fb61054b565b6109998b60400151838c600001518d60200151611c5a565b6109b18b60600151828c604001518d60600151611d38565b6109d36109c18c60400151611938565b6109cc5760006109ce565b825b6119de565b5050505050506109e1611822565b949350505050565b6109f1611768565b6109f9611829565b610a0583518351611e12565b6060835167ffffffffffffffff81118015610a1f57600080fd5b50604051908082528060200260200182016040528015610a49578160200160208202803683370190505b5090506060845167ffffffffffffffff81118015610a6657600080fd5b50604051908082528060200260200182016040528015610a90578160200160208202803683370190505b5090506000805b8651811015610c09576000878281518110610aae57fe5b602002602001015190506000878381518110610ac657fe5b60200260200101519050610b11846001600160a01b0316836001600160a01b03161160006001600160a01b0316846001600160a01b031614610b09576066610b0c565b60685b61054b565b819350816001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610b409190615b63565b60206040518083038186803b158015610b5857600080fd5b505afa158015610b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b909190615968565b858481518110610b9c57fe5b602002602001018181525050610bb181611e1f565b868481518110610bbd57fe5b602002602001018181525050610beb81868581518110610bd957fe5b6020026020010151101561021061054b565b610bff6001600160a01b0383168b83611ea6565b5050600101610a97565b506040517ff04f27070000000000000000000000000000000000000000000000000000000081526001600160a01b0388169063f04f270790610c55908990899088908a90600401615c85565b600060405180830381600087803b158015610c6f57600080fd5b505af1158015610c83573d6000803e3d6000fd5b5050505060005b8651811015610df4576000878281518110610ca157fe5b602002602001015190506000848381518110610cb957fe5b602002602001015190506000826001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610cf19190615b63565b60206040518083038186803b158015610d0957600080fd5b505afa158015610d1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d419190615968565b9050610d528282101561020361054b565b60008282039050610d7b888681518110610d6857fe5b602002602001015182101561025a61054b565b610d858482611f11565b836001600160a01b03168c6001600160a01b03167f0d7d75e01ab95780d3cd1c8ec0dd6c2ce19e3a20427eec8bf53283b6fb8e95f08c8881518110610dc657fe5b602002602001015184604051610ddd929190615e4d565b60405180910390a350505050806001019050610c8a565b50505050610e00611822565b50505050565b610e0e611768565b610e16611829565b82610e2081611f33565b610e2c83518351611e12565b60005b8351811015610eca576000848281518110610e4657fe5b60200260200101519050610e7260006001600160a01b0316826001600160a01b0316141561013561054b565b838281518110610e7e57fe5b6020908102919091018101516000888152600a835260408082206001600160a01b0395861683529093529190912080546001600160a01b03191692909116919091179055600101610e2f565b506000610ed685611f64565b90506002816002811115610ee657fe5b1415610f3457610efc845160021461020c61054b565b610f2f8585600081518110610f0d57fe5b602002602001015186600181518110610f2257fe5b6020026020010151611f7e565b610f5c565b6001816002811115610f4257fe5b1415610f5257610f2f858561202a565b610f5c8585612082565b847ff5847d3f2197b16cdcd2098ec95d0905cd1abdaf415f07bb7cef2bba8ac5dec48585604051610f8e929190615bed565b60405180910390a25050610fa0611822565b505050565b610fad611768565b610fb5611829565b81610fbf81611f33565b6000610fca84611f64565b90506002816002811115610fda57fe5b141561102857610ff0835160021461020c61054b565b611023848460008151811061100157fe5b60200260200101518560018151811061101657fe5b60200260200101516120d7565b611050565b600181600281111561103657fe5b1415611046576110238484612145565b61105084846121ff565b60005b83518110156110b657600a6000868152602001908152602001600020600085838151811061107d57fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055600101611053565b50837f7dcdc6d02ef40c7c1a7046a011b058bd7f988fa14e20a66344f9d4e60657d610846040516110e79190615bda565b60405180910390a25050610559611822565b60007f00000000000000000000000000000000000000000000000000000000000000008260405160200161112e929190615ac2565b604051602081830303815290604052805190602001209050919050565b610e00600185858561115c86612262565b61226e565b6001600160a01b031660009081526002602052604090205490565b6060611186611768565b61118e611829565b835161119981611b0f565b6111a8834211156101fc61054b565b6111b486518551611e12565b6111c08787878b6123f4565b91506000805b87518110156112925760008882815181106111dd57fe5b6020026020010151905060008583815181106111f557fe5b6020026020010151905061122188848151811061120e57fe5b60200260200101518213156101fb61054b565b600081131561126157885160208a015182916112409185918491611c5a565b61124983611938565b1561125b576112588582611945565b94505b50611288565b600081121561128857600081600003905061128683828c604001518d60600151611d38565b505b50506001016111c6565b5061129c816119de565b50506112a6611822565b9695505050505050565b60035461010090046001600160a01b031690565b60006112ce610526565b905090565b600080600080856112e381612683565b6000806112ef89611f64565b905060028160028111156112ff57fe5b14156113165761130f89896126a1565b9150611341565b600181600281111561132457fe5b14156113345761130f898961271b565b61133e8989612789565b91505b61134a826127a1565b9650611355826127b4565b9550611360826127ca565b6000998a52600a60209081526040808c206001600160a01b039b8c168d5290915290992054969995989796909616955050505050565b61139e611829565b610e00600085858561115c86612262565b7f000000000000000000000000000000000000000000000000000000000000000090565b6113db611768565b6113e3611829565b6113eb614d31565b60005b82518110156114e55782818151811061140357fe5b6020026020010151915060008260200151905061141f81612683565b604083015161143961143183836127d0565b61020961054b565b6000828152600a602090815260408083206001600160a01b03858116855292529091205461146c911633146101f661054b565b835160608501516000806114828487878661282c565b91509150846001600160a01b0316336001600160a01b0316877f6edcaf6241105b4c94c2efdbf3a6b12458eb3d07be3a0e81d24b13c44045fe7a85856040516114cc929190615e4d565b60405180910390a45050505050508060010190506113ee565b505061057e611822565b60006112ce61289b565b6000808261150681612683565b61150f84612938565b61151885611f64565b925092505b50915091565b60603330146115f6576000306001600160a01b0316600036604051611549929190615ada565b6000604051808303816000865af19150503d8060008114611586576040519150601f19603f3d011682016040523d82523d6000602084013e61158b565b606091505b50509050806000811461159a57fe5b60046000803e6000516001600160e01b0319167ffa61cc120000000000000000000000000000000000000000000000000000000081146115de573d6000803e3d6000fd5b50602060005260043d0380600460203e602081016000f35b6060611604858585896123f4565b9050602081510263fa61cc126020830352600482036024820181fd5b60608060008361162f81612683565b606061163a8661293e565b9095509050611648816129a0565b95979096509350505050565b61165c611768565b611664611829565b8261166e81611b0f565b6001600160a01b0384811660008181526004602090815260408083209488168084529490915290819020805460ff1916861515179055519091907f46961fdb4502b646d5095fba7600486a8ac05041d55cdf0f16ed677180b5cad8906116d5908690615d1b565b60405180910390a350610fa0611822565b60006116f28383612a4f565b90505b92915050565b7f08c379a0000000000000000000000000000000000000000000000000000000006000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b61177a6002600054141561019061054b565b6002600055565b60006117986000356001600160e01b0319166110f9565b905061057e6117a78233612a7d565b61019161054b565b6040516001600160a01b038216907f94b979b6831a51293e2641426f97747feed46f17779fed9cd18d1ecefcfe92ef90600090a2600380546001600160a01b03909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b6001600055565b61183c611834611aaa565b61019261054b565b565b600069ffffffffffffffffffff8216605084600281111561185b57fe5b901b17606085901b6bffffffffffffffffffffffff19161790505b9392505050565b600080600080600080600088606001519050336001600160a01b0316816001600160a01b0316146118cf57876118ba576118b5611781565b600197505b6118cf6118c78233612a4f565b6101f761054b565b885160208a015160408b01516080909b0151919b909a9992985090965090945092505050565b61190a8361190286611b41565b836000612b20565b50610e008482846000611d38565b61192b8261192586611b41565b83612b76565b610e008482856000611c5a565b6001600160a01b03161590565b60008282016116f2848210158361054b565b6119648385836000612b20565b50610e00828583612b76565b8015610e005761198b6001600160a01b038516848484612ba6565b826001600160a01b0316846001600160a01b03167f540a1a3f28340caec336c81d8d7b3df139ee5cdc1839a4f283d7ebb7eaae2d5c84846040516119d0929190615bc1565b60405180910390a350505050565b6119ed8134101561020461054b565b348190038015610559576105593382612bc7565b6001600160a01b039182166000908152600b6020908152604080832093909416825291909152205490565b8015611a4c57611a47611a3d611ac7565b421061019361054b565b611a61565b611a61611a57611aeb565b42106101a961054b565b6003805460ff19168215151790556040517f9e3a5e37224532dea67b89face185703738a228a6e8a23dee546960180d3be6490611a9f908390615d1b565b60405180910390a150565b6000611ab4611aeb565b4211806112ce57505060035460ff161590565b7f000000000000000000000000000000000000000000000000000000000000000090565b7f000000000000000000000000000000000000000000000000000000000000000090565b336001600160a01b0382161461057e57611b27611781565b611b318133612a4f565b61057e5761057e816101f7612c41565b6000611b4c82611938565b611b5e57611b5982610548565b6116f5565b6116f5610526565b600080600080611b798560800151612938565b90506000611b8a8660800151611f64565b90506002816002811115611b9a57fe5b1415611bb157611baa8683612c75565b9450611bdc565b6001816002811115611bbf57fe5b1415611bcf57611baa8683612d25565b611bd98683612db8565b94505b611bef8660000151876060015187612ff7565b809450819550505085604001516001600160a01b031686602001516001600160a01b031687608001517f2170c741c41531aec20e7c107c24eecfdd15e69c9bb0a8dd37b1840b9e0b207b8787604051611c49929190615e4d565b60405180910390a450509193909250565b82611c6457610e00565b611c6d84611938565b15611cee57611c7f811561020261054b565b611c8e8347101561020461054b565b611c96610526565b6001600160a01b031663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b158015611cd057600080fd5b505af1158015611ce4573d6000803e3d6000fd5b5050505050610e00565b6000611cf985610548565b90508115611d16576000611d108483876001612b20565b90940393505b8315611d3157611d316001600160a01b038216843087612ba6565b5050505050565b82611d4257610e00565b611d4b84611938565b15611ddb57611d5d811561020261054b565b611d65610526565b6001600160a01b0316632e1a7d4d846040518263ffffffff1660e01b8152600401611d909190615d3e565b600060405180830381600087803b158015611daa57600080fd5b505af1158015611dbe573d6000803e3d6000fd5b50611dd6925050506001600160a01b03831684612bc7565b610e00565b6000611de685610548565b90508115611dfe57611df9838286612b76565b611d31565b611d316001600160a01b0382168486611ea6565b610559818314606761054b565b600080611e2a6113af565b6001600160a01b031663d877845c6040518163ffffffff1660e01b815260040160206040518083038186803b158015611e6257600080fd5b505afa158015611e76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9a9190615968565b90506118768382613025565b610fa08363a9059cbb60e01b8484604051602401611ec5929190615bc1565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b031990931692909217909152613072565b801561055957610559611f226113af565b6001600160a01b0384169083611ea6565b611f3c81612683565b61057e611f4882612938565b6001600160a01b0316336001600160a01b0316146101f561054b565b600061ffff605083901c166116f5600382106101f461054b565b611f9f816001600160a01b0316836001600160a01b0316141561020a61054b565b611fbe816001600160a01b0316836001600160a01b031610606661054b565b60008381526009602052604090208054611ffb906001600160a01b0316158015611ff3575060018201546001600160a01b0316155b61020b61054b565b80546001600160a01b039384166001600160a01b03199182161782556001909101805492909316911617905550565b6000828152600860205260408120905b8251811015610e0057600061206b84838151811061205457fe5b60200260200101518461311290919063ffffffff16565b90506120798161020a61054b565b5060010161203a565b6000828152600160205260408120905b8251811015610e005760006120c08483815181106120ac57fe5b602090810291909101015184906000613175565b90506120ce8161020a61054b565b50600101612092565b60008060006120e7868686613222565b9250925092506121116120f9846132e9565b80156121095750612109836132e9565b61020d61054b565b600095865260096020526040862080546001600160a01b031990811682556001909101805490911690559490945550505050565b6000828152600860205260408120905b8251811015610e0057600083828151811061216c57fe5b602002602001015190506121b8612109600760008881526020019081526020016000206000846001600160a01b03166001600160a01b03168152602001908152602001600020546132e9565b60008581526007602090815260408083206001600160a01b038516845290915281208190556121e7848361330b565b90506121f58161020961054b565b5050600101612155565b6000828152600160205260408120905b8251811015610e0057600083828151811061222657fe5b60200260200101519050600061223c8483613412565b905061224a612109826132e9565b6122548483613421565b50505080600101905061220f565b61226a614d5a565b5090565b612276611768565b8361228081612683565b8361228a81611b0f565b61229e836000015151846020015151611e12565b60606122ad84600001516134c3565b905060606122bb8883613552565b905060608060606122d08c8c8c8c8c896135e3565b92509250925060006122e18c611f64565b905060028160028111156122f157fe5b1415612359576123548c8760008151811061230857fe5b60200260200101518660008151811061231d57fe5b60200260200101518960018151811061233257fe5b60200260200101518860018151811061234757fe5b60200260200101516137a8565b612382565b600181600281111561236757fe5b1415612378576123548c87866137e7565b6123828c85613854565b6000808e600181111561239157fe5b1490508b6001600160a01b03168d7fe5ce249087ce04f05a957192435400fd97868dba0e6a4b4c049abf8af80dae78896123cb888661389d565b876040516123db93929190615c4c565b60405180910390a3505050505050505050611d31611822565b6060835167ffffffffffffffff8111801561240e57600080fd5b50604051908082528060200260200182016040528015612438578160200160208202803683370190505b509050612443614d84565b61244b614ce1565b60008060005b89518110156126765789818151811061246657fe5b6020026020010151945060008951866020015110801561248a575089518660400151105b905061249781606461054b565b60006124b98b8860200151815181106124ac57fe5b6020026020010151611b41565b905060006124d08c8960400151815181106124ac57fe5b90506124f3816001600160a01b0316836001600160a01b031614156101fd61054b565b60608801516125435761250b600085116101fe61054b565b60006125188b8484613945565b6001600160a01b0316876001600160a01b031614905061253a816101ff61054b565b50606088018590525b87516080880152868a600181111561255757fe5b9081600181111561256457fe5b9052506001600160a01b0380831660208901528181166040808a01919091526060808b0151908a015260808a01516101008a01528c51821660c08a01528c01511660e08801526000806125b689611b66565b919850925090506125c88c8585613967565b97506125fc6125d683613981565b8c8c60200151815181106125e657fe5b60200260200101516139b190919063ffffffff16565b8b8b602001518151811061260c57fe5b60200260200101818152505061264a61262482613981565b8c8c604001518151811061263457fe5b60200260200101516139e590919063ffffffff16565b8b8b604001518151811061265a57fe5b6020026020010181815250505050505050806001019050612451565b5050505050949350505050565b60008181526005602052604090205461057e9060ff166101f461054b565b60008060008060006126b287613a19565b945094509450945050836001600160a01b0316866001600160a01b031614156126e157829450505050506116f5565b816001600160a01b0316866001600160a01b031614156127065793506116f592505050565b6127116102096116fb565b5050505092915050565b60008281526007602090815260408083206001600160a01b03851684529091528120548161274882613a8f565b80612766575060008581526008602052604090206127669085613aa1565b9050806127815761277685612683565b6127816102096116fb565b509392505050565b60008281526001602052604081206109e18184613412565b6dffffffffffffffffffffffffffff1690565b60701c6dffffffffffffffffffffffffffff1690565b60e01c90565b6000806127dc84611f64565b905060028160028111156127ec57fe5b1415612804576127fc8484613ac2565b9150506116f5565b600181600281111561281257fe5b1415612822576127fc8484613b13565b6127fc8484613b2b565b600080600061283a86611f64565b9050600087600281111561284a57fe5b14156128665761285c86828787613b43565b9250925050612892565b600187600281111561287457fe5b14156128865761285c86828787613bbe565b61285c86828787613c3a565b94509492505050565b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612908613c9d565b3060405160200161291d959493929190615df0565b60405160208183030381529060405280519060200120905090565b60601c90565b606080600061294c84611f64565b9050600281600281111561295c57fe5b14156129755761296b84613ca1565b925092505061299b565b600181600281111561298357fe5b14156129925761296b84613dd6565b61296b84613efd565b915091565b60606000825167ffffffffffffffff811180156129bc57600080fd5b506040519080825280602002602001820160405280156129e6578160200160208202803683370190505b5091506000905060005b825181101561151d576000848281518110612a0757fe5b60200260200101519050612a1a81613ff9565b848381518110612a2657fe5b602002602001018181525050612a4483612a3f836127ca565b614014565b9250506001016129f0565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205460ff1690565b6003546040517f9be2a88400000000000000000000000000000000000000000000000000000000815260009161010090046001600160a01b031690639be2a88490612ad090869086903090600401615d47565b60206040518083038186803b158015612ae857600080fd5b505afa158015612afc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f29190615478565b600080612b2d8686611a01565b9050612b468380612b3e5750848210155b61020161054b565b612b50818561402b565b9150818103612b6c878783612b6487613981565b60000361403a565b5050949350505050565b6000612b828484611a01565b90506000612b908284611945565b9050611d31858583612ba187613981565b61403a565b610e00846323b872dd60e01b858585604051602401611ec593929190615b77565b612bd6814710156101a361054b565b6000826001600160a01b031682604051612bef90610548565b60006040518083038185875af1925050503d8060008114612c2c576040519150601f19603f3d011682016040523d82523d6000602084013e612c31565b606091505b50509050610fa0816101a461054b565b6001600160a01b0382166000908152600260205260409020805460018101909155610fa0612c6f8483614095565b8361054b565b600080600080612c92866080015187602001518860400151613222565b92509250925060008087604001516001600160a01b031688602001516001600160a01b03161015612cc7575083905082612ccd565b50829050835b612cd9888884846141bb565b60408b015160208c01519199509294509092506001600160a01b03918216911610612d0d57612d0881836142d1565b612d17565b612d1782826142d1565b909255509295945050505050565b600080612d3a8460800151856020015161271b565b90506000612d508560800151866040015161271b565b9050612d5e858584846141bb565b6080880180516000908152600760208181526040808420828e01516001600160a01b03908116865290835281852098909855935183529081528282209a830151909516815298909352919096209590955550929392505050565b60808201516000908152600160209081526040822090840151829182918290612de290839061430c565b90506000612dfd88604001518461430c90919063ffffffff16565b9050811580612e0a575080155b15612e2757612e1c8860800151612683565b612e276102096116fb565b60001991820191016000612e3a8461432b565b905060608167ffffffffffffffff81118015612e5557600080fd5b50604051908082528060200260200182016040528015612e7f578160200160208202803683370190505b50600060a08c018190529091505b82811015612eff576000612ea1878361432f565b9050612eac81613ff9565b838381518110612eb857fe5b602002602001018181525050612ed58c60a00151612a3f836127ca565b60a08d015281861415612eea57809850612ef6565b84821415612ef6578097505b50600101612e8d565b506040517f01ec954a0000000000000000000000000000000000000000000000000000000081526001600160a01b038a16906301ec954a90612f4b908d90859089908990600401615e5b565b602060405180830381600087803b158015612f6557600080fd5b505af1158015612f79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f9d9190615968565b9750600080612fb58c600001518d606001518c612ff7565b9092509050612fc48983614345565b9850612fd08882614376565b9750612fdd87878b61438c565b612fe887868a61438c565b50505050505050505092915050565b6000808085600181111561300757fe5b141561301757508290508161301d565b50819050825b935093915050565b600082820261304984158061304257508385838161303f57fe5b04145b600361054b565b806130585760009150506116f5565b670de0b6b3a76400006000198201046001019150506116f5565b60006060836001600160a01b03168360405161308e9190615aea565b6000604051808303816000865af19150503d80600081146130cb576040519150601f19603f3d011682016040523d82523d6000602084013e6130d0565b606091505b509150915060008214156130e8573d6000803e3d6000fd5b610e0081516000148061310a57508180602001905181019061310a9190615478565b6101a261054b565b600061311e8383613aa1565b61316d57508154600180820184556000848152602080822090930180546001600160a01b0319166001600160a01b038616908117909155855490825282860190935260409020919091556116f5565b5060006116f5565b6001600160a01b03821660009081526002840160205260408120548061320257505082546040805180820182526001600160a01b03858116808352602080840187815260008781526001808c018452878220965187546001600160a01b03191696169590951786559051948401949094559482018089559083526002880190945291902091909155611876565b600019016000908152600180860160205260408220018390559050611876565b600080600080600061323487876143a4565b91509150600061324483836143d5565b60008a81526009602090815260408083208484526002019091528120805460018201549197509293509061327783613a8f565b80613286575061328682613a8f565b806132a757506132968c87613ac2565b80156132a757506132a78c86613ac2565b9050806132c2576132b78c612683565b6132c26102096116fb565b6132cc8383614408565b98506132d8838361442d565b975050505050505093509350939050565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161590565b6001600160a01b03811660009081526001830160205260408120548015613408578354600019808301919081019060009087908390811061334857fe5b60009182526020909120015487546001600160a01b039091169150819088908590811061337157fe5b600091825260208083209190910180546001600160a01b0319166001600160a01b039485161790559183168152600189810190925260409020908401905586548790806133ba57fe5b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b03881682526001898101909152604082209190915594506116f59350505050565b60009150506116f5565b60006116f28383610209614444565b6001600160a01b0381166000908152600283016020526040812054801561340857835460001990810160008181526001878101602090815260408084209587018452808420865481546001600160a01b03199081166001600160a01b0392831617835588860180549387019390935588548216875260028d018086528488209a909a5588541690975584905593895593871682529390925281205590506116f5565b606080825167ffffffffffffffff811180156134de57600080fd5b50604051908082528060200260200182016040528015613508578160200160208202803683370190505b50905060005b83518110156107ff576135268482815181106124ac57fe5b82828151811061353257fe5b6001600160a01b039092166020928302919091019091015260010161350e565b60608060606135608561293e565b9150915061357082518551611e12565b613580600083511161020f61054b565b60005b82518110156135da576135d285828151811061359b57fe5b60200260200101516001600160a01b03168483815181106135b857fe5b60200260200101516001600160a01b03161461020861054b565b600101613583565b50949350505050565b60608060608060006135f4866129a0565b9150915060006136038b612938565b905060008c600181111561361357fe5b146136b657806001600160a01b03166374f3b0098c8c8c8787613634614481565b8f604001516040518863ffffffff1660e01b815260040161365b9796959493929190615d66565b600060405180830381600087803b15801561367557600080fd5b505af1158015613689573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526136b19190810190615405565b61374f565b806001600160a01b031663d5c096c48c8c8c87876136d2614481565b8f604001516040518863ffffffff1660e01b81526004016136f99796959493929190615d66565b600060405180830381600087803b15801561371357600080fd5b505af1158015613727573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261374f9190810190615405565b80955081965050506137658751865186516144fb565b60008c600181111561377357fe5b1461378a576137858989898888614513565b613797565b6137978a8989888861465a565b955050505096509650969350505050565b60006137b485846143d5565b600087815260096020908152604080832084845260020190915290209091506137dd85846142d1565b9055505050505050565b60005b8251811015610e00578181815181106137ff57fe5b602002602001015160076000868152602001908152602001600020600085848151811061382857fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020556001016137ea565b6000828152600160205260408120905b8251811015610e00576138958184838151811061387d57fe5b60200260200101518461438c9092919063ffffffff16565b600101613864565b6060825167ffffffffffffffff811180156138b757600080fd5b506040519080825280602002602001820160405280156138e1578160200160208202803683370190505b50905060005b83518110156107ff57826139115783818151811061390157fe5b6020026020010151600003613926565b83818151811061391d57fe5b60200260200101515b82828151811061393257fe5b60209081029190910101526001016138e7565b60008084600181111561395457fe5b1461395f57816109e1565b509092915050565b60008084600181111561397657fe5b146107ff57826109e1565b600061226a7f800000000000000000000000000000000000000000000000000000000000000083106101a561054b565b60008282016116f28284128015906139c95750848212155b806139de57506000841280156139de57508482125b600061054b565b60008183036116f28284128015906139fd5750848213155b80613a125750600084128015613a1257508482135b600161054b565b6000818152600960205260408120805460018201546001600160a01b0391821692849290911690829081613a4d86856143d5565b6000818152600284016020526040902080546001820154919950919250613a748282614408565b9650613a80828261442d565b94505050505091939590929450565b6000613a9a826132e9565b1592915050565b6001600160a01b031660009081526001919091016020526040902054151590565b600082815260096020526040812080546001600160a01b0384811691161480613afa575060018101546001600160a01b038481169116145b80156109e1575050506001600160a01b03161515919050565b60008281526008602052604081206109e18184613aa1565b60008281526001602052604081206109e181846147d0565b6000806002856002811115613b5457fe5b1415613b6a57613b658685856147f1565b613b94565b6001856002811115613b7857fe5b1415613b8957613b658685856147ff565b613b9486858561480d565b8215613bae57613bae6001600160a01b0385163385611ea6565b5050600081900394909350915050565b6000806002856002811115613bcf57fe5b1415613be557613be086858561481b565b613c0f565b6001856002811115613bf357fe5b1415613c0457613be0868585614829565b613c0f868585614837565b8215613c2a57613c2a6001600160a01b038516333086612ba6565b5090946000869003945092505050565b6000806002856002811115613c4b57fe5b1415613c6357613c5c868585614845565b9050613c90565b6001856002811115613c7157fe5b1415613c8257613c5c868585614855565b613c8d868585614865565b90505b6000915094509492505050565b4690565b606080600080600080613cb387613a19565b92975090955093509150506001600160a01b0384161580613cdb57506001600160a01b038216155b15613d04575050604080516000808252602082019081528183019092529450925061299b915050565b60408051600280825260608201835290916020830190803683370190505095508386600081518110613d3257fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508186600181518110613d6057fe5b6001600160a01b03929092166020928302919091018201526040805160028082526060820183529092909190830190803683370190505094508285600081518110613da757fe5b6020026020010181815250508085600181518110613dc157fe5b60200260200101818152505050505050915091565b60008181526008602052604090206060908190613df28161432b565b67ffffffffffffffff81118015613e0857600080fd5b50604051908082528060200260200182016040528015613e32578160200160208202803683370190505b509250825167ffffffffffffffff81118015613e4d57600080fd5b50604051908082528060200260200182016040528015613e77578160200160208202803683370190505b50915060005b8351811015613ef6576000613e928383614875565b905080858381518110613ea157fe5b6001600160a01b03928316602091820292909201810191909152600088815260078252604080822093851682529290915220548451859084908110613ee257fe5b602090810291909101015250600101613e7d565b5050915091565b60008181526001602052604090206060908190613f198161432b565b67ffffffffffffffff81118015613f2f57600080fd5b50604051908082528060200260200182016040528015613f59578160200160208202803683370190505b509250825167ffffffffffffffff81118015613f7457600080fd5b50604051908082528060200260200182016040528015613f9e578160200160208202803683370190505b50915060005b8351811015613ef657613fb782826148a2565b858381518110613fc357fe5b60200260200101858481518110613fd657fe5b60209081029190910101919091526001600160a01b039091169052600101613fa4565b6000614004826127b4565b61400d836127a1565b0192915050565b60008183101561402457816116f2565b5090919050565b600081831061402457816116f2565b6001600160a01b038085166000818152600b602090815260408083209488168084529490915290819020859055517f18e1ea4139e68413d7d08aa752e71568e36b2c5bf940893314c2c5b01eaa0c42906119d0908590615d3e565b6000806140a06148c6565b9050428110156140b45760009150506116f5565b60006140be6148d2565b9050806140d0576000925050506116f5565b6000816140db6149e3565b80516020918201206040516140f7939233918a91899101615dc4565b604051602081830303815290604052805190602001209050600061411a82614a32565b90506000806000614129614a4e565b9250925092506000600185858585604051600081526020016040526040516141549493929190615e1c565b6020604051602081039080840390855afa158015614176573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906141ac57508a6001600160a01b0316816001600160a01b0316145b9b9a5050505050505050505050565b6000806000806141ca86613ff9565b905060006141d786613ff9565b90506141ee6141e5886127ca565b612a3f886127ca565b60a08a01526040517f9d2c110c0000000000000000000000000000000000000000000000000000000081526001600160a01b03891690639d2c110c9061423c908c9086908690600401615e94565b602060405180830381600087803b15801561425657600080fd5b505af115801561426a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061428e9190615968565b92506000806142a68b600001518c6060015187612ff7565b90925090506142b58983614345565b96506142c18882614376565b9550505050509450945094915050565b6000806142e96142e0856127ca565b612a3f856127ca565b90506109e16142f7856127a1565b614300856127a1565b8363ffffffff16614a75565b6001600160a01b03166000908152600291909101602052604090205490565b5490565b6000908152600191820160205260409020015490565b60008061435b83614355866127a1565b90611945565b90506000614368856127b4565b9050436112a6838383614a83565b60008061435b83614386866127a1565b90614abc565b60009182526001928301602052604090912090910155565b600080826001600160a01b0316846001600160a01b0316106143c75782846143ca565b83835b915091509250929050565b600082826040516020016143ea929190615b06565b60405160208183030381529060405280519060200120905092915050565b60006116f2614416846127a1565b61441f846127a1565b614428866127ca565b614a83565b60006116f261443b846127b4565b61441f846127b4565b6001600160a01b038216600090815260028401602052604081205461446b8115158461054b565b614478856001830361432f565b95945050505050565b600061448b6113af565b6001600160a01b03166355c676286040518163ffffffff1660e01b815260040160206040518083038186803b1580156144c357600080fd5b505afa1580156144d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ce9190615968565b610fa0828414801561450c57508183145b606761054b565b6060835167ffffffffffffffff8111801561452d57600080fd5b50604051908082528060200260200182016040528015614557578160200160208202803683370190505b50905060005b85515181101561465057600084828151811061457557fe5b602002602001015190506145a58760200151838151811061459257fe5b60200260200101518210156101f961054b565b6000876000015183815181106145b757fe5b602002602001015190506145d181838b8b60600151611d38565b60008584815181106145df57fe5b602002602001015190506145fb6145f583611b41565b82611f11565b61462a6146088483611945565b89868151811061461457fe5b602002602001015161437690919063ffffffff16565b85858151811061463657fe5b60200260200101818152505050505080600101905061455d565b5095945050505050565b60606000845167ffffffffffffffff8111801561467657600080fd5b506040519080825280602002602001820160405280156146a0578160200160208202803683370190505b50915060005b8651518110156147c65760008582815181106146be57fe5b602002602001015190506146ee886020015183815181106146db57fe5b60200260200101518211156101fa61054b565b60008860000151838151811061470057fe5b6020026020010151905061471a81838c8c60600151611c5a565b61472381611938565b15614735576147328483611945565b93505b600086848151811061474357fe5b602002602001015190506147596145f583611b41565b80831015614778576147738382038a868151811061461457fe5b6147a0565b6147a08184038a868151811061478a57fe5b602002602001015161434590919063ffffffff16565b8685815181106147ac57fe5b6020026020010181815250505050508060010190506146a6565b50614650816119de565b6001600160a01b031660009081526002919091016020526040902054151590565b610e008383614ad284614b0d565b610e008383614ad284614bb8565b610e008383614ad284614c13565b610e008383614c6284614b0d565b610e008383614c6284614bb8565b610e008383614c6284614c13565b60006109e18484614c8385614b0d565b60006109e18484614c8385614bb8565b60006109e18484614c8385614c13565b600082600001828154811061488657fe5b6000918252602090912001546001600160a01b03169392505050565b600090815260019182016020526040902080549101546001600160a01b0390911691565b60006112ce6000614c9d565b6000803560e01c8063b95cac28811461491a57638bdb39138114614942576352bbbe29811461496a5763945bcec981146149925763fa6e671d81146149ba57600092506149de565b7f3f7b71252bd19113ff48c19c6e004a9bcfcca320a0d74d58e85877cbd7dcae5892506149de565b7f8bbc57f66ea936902f50a71ce12b92c43f3c5340bb40c27c4e90ab84eeae335392506149de565b7fe192dcbc143b1e244ad73b813fd3c097b832ad260a157340b4e5e5beda067abe92506149de565b7f9bfc43a4d98313c6766986ffd7c916c7481566d9f224c6819af0a53388aced3a92506149de565b7fa3f865aa351e51cfeb40f5178d1564bb629fe9030b83caf6361d1baaf5b90b5a92505b505090565b60606000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505050608010156105485760803603815290565b6000614a3c61289b565b8260405160200161112e929190615b2d565b6000806000614a5d6020614c9d565b9250614a696040614c9d565b91506108416060614c9d565b60e01b60709190911b010190565b6000838301614ab1858210801590614aa957506e01000000000000000000000000000082105b61020e61054b565b614478858585614a75565b6000614acc83831115600161054b565b50900390565b600080614ae283614386866127a1565b90506000614af384614355876127b4565b90506000614b00866127ca565b90506112a6838383614a83565b6000806000806000614b1e89613a19565b9450509350935093506000836001600160a01b0316896001600160a01b03161415614b69576000614b5384898b63ffffffff16565b9050614b5f8185614ca7565b9093509050614b8b565b6000614b7983898b63ffffffff16565b9050614b858184614ca7565b90925090505b614b9583836142d1565b8555614ba18383614cc3565b600190950194909455509192505050949350505050565b600080614bc5868661271b565b90506000614bd782858763ffffffff16565b60008881526007602090815260408083206001600160a01b038b16845290915290208190559050614c088183614ca7565b979650505050505050565b600084815260016020526040812081614c2c8287613412565b90506000614c3e82868863ffffffff16565b9050614c4b838883613175565b50614c568183614ca7565b98975050505050505050565b600080614c7283614355866127a1565b90506000614af384614386876127b4565b600080614c8f846127a1565b905043614478828583614a83565b3601607f19013590565b6000614cb2826127b4565b614cbb846127b4565b039392505050565b60006116f2614cd1846127b4565b614cda846127b4565b6000614a75565b60408051610120810190915280600081526000602082018190526040820181905260608083018290526080830182905260a0830182905260c0830182905260e08301919091526101009091015290565b604080516080810190915280600081526000602082018190526040820181905260609091015290565b60405180608001604052806060815260200160608152602001606081526020016000151581525090565b6040518060a0016040528060008019168152602001600081526020016000815260200160008152602001606081525090565b80356116f581615f5a565b600082601f830112614dd1578081fd5b8135614de4614ddf82615f04565b615edd565b818152915060208083019084810181840286018201871015614e0557600080fd5b60005b84811015614e2d578135614e1b81615f5a565b84529282019290820190600101614e08565b505050505092915050565b600082601f830112614e48578081fd5b8135614e56614ddf82615f04565b818152915060208083019084810160005b84811015614e2d578135870160a080601f19838c03011215614e8857600080fd5b614e9181615edd565b85830135815260408084013587830152606080850135828401526080915081850135818401525082840135925067ffffffffffffffff831115614ed357600080fd5b614ee18c8885870101614fc0565b90820152865250509282019290820190600101614e67565b600082601f830112614f09578081fd5b8135614f17614ddf82615f04565b818152915060208083019084810181840286018201871015614f3857600080fd5b60005b84811015614e2d57813584529282019290820190600101614f3b565b600082601f830112614f67578081fd5b8151614f75614ddf82615f04565b818152915060208083019084810181840286018201871015614f9657600080fd5b60005b84811015614e2d57815184529282019290820190600101614f99565b80356116f581615f6f565b600082601f830112614fd0578081fd5b813567ffffffffffffffff811115614fe6578182fd5b614ff9601f8201601f1916602001615edd565b915080825283602082850101111561501057600080fd5b8060208401602084013760009082016020015292915050565b80356116f581615f7d565b8035600281106116f557600080fd5b8035600481106116f557600080fd5b600060808284031215615063578081fd5b61506d6080615edd565b9050813567ffffffffffffffff8082111561508757600080fd5b61509385838601614dc1565b835260208401359150808211156150a957600080fd5b6150b585838601614ef9565b602084015260408401359150808211156150ce57600080fd5b506150db84828501614fc0565b6040830152506150ee8360608401614fb5565b606082015292915050565b60006080828403121561510a578081fd5b6151146080615edd565b9050813561512181615f5a565b8152602082013561513181615f6f565b6020820152604082013561514481615f5a565b604082015260608201356150ee81615f6f565b600060208284031215615168578081fd5b81356116f281615f5a565b60008060408385031215615185578081fd5b823561519081615f5a565b915060208301356151a081615f5a565b809150509250929050565b6000806000606084860312156151bf578081fd5b83356151ca81615f5a565b925060208401356151da81615f5a565b915060408401356151ea81615f6f565b809150509250925092565b60008060408385031215615207578182fd5b823561521281615f5a565b9150602083013567ffffffffffffffff81111561522d578182fd5b61523985828601614dc1565b9150509250929050565b60006020808385031215615255578182fd5b823567ffffffffffffffff81111561526b578283fd5b8301601f8101851361527b578283fd5b8035615289614ddf82615f04565b818152838101908385016080808502860187018a10156152a7578788fd5b8795505b848610156153105780828b0312156152c1578788fd5b6152ca81615edd565b6152d48b84615029565b8152878301358882015260406152ec8c828601614db6565b908201526060838101359082015284526001959095019492860192908101906152ab565b509098975050505050505050565b60006020808385031215615330578182fd5b823567ffffffffffffffff811115615346578283fd5b8301601f81018513615356578283fd5b8035615364614ddf82615f04565b8181528381019083850160a0808502860187018a1015615382578788fd5b8795505b848610156153105780828b03121561539c578788fd5b6153a581615edd565b6153af8b84615043565b81526153bd8b898501614db6565b818901526040838101359082015260606153d98c828601614db6565b9082015260806153eb8c858301614db6565b908201528452600195909501949286019290810190615386565b60008060408385031215615417578182fd5b825167ffffffffffffffff8082111561542e578384fd5b61543a86838701614f57565b9350602085015191508082111561544f578283fd5b5061523985828601614f57565b60006020828403121561546d578081fd5b81356116f281615f6f565b600060208284031215615489578081fd5b81516116f281615f6f565b6000602082840312156154a5578081fd5b5035919050565b600080600080608085870312156154c1578182fd5b8435935060208501356154d381615f5a565b925060408501356154e381615f5a565b9150606085013567ffffffffffffffff8111156154fe578182fd5b61550a87828801615052565b91505092959194509250565b60008060408385031215615528578182fd5b82359150602083013567ffffffffffffffff81111561522d578182fd5b600080600060608486031215615559578081fd5b8335925060208085013567ffffffffffffffff80821115615578578384fd5b61558488838901614dc1565b94506040870135915080821115615599578384fd5b508501601f810187136155aa578283fd5b80356155b8614ddf82615f04565b81815283810190838501858402850186018b10156155d4578687fd5b8694505b838510156155ff5780356155eb81615f5a565b8352600194909401939185019185016155d8565b5080955050505050509250925092565b60008060408385031215615621578182fd5b8235915060208301356151a081615f5a565b600060208284031215615644578081fd5b81356001600160e01b0319811681146116f2578182fd5b60008060008060808587031215615670578182fd5b843561567b81615f5a565b9350602085013567ffffffffffffffff80821115615697578384fd5b6156a388838901614dc1565b945060408701359150808211156156b8578384fd5b6156c488838901614ef9565b935060608701359150808211156156d9578283fd5b5061550a87828801614fc0565b6000602082840312156156f7578081fd5b81356116f281615f7d565b60008060008060e08587031215615717578182fd5b6157218686615034565b9350602085013567ffffffffffffffff8082111561573d578384fd5b61574988838901614e38565b9450604087013591508082111561575e578384fd5b5061576b87828801614dc1565b92505061577b86606087016150f9565b905092959194509250565b600080600080600080610120878903121561579f578384fd5b6157a98888615034565b955060208088013567ffffffffffffffff808211156157c6578687fd5b6157d28b838c01614e38565b975060408a01359150808211156157e7578687fd5b6157f38b838c01614dc1565b96506158028b60608c016150f9565b955060e08a0135915080821115615817578485fd5b508801601f81018a13615828578384fd5b8035615836614ddf82615f04565b81815283810190838501858402850186018e1015615852578788fd5b8794505b83851015615874578035835260019490940193918501918501615856565b50809650505050505061010087013590509295509295509295565b60008060008060e085870312156158a4578182fd5b843567ffffffffffffffff808211156158bb578384fd5b9086019060c082890312156158ce578384fd5b6158d860c0615edd565b823581526158e98960208501615034565b602082015260408301356158fc81615f5a565b604082015261590e8960608501614db6565b60608201526080830135608082015260a08301358281111561592e578586fd5b61593a8a828601614fc0565b60a08301525080965050505061595386602087016150f9565b939693955050505060a08201359160c0013590565b600060208284031215615979578081fd5b5051919050565b6001600160a01b03169052565b6000815180845260208085019450808401835b838110156159c55781516001600160a01b0316875295820195908201906001016159a0565b509495945050505050565b6000815180845260208085019450808401835b838110156159c5578151875295820195908201906001016159e3565b60008151808452615a17816020860160208601615f24565b601f01601f19169290920160200192915050565b6000610120825160028110615a3c57fe5b808552506020830151615a526020860182615980565b506040830151615a656040860182615980565b50606083015160608501526080830151608085015260a083015160a085015260c0830151615a9660c0860182615980565b5060e0830151615aa960e0860182615980565b506101008084015182828701526112a6838701826159ff565b9182526001600160e01b031916602082015260240190565b6000828483379101908152919050565b60008251615afc818460208701615f24565b9190910192915050565b6bffffffffffffffffffffffff19606093841b811682529190921b16601482015260280190565b7f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b038316815260408101615bb483615f50565b8260208301529392505050565b6001600160a01b03929092168252602082015260400190565b6000602082526116f2602083018461598d565b600060408252615c00604083018561598d565b828103602084810191909152845180835285820192820190845b81811015615c3f5784516001600160a01b031683529383019391830191600101615c1a565b5090979650505050505050565b600060608252615c5f606083018661598d565b8281036020840152615c7181866159d0565b905082810360408401526112a681856159d0565b600060808252615c98608083018761598d565b8281036020840152615caa81876159d0565b90508281036040840152615cbe81866159d0565b90508281036060840152614c0881856159ff565b600060608252615ce5606083018661598d565b8281036020840152615cf781866159d0565b915050826040830152949350505050565b6000602082526116f260208301846159d0565b901515815260200190565b92151583526020830191909152604082015260600190565b90815260200190565b9283526001600160a01b03918216602084015216604082015260600190565b60008882526001600160a01b03808916602084015280881660408401525060e06060830152615d9860e08301876159d0565b8560808401528460a084015282810360c0840152615db681856159ff565b9a9950505050505050505050565b94855260208501939093526001600160a01b039190911660408401526060830152608082015260a00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b60208101615e4783615f50565b91905290565b918252602082015260400190565b600060808252615e6e6080830187615a2b565b8281036020840152615e8081876159d0565b604084019590955250506060015292915050565b600060608252615ea76060830186615a2b565b60208301949094525060400152919050565b938452602084019290925260408301526001600160a01b0316606082015260800190565b60405181810167ffffffffffffffff81118282101715615efc57600080fd5b604052919050565b600067ffffffffffffffff821115615f1a578081fd5b5060209081020190565b60005b83811015615f3f578181015183820152602001615f27565b83811115610e005750506000910152565b6003811061057e57fe5b6001600160a01b038116811461057e57600080fd5b801515811461057e57600080fd5b6003811061057e57600080fdfea2646970667358221220201e4f926e390fed8dd5318c58846af735c2bebc61b80693ae936a5fe76dcf1464736f6c6343000701003360c060405234801561001057600080fd5b50604051610be6380380610be683398101604081905261002f9161004d565b30608052600160005560601b6001600160601b03191660a05261007b565b60006020828403121561005e578081fd5b81516001600160a01b0381168114610074578182fd5b9392505050565b60805160a05160601c610b406100a66000398061041352806105495250806102a75250610b406000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063851c1bb311610076578063d877845c1161005b578063d877845c14610129578063e42abf3514610131578063fbfa77cf14610151576100a3565b8063851c1bb314610101578063aaabadc514610114576100a3565b806338e9922e146100a857806355c67628146100bd5780636b6b9f69146100db5780636daefab6146100ee575b600080fd5b6100bb6100b636600461099c565b610159565b005b6100c56101b8565b6040516100d29190610aa6565b60405180910390f35b6100bb6100e936600461099c565b6101be565b6100bb6100fc3660046107d1565b610211565b6100c561010f366004610924565b6102a3565b61011c6102f5565b6040516100d29190610a35565b6100c5610304565b61014461013f366004610852565b61030a565b6040516100d29190610a62565b61011c610411565b610161610435565b6101786706f05b59d3b2000082111561025861047e565b60018190556040517fa9ba3ffe0b6c366b81232caab38605a0699ad5398d6cce76f91ee809e322dafc906101ad908390610aa6565b60405180910390a150565b60015490565b6101c6610435565b6101dc662386f26fc1000082111561025961047e565b60028190556040517f5a0b7386237e7f07fa741efc64e59c9387d2cccafec760efed4d53387f20e19a906101ad908390610aa6565b610219610490565b610221610435565b61022b84836104a9565b60005b8481101561029357600086868381811061024457fe5b90506020020160208101906102599190610980565b9050600085858481811061026957fe5b6020029190910135915061028990506001600160a01b03831685836104b6565b505060010161022e565b5061029c61053e565b5050505050565b60007f0000000000000000000000000000000000000000000000000000000000000000826040516020016102d89291906109cc565b604051602081830303815290604052805190602001209050919050565b60006102ff610545565b905090565b60025490565b6060815167ffffffffffffffff8111801561032457600080fd5b5060405190808252806020026020018201604052801561034e578160200160208202803683370190505b50905060005b825181101561040b5782818151811061036957fe5b60200260200101516001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161039c9190610a35565b60206040518083038186803b1580156103b457600080fd5b505afa1580156103c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ec91906109b4565b8282815181106103f857fe5b6020908102919091010152600101610354565b50919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60006104646000357fffffffff00000000000000000000000000000000000000000000000000000000166102a3565b905061047b61047382336105d8565b61019161047e565b50565b8161048c5761048c8161066a565b5050565b6104a26002600054141561019061047e565b6002600055565b61048c818314606761047e565b6105398363a9059cbb60e01b84846040516024016104d5929190610a49565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526106d7565b505050565b6001600055565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663aaabadc56040518163ffffffff1660e01b815260040160206040518083038186803b1580156105a057600080fd5b505afa1580156105b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ff9190610964565b60006105e2610545565b6001600160a01b0316639be2a8848484306040518463ffffffff1660e01b815260040161061193929190610aaf565b60206040518083038186803b15801561062957600080fd5b505afa15801561063d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066191906108fd565b90505b92915050565b7f08c379a0000000000000000000000000000000000000000000000000000000006000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b60006060836001600160a01b0316836040516106f391906109fc565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150600082141561074d573d6000803e3d6000fd5b61077781516000148061076f57508180602001905181019061076f91906108fd565b6101a261047e565b50505050565b60008083601f84011261078e578182fd5b50813567ffffffffffffffff8111156107a5578182fd5b60208301915083602080830285010111156107bf57600080fd5b9250929050565b803561066481610af5565b6000806000806000606086880312156107e8578081fd5b853567ffffffffffffffff808211156107ff578283fd5b61080b89838a0161077d565b90975095506020880135915080821115610823578283fd5b506108308882890161077d565b909450925050604086013561084481610af5565b809150509295509295909350565b60006020808385031215610864578182fd5b823567ffffffffffffffff8082111561087b578384fd5b818501915085601f83011261088e578384fd5b81358181111561089c578485fd5b83810291506108ac848301610ace565b8181528481019084860184860187018a10156108c6578788fd5b8795505b838610156108f0576108dc8a826107c6565b8352600195909501949186019186016108ca565b5098975050505050505050565b60006020828403121561090e578081fd5b8151801515811461091d578182fd5b9392505050565b600060208284031215610935578081fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461091d578182fd5b600060208284031215610975578081fd5b815161091d81610af5565b600060208284031215610991578081fd5b813561091d81610af5565b6000602082840312156109ad578081fd5b5035919050565b6000602082840312156109c5578081fd5b5051919050565b9182527fffffffff0000000000000000000000000000000000000000000000000000000016602082015260240190565b60008251815b81811015610a1c5760208186018101518583015201610a02565b81811115610a2a5782828501525b509190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015610a9a57835183529284019291840191600101610a7e565b50909695505050505050565b90815260200190565b9283526001600160a01b03918216602084015216604082015260600190565b60405181810167ffffffffffffffff81118282101715610aed57600080fd5b604052919050565b6001600160a01b038116811461047b57600080fdfea2646970667358221220be72bdf8e7a3c38606c5f954fbe2d77798347aaa1cfb76fe77ec2f6c245d24bc64736f6c63430007010033", "deployedBytecode": "", "linkReferences": {}, "deployedLinkReferences": {} -} \ No newline at end of file +} From d977d4ad64af12906b077dce682d845a42c39725 Mon Sep 17 00:00:00 2001 From: ncitron Date: Sat, 11 Sep 2021 01:10:33 -0400 Subject: [PATCH 7/9] add balance v2 contract source --- external/abi/balancer/v2/BPoolV2.json | 8 -- .../contracts/balancer/{ => v1}/BFactory.sol | 0 .../contracts/balancer/{ => v1}/BPool.sol | 0 .../contracts/balancer/{ => v1}/BRegistry.sol | 0 .../balancer/{ => v1}/ExchangeProxy.sol | 0 external/contracts/balancer/v2/BVault.sol | 91 +++++++++++++++++++ .../balancer/v2/WeightedPoolFactory.sol | 60 ++++++++++++ 7 files changed, 151 insertions(+), 8 deletions(-) delete mode 100644 external/abi/balancer/v2/BPoolV2.json rename external/contracts/balancer/{ => v1}/BFactory.sol (100%) rename external/contracts/balancer/{ => v1}/BPool.sol (100%) rename external/contracts/balancer/{ => v1}/BRegistry.sol (100%) rename external/contracts/balancer/{ => v1}/ExchangeProxy.sol (100%) create mode 100644 external/contracts/balancer/v2/BVault.sol create mode 100644 external/contracts/balancer/v2/WeightedPoolFactory.sol diff --git a/external/abi/balancer/v2/BPoolV2.json b/external/abi/balancer/v2/BPoolV2.json deleted file mode 100644 index f049e9203..000000000 --- a/external/abi/balancer/v2/BPoolV2.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "contractName": "BPoolV2", - "abi":[{"inputs":[{"internalType":"contract IVault","name":"vault","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"normalizedWeights","type":"uint256[]"},{"internalType":"uint256","name":"swapFeePercentage","type":"uint256"},{"internalType":"uint256","name":"pauseWindowDuration","type":"uint256"},{"internalType":"uint256","name":"bufferPeriodDuration","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"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":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"PausedStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"swapFeePercentage","type":"uint256"}],"name":"SwapFeePercentageChanged","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":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","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":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"decreaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"getActionId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAuthorizer","outputs":[{"internalType":"contract IAuthorizer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInvariant","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastInvariant","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNormalizedWeights","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPausedState","outputs":[{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"uint256","name":"pauseWindowEndTime","type":"uint256"},{"internalType":"uint256","name":"bufferPeriodEndTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPoolId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSwapFeePercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVault","outputs":[{"internalType":"contract IVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"increaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"uint256","name":"protocolSwapFeePercentage","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"onExitPool","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"uint256","name":"protocolSwapFeePercentage","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"onJoinPool","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"enum IVault.SwapKind","name":"kind","type":"uint8"},{"internalType":"contract IERC20","name":"tokenIn","type":"address"},{"internalType":"contract IERC20","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"userData","type":"bytes"}],"internalType":"struct IPoolSwapStructs.SwapRequest","name":"request","type":"tuple"},{"internalType":"uint256","name":"balanceTokenIn","type":"uint256"},{"internalType":"uint256","name":"balanceTokenOut","type":"uint256"}],"name":"onSwap","outputs":[{"internalType":"uint256","name":"","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":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"uint256","name":"protocolSwapFeePercentage","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"queryExit","outputs":[{"internalType":"uint256","name":"bptIn","type":"uint256"},{"internalType":"uint256[]","name":"amountsOut","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"uint256","name":"protocolSwapFeePercentage","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"queryJoin","outputs":[{"internalType":"uint256","name":"bptOut","type":"uint256"},{"internalType":"uint256[]","name":"amountsIn","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"swapFeePercentage","type":"uint256"}],"name":"setSwapFeePercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}], - "bytecode": "6105006040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9610120523480156200003757600080fd5b50604051620058b6380380620058b68339810160408190526200005a9162000cf2565b88888888878787878785516002146200007557600162000078565b60025b6040805180820190915260018152603160f81b6020808301918252336080526001600160601b0319606087901b1660a0528b51908c0190812060c0529151902060e0527f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6101005289518a918a918a918a918a918a918a91849184918a918a9162000107916003919062000abb565b5080516200011d90600490602084019062000abb565b50620001359150506276a70083111561019462000865565b6200014962278d0082111561019562000865565b42909101610140819052016101605284516200016b906002111560c862000865565b6200018360088651111560c96200086560201b60201c565b62000199856200087a60201b62000d571760201c565b620001a48462000886565b6040516309b2760f60e01b81526000906001600160a01b038b16906309b2760f90620001d5908c9060040162000eab565b602060405180830381600087803b158015620001f057600080fd5b505af115801562000205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022b919062000cd9565b9050896001600160a01b03166366a9c7d2828889516001600160401b03811180156200025657600080fd5b5060405190808252806020026020018201604052801562000281578160200160208202803683370190505b506040518463ffffffff1660e01b8152600401620002a29392919062000e0f565b600060405180830381600087803b158015620002bd57600080fd5b505af1158015620002d2573d6000803e3d6000fd5b5050506001600160601b031960608c901b1661018052506101a081905285516101c0528551620003045760006200031b565b856000815181106200031257fe5b60200260200101515b60601b6001600160601b0319166101e05285516001106200033e57600062000355565b856001815181106200034c57fe5b60200260200101515b60601b6001600160601b031916610200528551600210620003785760006200038f565b856002815181106200038657fe5b60200260200101515b60601b6001600160601b031916610220528551600310620003b2576000620003c9565b85600381518110620003c057fe5b60200260200101515b60601b6001600160601b031916610240528551600410620003ec57600062000403565b85600481518110620003fa57fe5b60200260200101515b60601b6001600160601b031916610260528551600510620004265760006200043d565b856005815181106200043457fe5b60200260200101515b60601b6001600160601b0319166102805285516006106200046057600062000477565b856006815181106200046e57fe5b60200260200101515b60601b6001600160601b0319166102a05285516007106200049a576000620004b1565b85600781518110620004a857fe5b60200260200101515b60601b6001600160601b0319166102c0528551620004d1576000620004f7565b620004f786600081518110620004e357fe5b6020026020010151620008f560201b60201c565b6102e05285516001106200050d5760006200051f565b6200051f86600181518110620004e357fe5b6103005285516002106200053557600062000547565b6200054786600281518110620004e357fe5b6103205285516003106200055d5760006200056f565b6200056f86600381518110620004e357fe5b6103405285516004106200058557600062000597565b6200059786600481518110620004e357fe5b610360528551600510620005ad576000620005bf565b620005bf86600581518110620004e357fe5b610380528551600610620005d5576000620005e7565b620005e786600681518110620004e357fe5b6103a0528551600710620005fd5760006200060f565b6200060f86600781518110620004e357fe5b6103c08181525050505050505050505050505050505050505050600086519050620006478187516200099760201b62000d651760201c565b6000806000805b848160ff161015620006cd5760008a8260ff16815181106200066c57fe5b6020026020010151905062000694662386f26fc1000082101561012e6200086560201b60201c565b620006ae8186620009a660201b62000d721790919060201c565b945082811115620006c3578160ff1693508092505b506001016200064e565b50620006e6670de0b6b3a7640000841461013462000865565b6103e08290528851620006fb57600062000712565b886000815181106200070957fe5b60200260200101515b610400528851600110620007285760006200073f565b886001815181106200073657fe5b60200260200101515b610420528851600210620007555760006200076c565b886002815181106200076357fe5b60200260200101515b6104405288516003106200078257600062000799565b886003815181106200079057fe5b60200260200101515b610460528851600410620007af576000620007c6565b88600481518110620007bd57fe5b60200260200101515b610480528851600510620007dc576000620007f3565b88600581518110620007ea57fe5b60200260200101515b6104a05288516006106200080957600062000820565b886006815181106200081757fe5b60200260200101515b6104c0528851600710620008365760006200084d565b886007815181106200084457fe5b60200260200101515b6104e0525062000f329b505050505050505050505050565b8162000876576200087681620009c3565b5050565b80620008768162000a16565b6200089b64e8d4a5100082101560cb62000865565b620008b367016345785d8a000082111560ca62000865565b60078190556040517fa9ba3ffe0b6c366b81232caab38605a0699ad5398d6cce76f91ee809e322dafc90620008ea90839062000ec0565b60405180910390a150565b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156200093257600080fd5b505afa15801562000947573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200096d919062000dec565b60ff16905060006200098c60128362000aa360201b62000d841760201c565b600a0a949350505050565b62000876828214606762000865565b6000828201620009ba848210158362000865565b90505b92915050565b62461bcd60e51b6000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b60028151101562000a275762000aa0565b60008160008151811062000a3757fe5b602002602001015190506000600190505b825181101562000a9d57600083828151811062000a6157fe5b6020026020010151905062000a92816001600160a01b0316846001600160a01b03161060656200086560201b60201c565b915060010162000a48565b50505b50565b600062000ab583831115600162000865565b50900390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1062000afe57805160ff191683800117855562000b2e565b8280016001018555821562000b2e579182015b8281111562000b2e57825182559160200191906001019062000b11565b5062000b3c92915062000b40565b5090565b5b8082111562000b3c576000815560010162000b41565b8051620009bd8162000f1c565b600082601f83011262000b75578081fd5b815162000b8c62000b868262000ef0565b62000ec9565b81815291506020808301908481018184028601820187101562000bae57600080fd5b60005b8481101562000bda57815162000bc78162000f1c565b8452928201929082019060010162000bb1565b505050505092915050565b600082601f83011262000bf6578081fd5b815162000c0762000b868262000ef0565b81815291506020808301908481018184028601820187101562000c2957600080fd5b60005b8481101562000bda5781518452928201929082019060010162000c2c565b600082601f83011262000c5b578081fd5b81516001600160401b0381111562000c71578182fd5b602062000c87601f8301601f1916820162000ec9565b9250818352848183860101111562000c9e57600080fd5b60005b8281101562000cbe57848101820151848201830152810162000ca1565b8281111562000cd05760008284860101525b50505092915050565b60006020828403121562000ceb578081fd5b5051919050565b60008060008060008060008060006101208a8c03121562000d11578485fd5b62000d1d8b8b62000b57565b60208b01519099506001600160401b038082111562000d3a578687fd5b62000d488d838e0162000c4a565b995060408c015191508082111562000d5e578687fd5b62000d6c8d838e0162000c4a565b985060608c015191508082111562000d82578687fd5b62000d908d838e0162000b64565b975060808c015191508082111562000da6578687fd5b5062000db58c828d0162000be5565b95505060a08a0151935060c08a0151925060e08a0151915062000ddd8b6101008c0162000b57565b90509295985092959850929598565b60006020828403121562000dfe578081fd5b815160ff81168114620009ba578182fd5b60006060820185835260206060818501528186518084526080860191508288019350845b8181101562000e5b5762000e48855162000f10565b8352938301939183019160010162000e33565b505084810360408601528551808252908201925081860190845b8181101562000e9d5762000e8a835162000f10565b8552938301939183019160010162000e75565b509298975050505050505050565b602081016003831062000eba57fe5b91905290565b90815260200190565b6040518181016001600160401b038111828210171562000ee857600080fd5b604052919050565b60006001600160401b0382111562000f06578081fd5b5060209081020190565b6001600160a01b031690565b6001600160a01b038116811462000aa057600080fd5b60805160a05160601c60c05160e051610100516101205161014051610160516101805160601c6101a0516101c0516101e05160601c6102005160601c6102205160601c6102405160601c6102605160601c6102805160601c6102a05160601c6102c05160601c6102e05161030051610320516103405161036051610380516103a0516103c0516103e05161040051610420516104405161046051610480516104a0516104c0516104e05161476e6200114860003980611ec55280612857525080611e8252806127f6525080611e3f5280612795525080611dfc5280612734525080611db952806126d3525080611d765280612672525080611d335280612611525080611cf052806125b05250806122d0528061230452806123405250806116285280611b1e5250806115e55280611abd5250806115a25280611a5c52508061155f52806119fb52508061151c528061199a5250806114d9528061193952508061149652806118d85250806114455280611877525080611ae3528061281c525080611a8252806127bb525080611a21528061275a5250806119c052806126f952508061195f52806126985250806118fe528061263752508061189d52806125d652508061183c52806125755250806111025250806105d7525080610835525080610ef1525080610ecd525080610ab5525080610ff452508061103652508061101552508061081152508061079b525061476e6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80637ecebe001161010f578063a9059cbb116100a2578063d5c096c411610071578063d5c096c4146103e6578063d73dd623146103f9578063dd62ed3e1461040c578063f89f27ed1461041f576101f0565b8063a9059cbb146103b0578063aaabadc5146103c3578063c0ff1a15146103cb578063d505accf146103d3576101f0565b80638d928af8116100de5780638d928af81461038557806395d89b411461038d5780639b02cdde146103955780639d2c110c1461039d576101f0565b80637ecebe0014610337578063851c1bb31461034a57806387ec68171461035d578063893d20e814610370576101f0565b806338e9922e11610187578063661884631161015657806366188463146102e8578063679aefce146102fb57806370a082311461030357806374f3b00914610316576101f0565b806338e9922e146102a457806338fff2d0146102b757806355c67628146102bf5780636028bfd4146102c7576101f0565b80631c0de051116101c35780631c0de0511461025d57806323b872dd14610274578063313ce567146102875780633644e5151461029c576101f0565b806306fdde03146101f5578063095ea7b31461021357806316c38b3c1461023357806318160ddd14610248575b600080fd5b6101fd610434565b60405161020a9190614647565b60405180910390f35b61022661022136600461401c565b6104cb565b60405161020a919061457e565b610246610241366004614113565b6104e2565b005b6102506104f6565b60405161020a91906145a1565b6102656104fc565b60405161020a93929190614589565b610226610282366004613f67565b610525565b61028f6105a8565b60405161020a91906146b3565b6102506105ad565b6102466102b236600461449d565b6105bc565b6102506105d5565b6102506105f9565b6102da6102d536600461414b565b6105ff565b60405161020a92919061469a565b6102266102f636600461401c565b610636565b610250610690565b610250610311366004613f13565b6106bb565b61032961032436600461414b565b6106da565b60405161020a929190614559565b610250610345366004613f13565b61077c565b610250610358366004614248565b610797565b6102da61036b36600461414b565b6107e9565b61037861080f565b60405161020a9190614532565b610378610833565b6101fd610857565b6102506108b8565b6102506103ab3660046143a1565b6108be565b6102266103be36600461401c565b6109a5565b6103786109b2565b6102506109bc565b6102466103e1366004613fa7565b610a80565b6103296103f436600461414b565b610bc9565b61022661040736600461401c565b610cec565b61025061041a366004613f2f565b610d22565b610427610d4d565b60405161020a9190614546565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104c05780601f10610495576101008083540402835291602001916104c0565b820191906000526020600020905b8154815290600101906020018083116104a357829003601f168201915b505050505090505b90565b60006104d8338484610d9a565b5060015b92915050565b6104ea610e02565b6104f381610e30565b50565b60025490565b6000806000610509610eae565b159250610514610ecb565b915061051e610eef565b9050909192565b6001600160a01b0383166000818152600160209081526040808320338085529252822054919261056391148061055b5750838210155b610197610f13565b61056e858585610f21565b336001600160a01b0386161480159061058957506000198114155b1561059b5761059b8533858403610d9a565b60019150505b9392505050565b601290565b60006105b7610ff0565b905090565b6105c4610e02565b6105cc61108d565b6104f3816110a2565b7f000000000000000000000000000000000000000000000000000000000000000090565b60075490565b600060606106158651610610611100565b610d65565b61062a898989898989896111246111ec611252565b97509795505050505050565b3360009081526001602090815260408083206001600160a01b03861684529091528120548083106106725761066d33856000610d9a565b610686565b61068633856106818487610d84565b610d9a565b5060019392505050565b60006105b761069d6104f6565b6106b56106a86109bc565b6106b0611100565b611374565b90611398565b6001600160a01b0381166000908152602081905260409020545b919050565b606080886107046106e9610833565b6001600160a01b0316336001600160a01b03161460cd610f13565b61071961070f6105d5565b82146101f4610f13565b60606107236113e9565b905061072f8882611666565b60006060806107438e8e8e8e8e8e8e611124565b9250925092506107538d846116c7565b61075d82856111ec565b61076781856111ec565b909550935050505b5097509795505050505050565b6001600160a01b031660009081526005602052604090205490565b60007f0000000000000000000000000000000000000000000000000000000000000000826040516020016107cc9291906144ef565b604051602081830303815290604052805190602001209050919050565b600060606107fa8651610610611100565b61062a8989898989898961175a6117d7611252565b7f000000000000000000000000000000000000000000000000000000000000000090565b7f000000000000000000000000000000000000000000000000000000000000000090565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104c05780601f10610495576101008083540402835291602001916104c0565b60085490565b6000806108ce8560200151611838565b905060006108df8660400151611838565b90506000865160018111156108f057fe5b1415610956576109038660600151611b4d565b60608701526109128583611b71565b945061091e8482611b71565b935061092e866060015183611b71565b60608701526000610940878787611b7d565b905061094c8183611bb8565b93505050506105a1565b6109608583611b71565b945061096c8482611b71565b935061097c866060015182611b71565b6060870152600061098e878787611bc4565b905061099a8184611bf7565b905061094c81611c03565b60006104d8338484610f21565b60006105b7611c1a565b600060606109c8610833565b6001600160a01b031663f94d46686109de6105d5565b6040518263ffffffff1660e01b81526004016109fa91906145a1565b60006040518083038186803b158015610a1257600080fd5b505afa158015610a26573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a4e9190810190614047565b50915050610a6381610a5e6113e9565b611666565b6060610a6d611c94565b9050610a798183611ef1565b9250505090565b610a8e8442111560d1610f13565b6001600160a01b0387166000908152600560209081526040808320549051909291610ae5917f0000000000000000000000000000000000000000000000000000000000000000918c918c918c9188918d91016145c9565b6040516020818303038152906040528051906020012090506000610b0882611f63565b9050600060018288888860405160008152602001604052604051610b2f9493929190614629565b6020604051602081039080840390855afa158015610b51573d6000803e3d6000fd5b5050604051601f1901519150610b9390506001600160a01b03821615801590610b8b57508b6001600160a01b0316826001600160a01b0316145b6101f8610f13565b6001600160a01b038b166000908152600560205260409020600185019055610bbc8b8b8b610d9a565b5050505050505050505050565b60608088610bd86106e9610833565b610be361070f6105d5565b6060610bed6113e9565b9050610bf76104f6565b610c9d5760006060610c0b8d8d8d8a611f7f565b91509150610c20620f424083101560cc610f13565b610c2e6000620f424061201a565b610c3d8b620f4240840361201a565b610c4781846117d7565b80610c50611100565b67ffffffffffffffff81118015610c6657600080fd5b50604051908082528060200260200182016040528015610c90578160200160208202803683370190505b509550955050505061076f565b610ca78882611666565b6000606080610cbb8e8e8e8e8e8e8e61175a565b925092509250610ccb8c8461201a565b610cd582856117d7565b610cdf81856111ec565b909550935061076f915050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916104d89185906106819086610d72565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60606105b7611c94565b80610d61816120b0565b5050565b610d618183146067610f13565b60008282016105a18482101583610f13565b6000610d94838311156001610f13565b50900390565b6001600160a01b0380841660008181526001602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610df59085906145a1565b60405180910390a3505050565b6000610e196000356001600160e01b031916610797565b90506104f3610e288233612129565b610191610f13565b8015610e5057610e4b610e41610ecb565b4210610193610f13565b610e65565b610e65610e5b610eef565b42106101a9610f13565b6006805460ff19168215151790556040517f9e3a5e37224532dea67b89face185703738a228a6e8a23dee546960180d3be6490610ea390839061457e565b60405180910390a150565b6000610eb8610eef565b4211806105b757505060065460ff161590565b7f000000000000000000000000000000000000000000000000000000000000000090565b7f000000000000000000000000000000000000000000000000000000000000000090565b81610d6157610d6181612219565b6001600160a01b038316600090815260208190526040902054610f4982821015610196610f13565b610f606001600160a01b0384161515610199610f13565b6001600160a01b03808516600090815260208190526040808220858503905591851681522054610f909083610d72565b6001600160a01b0380851660008181526020819052604090819020939093559151908616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610fe29086906145a1565b60405180910390a350505050565b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061105d61226c565b306040516020016110729594939291906145fd565b60405160208183030381529060405280519060200120905090565b6110a0611098610eae565b610192610f13565b565b6110b564e8d4a5100082101560cb610f13565b6110cb67016345785d8a000082111560ca610f13565b60078190556040517fa9ba3ffe0b6c366b81232caab38605a0699ad5398d6cce76f91ee809e322dafc90610ea39083906145a1565b7f000000000000000000000000000000000000000000000000000000000000000090565b60006060806060611133611c94565b905061113d610eae565b1561117457600061114e828a611ef1565b905061115f8983600854848b612270565b925061116e8984610d84612380565b506111c0565b61117c611100565b67ffffffffffffffff8111801561119257600080fd5b506040519080825280602002602001820160405280156111bc578160200160208202803683370190505b5091505b6111cb8882876123eb565b90945092506111db888483612458565b600855509750975097945050505050565b60005b6111f7611100565b81101561124d5761122e83828151811061120d57fe5b602002602001015183838151811061122157fe5b6020026020010151612471565b83828151811061123a57fe5b60209081029190910101526001016111ef565b505050565b333014611310576000306001600160a01b0316600036604051611276929190614507565b6000604051808303816000865af19150503d80600081146112b3576040519150601f19603f3d011682016040523d82523d6000602084013e6112b8565b606091505b5050905080600081146112c757fe5b60046000803e6000516001600160e01b0319166343adbafb60e01b81146112f2573d6000803e3d6000fd5b506020600460003e604060205260243d03602460403e601c3d016000f35b606061131a6113e9565b90506113268782611666565b6000606061133d8c8c8c8c8c8c8c8c63ffffffff16565b509150915061135081848663ffffffff16565b8051601f1982018390526343adbafb603f1983015260200260231982016044820181fd5b60008282026105a184158061139157508385838161138e57fe5b04145b6003610f13565b60006113a78215156004610f13565b826113b4575060006104dc565b670de0b6b3a7640000838102906113d7908583816113ce57fe5b04146005610f13565b8281816113e057fe5b049150506104dc565b606060006113f5611100565b905060608167ffffffffffffffff8111801561141057600080fd5b5060405190808252806020026020018201604052801561143a578160200160208202803683370190505b5090508115611482577f00000000000000000000000000000000000000000000000000000000000000008160008151811061147157fe5b60200260200101818152505061148b565b91506104c89050565b6001821115611482577f0000000000000000000000000000000000000000000000000000000000000000816001815181106114c257fe5b6020026020010181815250506002821115611482577f00000000000000000000000000000000000000000000000000000000000000008160028151811061150557fe5b6020026020010181815250506003821115611482577f00000000000000000000000000000000000000000000000000000000000000008160038151811061154857fe5b6020026020010181815250506004821115611482577f00000000000000000000000000000000000000000000000000000000000000008160048151811061158b57fe5b6020026020010181815250506005821115611482577f0000000000000000000000000000000000000000000000000000000000000000816005815181106115ce57fe5b6020026020010181815250506006821115611482577f00000000000000000000000000000000000000000000000000000000000000008160068151811061161157fe5b6020026020010181815250506007821115611482577f00000000000000000000000000000000000000000000000000000000000000008160078151811061165457fe5b60200260200101818152505091505090565b60005b611671611100565b81101561124d576116a883828151811061168757fe5b602002602001015183838151811061169b57fe5b6020026020010151611374565b8382815181106116b457fe5b6020908102919091010152600101611669565b6001600160a01b0382166000908152602081905260409020546116ef82821015610196610f13565b6001600160a01b038316600090815260208190526040902082820390556002546117199083610d84565b6002556040516000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610df59086906145a1565b600060608061176761108d565b6060611771611c94565b9050600061177f828a611ef1565b905060606117928a84600854858c612270565b90506117a18a82610d84612380565b600060606117b08c868b612491565b915091506117bf8c82876124eb565b600855909e909d50909b509950505050505050505050565b60005b6117e2611100565b81101561124d576118198382815181106117f857fe5b602002602001015183838151811061180c57fe5b60200260200101516124fa565b83828151811061182557fe5b60209081029190910101526001016117da565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561189b57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156118fc57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561195d57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156119be57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611a1f57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611a8057507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611ae157507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611b4257507f00000000000000000000000000000000000000000000000000000000000000006106d5565b6106d5610135612219565b600080611b656007548461252d90919063ffffffff16565b90506105a18382610d84565b60006105a18383611374565b6000611b8761108d565b611bb083611b988660200151612571565b84611ba68860400151612571565b886060015161287b565b949350505050565b60006105a18383612471565b6000611bce61108d565b611bb083611bdf8660200151612571565b84611bed8860400151612571565b88606001516128f6565b60006105a183836124fa565b60006104dc611c1360075461296c565b8390612992565b6000611c24610833565b6001600160a01b031663aaabadc56040518163ffffffff1660e01b815260040160206040518083038186803b158015611c5c57600080fd5b505afa158015611c70573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b79190614270565b60606000611ca0611100565b905060608167ffffffffffffffff81118015611cbb57600080fd5b50604051908082528060200260200182016040528015611ce5578160200160208202803683370190505b5090508115611482577f000000000000000000000000000000000000000000000000000000000000000081600081518110611d1c57fe5b6020026020010181815250506001821115611482577f000000000000000000000000000000000000000000000000000000000000000081600181518110611d5f57fe5b6020026020010181815250506002821115611482577f000000000000000000000000000000000000000000000000000000000000000081600281518110611da257fe5b6020026020010181815250506003821115611482577f000000000000000000000000000000000000000000000000000000000000000081600381518110611de557fe5b6020026020010181815250506004821115611482577f000000000000000000000000000000000000000000000000000000000000000081600481518110611e2857fe5b6020026020010181815250506005821115611482577f000000000000000000000000000000000000000000000000000000000000000081600581518110611e6b57fe5b6020026020010181815250506006821115611482577f000000000000000000000000000000000000000000000000000000000000000081600681518110611eae57fe5b6020026020010181815250506007821115611482577f00000000000000000000000000000000000000000000000000000000000000008160078151811061165457fe5b670de0b6b3a764000060005b8351811015611f5357611f49611f42858381518110611f1857fe5b6020026020010151858481518110611f2c57fe5b60200260200101516129d490919063ffffffff16565b8390612a23565b9150600101611efd565b506104dc60008211610137610f13565b6000611f6d610ff0565b826040516020016107cc929190614517565b60006060611f8b61108d565b6000611f9684612a4f565b9050611fb16000826002811115611fa957fe5b1460ce610f13565b6060611fbc85612a65565b9050611fd0611fc9611100565b8251610d65565b611fdc81610a5e6113e9565b6060611fe6611c94565b90506000611ff48284611ef1565b90506000612004826106b0611100565b6008929092555099919850909650505050505050565b6001600160a01b03821660009081526020819052604090205461203d9082610d72565b6001600160a01b0383166000908152602081905260409020556002546120639082610d72565b6002556040516001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906120a49085906145a1565b60405180910390a35050565b6002815110156120bf576104f3565b6000816000815181106120ce57fe5b602002602001015190506000600190505b825181101561124d5760008382815181106120f657fe5b6020026020010151905061211f816001600160a01b0316846001600160a01b0316106065610f13565b91506001016120df565b600073ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1b61214861080f565b6001600160a01b031614158015612163575061216383612a7b565b1561218b5761217061080f565b6001600160a01b0316336001600160a01b03161490506104dc565b612193611c1a565b6001600160a01b0316639be2a8848484306040518463ffffffff1660e01b81526004016121c2939291906145aa565b60206040518083038186803b1580156121da57600080fd5b505afa1580156121ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612212919061412f565b90506104dc565b62461bcd60e51b6000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b4690565b60608061227b611100565b67ffffffffffffffff8111801561229157600080fd5b506040519080825280602002602001820160405280156122bb578160200160208202803683370190505b509050826122ca579050612377565b61233d877f0000000000000000000000000000000000000000000000000000000000000000815181106122f957fe5b6020026020010151877f00000000000000000000000000000000000000000000000000000000000000008151811061232d57fe5b6020026020010151878787612a95565b817f00000000000000000000000000000000000000000000000000000000000000008151811061236957fe5b602090810291909101015290505b95945050505050565b60005b61238b611100565b8110156123e5576123c68482815181106123a157fe5b60200260200101518483815181106123b557fe5b60200260200101518463ffffffff16565b8482815181106123d257fe5b6020908102919091010152600101612383565b50505050565b6000606060006123fa84612a4f565b9050600081600281111561240a57fe5b14156124255761241b868686612b0d565b9250925050612450565b600181600281111561243357fe5b14156124435761241b8685612beb565b61241b868686612c1d565b505b935093915050565b60006124678484610d84612380565b611bb08285611ef1565b60006124808215156004610f13565b81838161248957fe5b049392505050565b6000606060006124a084612a4f565b905060018160028111156124b057fe5b14156124c15761241b868686612c88565b60028160028111156124cf57fe5b14156124e05761241b868686612ce2565b61244e610136612219565b60006124678484610d72612380565b60006125098215156004610f13565b82612516575060006104dc565b81600184038161252257fe5b0460010190506104dc565b600082820261254784158061139157508385838161138e57fe5b806125565760009150506104dc565b670de0b6b3a764000060001982015b046001019150506104dc565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156125d457507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561263557507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561269657507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156126f757507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561275857507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156127b957507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561281a57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611b4257507f00000000000000000000000000000000000000000000000000000000000000006106d5565b600061289d61289287670429d069189e0000612a23565b831115610130610f13565b60006128a98784610d72565b905060006128b78883612992565b905060006128c58887611398565b905060006128d38383612d8a565b90506128e86128e18261296c565b8990612a23565b9a9950505050505050505050565b600061291861290d85670429d069189e0000612a23565b831115610131610f13565b600061292e6129278685610d84565b8690612992565b9050600061293c8588612992565b9050600061294a8383612d8a565b9050600061296082670de0b6b3a7640000610d84565b90506128e88a8261252d565b6000670de0b6b3a764000082106129845760006104dc565b50670de0b6b3a76400000390565b60006129a18215156004610f13565b826129ae575060006104dc565b670de0b6b3a7640000838102906129c8908583816113ce57fe5b82600182038161256557fe5b6000806129e18484612db6565b905060006129fb6129f48361271061252d565b6001610d72565b905080821015612a10576000925050506104dc565b612a1a8282610d84565b925050506104dc565b6000828202612a3d84158061139157508385838161138e57fe5b670de0b6b3a764000090049392505050565b6000818060200190518101906104dc919061428c565b6060818060200190518101906105a19190614352565b6000612a8d631c74c91760e11b610797565b909114919050565b6000838311612aa657506000612377565b6000612ab28585612992565b90506000612ac8670de0b6b3a764000088611398565b9050612adc826709b6e64a8ec60000612ec1565b91506000612aea8383612d8a565b90506000612b01612afa8361296c565b8b90612a23565b90506128e88187612a23565b60006060612b1961108d565b600080612b2585612ed8565b91509150612b3d612b34611100565b82106064610f13565b6060612b47611100565b67ffffffffffffffff81118015612b5d57600080fd5b50604051908082528060200260200182016040528015612b87578160200160208202803683370190505b509050612bc6888381518110612b9957fe5b6020026020010151888481518110612bad57fe5b602002602001015185612bbe6104f6565b600754612efa565b818381518110612bd257fe5b6020908102919091010152919791965090945050505050565b600060606000612bfa84612fb7565b90506060612c108683612c0b6104f6565b612fcd565b9196919550909350505050565b60006060612c2961108d565b60606000612c368561307f565b91509150612c478251610610611100565b612c5382610a5e6113e9565b6000612c6b888885612c636104f6565b600754613097565b9050612c7b8282111560cf610f13565b9791965090945050505050565b60006060806000612c988561307f565b91509150612cae612ca7611100565b8351610d65565b612cba82610a5e6113e9565b6000612cd2888885612cca6104f6565b6007546132bc565b9050612c7b8282101560d0610f13565b60006060600080612cf285612ed8565b91509150612d01612b34611100565b6060612d0b611100565b67ffffffffffffffff81118015612d2157600080fd5b50604051908082528060200260200182016040528015612d4b578160200160208202803683370190505b509050612bc6888381518110612d5d57fe5b6020026020010151888481518110612d7157fe5b602002602001015185612d826104f6565b6007546134cd565b600080612d978484612db6565b90506000612daa6129f48361271061252d565b90506123778282610d72565b600081612dcc5750670de0b6b3a76400006104dc565b82612dd9575060006104dc565b612dea600160ff1b84106006610f13565b82612e10770bce5086492111aea88f4bb1ca6bcf584181ea8059f7653284106007610f13565b826000670c7d713b49da000083138015612e315750670f43fc2c04ee000083125b15612e68576000612e418461356f565b9050670de0b6b3a764000080820784020583670de0b6b3a764000083050201915050612e76565b81612e7284613696565b0290505b670de0b6b3a76400009005612eae680238fd42c5cf03ffff198212801590612ea7575068070c1cc73b00c800008213155b6008610f13565b612eb781613a44565b9695505050505050565b600081831015612ed157816105a1565b5090919050565b60008082806020019051810190612eef919061431c565b909590945092505050565b600080612f1184612f0b8188610d84565b90612992565b9050612f2a6709b6e64a8ec60000821015610132610f13565b6000612f48612f41670de0b6b3a764000089611398565b8390612d8a565b90506000612f5f612f588361296c565b8a90612a23565b90506000612f6c8961296c565b90506000612f7a838361252d565b90506000612f888483610d84565b9050612fa7612fa0612f998a61296c565b8490612a23565b8290610d72565b9c9b505050505050505050505050565b6000818060200190518101906105a191906142ef565b60606000612fdb8484611398565b90506060855167ffffffffffffffff81118015612ff757600080fd5b50604051908082528060200260200182016040528015613021578160200160208202803683370190505b50905060005b8651811015613075576130568388838151811061304057fe5b6020026020010151612a2390919063ffffffff16565b82828151811061306257fe5b6020908102919091010152600101613027565b5095945050505050565b6060600082806020019051810190612eef91906142a8565b60006060845167ffffffffffffffff811180156130b357600080fd5b506040519080825280602002602001820160405280156130dd578160200160208202803683370190505b5090506000805b88518110156131a25761313d8982815181106130fc57fe5b6020026020010151612f0b89848151811061311357fe5b60200260200101518c858151811061312757fe5b6020026020010151610d8490919063ffffffff16565b83828151811061314957fe5b60200260200101818152505061319861319189838151811061316757fe5b602002602001015185848151811061317b57fe5b602002602001015161252d90919063ffffffff16565b8390610d72565b91506001016130e4565b50670de0b6b3a764000060005b895181101561329b5760008482815181106131c657fe5b602002602001015184111561321d5760006131ef6131e38661296c565b8d858151811061304057fe5b90506000613203828c868151811061312757fe5b9050613214613191611c138b61296c565b92505050613234565b88828151811061322957fe5b602002602001015190505b600061325d8c848151811061324557fe5b60200260200101516106b5848f878151811061312757fe5b905061328f6132888c858151811061327157fe5b6020026020010151836129d490919063ffffffff16565b8590612a23565b935050506001016131af565b506132af6132a88261296c565b879061252d565b9998505050505050505050565b60006060845167ffffffffffffffff811180156132d857600080fd5b50604051908082528060200260200182016040528015613302578160200160208202803683370190505b5090506000805b88518110156133aa5761336289828151811061332157fe5b60200260200101516106b589848151811061333857fe5b60200260200101518c858151811061334c57fe5b6020026020010151610d7290919063ffffffff16565b83828151811061336e57fe5b6020026020010181815250506133a061319189838151811061338c57fe5b602002602001015185848151811061304057fe5b9150600101613309565b50670de0b6b3a764000060005b895181101561348b576000838583815181106133cf57fe5b6020026020010151111561342b5760006133f46131e386670de0b6b3a7640000610d84565b90506000613408828c868151811061312757fe5b9050613422613191611f42670de0b6b3a76400008c610d84565b92505050613442565b88828151811061343757fe5b602002602001015190505b600061346b8c848151811061345357fe5b60200260200101516106b5848f878151811061334c57fe5b905061347f6132888c858151811061327157fe5b935050506001016133b7565b50670de0b6b3a764000081106134c1576134b76134b082670de0b6b3a7640000610d84565b8790612a23565b9350505050612377565b60009350505050612377565b6000806134de84612f0b8188610d72565b90506134f76729a2241af62c0000821115610133610f13565b600061350e612f41670de0b6b3a764000089612992565b9050600061352e61352783670de0b6b3a7640000610d84565b8a9061252d565b9050600061353b8961296c565b90506000613549838361252d565b905060006135578483610d84565b9050612fa7612fa06135688a61296c565b8490612992565b670de0b6b3a7640000026000806ec097ce7bc90715b34b9f1000000000808401906ec097ce7bc90715b34b9f0fffffffff19850102816135ab57fe5b05905060006ec097ce7bc90715b34b9f100000000082800205905081806ec097ce7bc90715b34b9f100000000081840205915060038205016ec097ce7bc90715b34b9f100000000082840205915060058205016ec097ce7bc90715b34b9f100000000082840205915060078205016ec097ce7bc90715b34b9f100000000082840205915060098205016ec097ce7bc90715b34b9f1000000000828402059150600b8205016ec097ce7bc90715b34b9f1000000000828402059150600d8205016ec097ce7bc90715b34b9f1000000000828402059150600f826002919005919091010295945050505050565b60006136a6600083136064610f13565b670de0b6b3a76400008212156136e1576136d7826ec097ce7bc90715b34b9f1000000000816136d157fe5b05613696565b60000390506106d5565b60007e1600ef3172e58d2e933ec884fde10064c63b5372d805e203c0000000000000831261373257770195e54c5dd42177f53a27172fa9ec630262827000000000830592506806f05b59d3b2000000015b73011798004d755d3c8bc8e03204cf44619e000000831261376a576b1425982cf597cd205cef7380830592506803782dace9d9000000015b606492830292026e01855144814a7ff805980ff008400083126137b2576e01855144814a7ff805980ff008400068056bc75e2d63100000840205925068ad78ebc5ac62000000015b6b02df0ab5a80a22c61ab5a70083126137ed576b02df0ab5a80a22c61ab5a70068056bc75e2d6310000084020592506856bc75e2d631000000015b693f1fce3da636ea5cf850831261382457693f1fce3da636ea5cf85068056bc75e2d631000008402059250682b5e3af16b18800000015b690127fa27722cc06cc5e2831261385b57690127fa27722cc06cc5e268056bc75e2d6310000084020592506815af1d78b58c400000015b68280e60114edb805d0383126138905768280e60114edb805d0368056bc75e2d631000008402059250680ad78ebc5ac6200000015b680ebc5fb4174612111083126138bb57680ebc5fb4174612111068056bc75e2d631000009384020592015b6808f00f760a4b2db55d83126138f0576808f00f760a4b2db55d68056bc75e2d6310000084020592506802b5e3af16b1880000015b6806f5f17757889379378312613925576806f5f177578893793768056bc75e2d63100000840205925068015af1d78b58c40000015b6806248f33704b2866038312613959576806248f33704b28660368056bc75e2d63100000840205925067ad78ebc5ac620000015b6805c548670b9510e7ac831261398d576805c548670b9510e7ac68056bc75e2d6310000084020592506756bc75e2d6310000015b600068056bc75e2d63100000840168056bc75e2d6310000080860302816139b057fe5b059050600068056bc75e2d63100000828002059050818068056bc75e2d63100000818402059150600382050168056bc75e2d63100000828402059150600582050168056bc75e2d63100000828402059150600782050168056bc75e2d63100000828402059150600982050168056bc75e2d63100000828402059150600b820501600202606485820105979650505050505050565b6000613a73680238fd42c5cf03ffff198312158015613a6c575068070c1cc73b00c800008313155b6009610f13565b6000821215613aa757613a8882600003613a44565b6ec097ce7bc90715b34b9f100000000081613a9f57fe5b0590506106d5565b60006806f05b59d3b20000008312613ae757506806f05b59d3b1ffffff1990910190770195e54c5dd42177f53a27172fa9ec630262827000000000613b1d565b6803782dace9d90000008312613b1957506803782dace9d8ffffff19909101906b1425982cf597cd205cef7380613b1d565b5060015b6064929092029168056bc75e2d6310000068ad78ebc5ac620000008412613b6d5768ad78ebc5ac61ffffff199093019268056bc75e2d631000006e01855144814a7ff805980ff008400082020590505b6856bc75e2d6310000008412613ba9576856bc75e2d630ffffff199093019268056bc75e2d631000006b02df0ab5a80a22c61ab5a70082020590505b682b5e3af16b188000008412613be357682b5e3af16b187fffff199093019268056bc75e2d63100000693f1fce3da636ea5cf85082020590505b6815af1d78b58c4000008412613c1d576815af1d78b58c3fffff199093019268056bc75e2d63100000690127fa27722cc06cc5e282020590505b680ad78ebc5ac62000008412613c5657680ad78ebc5ac61fffff199093019268056bc75e2d6310000068280e60114edb805d0382020590505b68056bc75e2d631000008412613c8f5768056bc75e2d630fffff199093019268056bc75e2d63100000680ebc5fb4174612111082020590505b6802b5e3af16b18800008412613cc8576802b5e3af16b187ffff199093019268056bc75e2d631000006808f00f760a4b2db55d82020590505b68015af1d78b58c400008412613d015768015af1d78b58c3ffff199093019268056bc75e2d631000006806f5f177578893793782020590505b68056bc75e2d631000008481019085906002908280020505918201919050600368056bc75e2d631000008783020505918201919050600468056bc75e2d631000008783020505918201919050600568056bc75e2d631000008783020505918201919050600668056bc75e2d631000008783020505918201919050600768056bc75e2d631000008783020505918201919050600868056bc75e2d631000008783020505918201919050600968056bc75e2d631000008783020505918201919050600a68056bc75e2d631000008783020505918201919050600b68056bc75e2d631000008783020505918201919050600c68056bc75e2d631000008783020505918201919050606468056bc75e2d63100000848402058502059695505050505050565b80356104dc81614708565b600082601f830112613e3d578081fd5b8151613e50613e4b826146e8565b6146c1565b818152915060208083019084810181840286018201871015613e7157600080fd5b60005b84811015613e9057815184529282019290820190600101613e74565b505050505092915050565b600082601f830112613eab578081fd5b813567ffffffffffffffff811115613ec1578182fd5b613ed4601f8201601f19166020016146c1565b9150808252836020828501011115613eeb57600080fd5b8060208401602084013760009082016020015292915050565b8035600281106104dc57600080fd5b600060208284031215613f24578081fd5b81356105a181614708565b60008060408385031215613f41578081fd5b8235613f4c81614708565b91506020830135613f5c81614708565b809150509250929050565b600080600060608486031215613f7b578081fd5b8335613f8681614708565b92506020840135613f9681614708565b929592945050506040919091013590565b600080600080600080600060e0888a031215613fc1578283fd5b8735613fcc81614708565b96506020880135613fdc81614708565b95506040880135945060608801359350608088013560ff81168114613fff578384fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561402e578182fd5b823561403981614708565b946020939093013593505050565b60008060006060848603121561405b578081fd5b835167ffffffffffffffff80821115614072578283fd5b818601915086601f830112614085578283fd5b8151614093613e4b826146e8565b80828252602080830192508086018b8283870289010111156140b3578788fd5b8796505b848710156140de5780516140ca81614708565b8452600196909601959281019281016140b7565b5089015190975093505050808211156140f5578283fd5b5061410286828701613e2d565b925050604084015190509250925092565b600060208284031215614124578081fd5b81356105a18161471d565b600060208284031215614140578081fd5b81516105a18161471d565b600080600080600080600060e0888a031215614165578081fd5b8735965060208089013561417881614708565b9650604089013561418881614708565b9550606089013567ffffffffffffffff808211156141a4578384fd5b818b0191508b601f8301126141b7578384fd5b81356141c5613e4b826146e8565b8082825285820191508585018f8788860288010111156141e3578788fd5b8795505b838610156142055780358352600195909501949186019186016141e7565b509850505060808b0135955060a08b0135945060c08b013592508083111561422b578384fd5b50506142398a828b01613e9b565b91505092959891949750929550565b600060208284031215614259578081fd5b81356001600160e01b0319811681146105a1578182fd5b600060208284031215614281578081fd5b81516105a181614708565b60006020828403121561429d578081fd5b81516105a18161472b565b6000806000606084860312156142bc578081fd5b83516142c78161472b565b602085015190935067ffffffffffffffff8111156142e3578182fd5b61410286828701613e2d565b60008060408385031215614301578182fd5b825161430c8161472b565b6020939093015192949293505050565b600080600060608486031215614330578081fd5b835161433b8161472b565b602085015160409095015190969495509392505050565b60008060408385031215614364578182fd5b825161436f8161472b565b602084015190925067ffffffffffffffff81111561438b578182fd5b61439785828601613e2d565b9150509250929050565b6000806000606084860312156143b5578081fd5b833567ffffffffffffffff808211156143cc578283fd5b81860191506101208083890312156143e2578384fd5b6143eb816146c1565b90506143f78884613f04565b81526144068860208501613e22565b60208201526144188860408501613e22565b6040820152606083013560608201526080830135608082015260a083013560a08201526144488860c08501613e22565b60c082015261445a8860e08501613e22565b60e08201526101008084013583811115614472578586fd5b61447e8a828701613e9b565b9183019190915250976020870135975060409096013595945050505050565b6000602082840312156144ae578081fd5b5035919050565b6000815180845260208085019450808401835b838110156144e4578151875295820195908201906001016144c8565b509495945050505050565b9182526001600160e01b031916602082015260240190565b6000828483379101908152919050565b61190160f01b81526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6000602082526105a160208301846144b5565b60006040825261456c60408301856144b5565b828103602084015261237781856144b5565b901515815260200190565b92151583526020830191909152604082015260600190565b90815260200190565b9283526001600160a01b03918216602084015216604082015260600190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b6000602080835283518082850152825b8181101561467357858101830151858201604001528201614657565b818111156146845783604083870101525b50601f01601f1916929092016040019392505050565b600083825260406020830152611bb060408301846144b5565b60ff91909116815260200190565b60405181810167ffffffffffffffff811182821017156146e057600080fd5b604052919050565b600067ffffffffffffffff8211156146fe578081fd5b5060209081020190565b6001600160a01b03811681146104f357600080fd5b80151581146104f357600080fd5b600381106104f357600080fdfea2646970667358221220a2c3b62e0bc50507598395387e1557612d7ad59e817ddae4d5279907402fedb464736f6c63430007010033", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/external/contracts/balancer/BFactory.sol b/external/contracts/balancer/v1/BFactory.sol similarity index 100% rename from external/contracts/balancer/BFactory.sol rename to external/contracts/balancer/v1/BFactory.sol diff --git a/external/contracts/balancer/BPool.sol b/external/contracts/balancer/v1/BPool.sol similarity index 100% rename from external/contracts/balancer/BPool.sol rename to external/contracts/balancer/v1/BPool.sol diff --git a/external/contracts/balancer/BRegistry.sol b/external/contracts/balancer/v1/BRegistry.sol similarity index 100% rename from external/contracts/balancer/BRegistry.sol rename to external/contracts/balancer/v1/BRegistry.sol diff --git a/external/contracts/balancer/ExchangeProxy.sol b/external/contracts/balancer/v1/ExchangeProxy.sol similarity index 100% rename from external/contracts/balancer/ExchangeProxy.sol rename to external/contracts/balancer/v1/ExchangeProxy.sol diff --git a/external/contracts/balancer/v2/BVault.sol b/external/contracts/balancer/v2/BVault.sol new file mode 100644 index 000000000..27595f3f8 --- /dev/null +++ b/external/contracts/balancer/v2/BVault.sol @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +import "@balancer-labs/v2-solidity-utils/contracts/misc/IWETH.sol"; + +import "./interfaces/IAuthorizer.sol"; + +import "./VaultAuthorization.sol"; +import "./FlashLoans.sol"; +import "./Swaps.sol"; + +/** + * @dev The `Vault` is Balancer V2's core contract. A single instance of it exists for the entire network, and it is the + * entity used to interact with Pools by Liquidity Providers who join and exit them, Traders who swap, and Asset + * Managers who withdraw and deposit tokens. + * + * The `Vault`'s source code is split among a number of sub-contracts, with the goal of improving readability and making + * understanding the system easier. Most sub-contracts have been marked as `abstract` to explicitly indicate that only + * the full `Vault` is meant to be deployed. + * + * Roughly speaking, these are the contents of each sub-contract: + * + * - `AssetManagers`: Pool token Asset Manager registry, and Asset Manager interactions. + * - `Fees`: set and compute protocol fees. + * - `FlashLoans`: flash loan transfers and fees. + * - `PoolBalances`: Pool joins and exits. + * - `PoolRegistry`: Pool registration, ID management, and basic queries. + * - `PoolTokens`: Pool token registration and registration, and balance queries. + * - `Swaps`: Pool swaps. + * - `UserBalance`: manage user balances (Internal Balance operations and external balance transfers) + * - `VaultAuthorization`: access control, relayers and signature validation. + * + * Additionally, the different Pool specializations are handled by the `GeneralPoolsBalance`, + * `MinimalSwapInfoPoolsBalance` and `TwoTokenPoolsBalance` sub-contracts, which in turn make use of the + * `BalanceAllocation` library. + * + * The most important goal of the `Vault` is to make token swaps use as little gas as possible. This is reflected in a + * multitude of design decisions, from minor things like the format used to store Pool IDs, to major features such as + * the different Pool specialization settings. + * + * Finally, the large number of tasks carried out by the Vault means its bytecode is very large, close to exceeding + * the contract size limit imposed by EIP 170 (https://eips.ethereum.org/EIPS/eip-170). Manual tuning of the source code + * was required to improve code generation and bring the bytecode size below this limit. This includes extensive + * utilization of `internal` functions (particularly inside modifiers), usage of named return arguments, dedicated + * storage access methods, dynamic revert reason generation, and usage of inline assembly, to name a few. + */ +contract Vault is VaultAuthorization, FlashLoans, Swaps { + constructor( + IAuthorizer authorizer, + IWETH weth, + uint256 pauseWindowDuration, + uint256 bufferPeriodDuration + ) VaultAuthorization(authorizer) AssetHelpers(weth) TemporarilyPausable(pauseWindowDuration, bufferPeriodDuration) { + // solhint-disable-previous-line no-empty-blocks + } + + function setPaused(bool paused) external override nonReentrant authenticate { + _setPaused(paused); + } + + // solhint-disable-next-line func-name-mixedcase + function WETH() external view override returns (IWETH) { + return _WETH(); + } +} +© 2021 GitHub, Inc. +Terms +Privacy +Security +Status +Docs +Contact GitHub +Pricing +API +Training +Blog +About diff --git a/external/contracts/balancer/v2/WeightedPoolFactory.sol b/external/contracts/balancer/v2/WeightedPoolFactory.sol new file mode 100644 index 000000000..fd924db35 --- /dev/null +++ b/external/contracts/balancer/v2/WeightedPoolFactory.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +import "@balancer-labs/v2-vault/contracts/interfaces/IVault.sol"; + +import "@balancer-labs/v2-pool-utils/contracts/factories/BasePoolSplitCodeFactory.sol"; +import "@balancer-labs/v2-pool-utils/contracts/factories/FactoryWidePauseWindow.sol"; + +import "./WeightedPool.sol"; + +contract WeightedPoolFactory is BasePoolSplitCodeFactory, FactoryWidePauseWindow { + constructor(IVault vault) BasePoolSplitCodeFactory(vault, type(WeightedPool).creationCode) { + // solhint-disable-previous-line no-empty-blocks + } + + /** + * @dev Deploys a new `WeightedPool`. + */ + function create( + string memory name, + string memory symbol, + IERC20[] memory tokens, + uint256[] memory weights, + address[] memory assetManagers, + uint256 swapFeePercentage, + address owner + ) external returns (address) { + (uint256 pauseWindowDuration, uint256 bufferPeriodDuration) = getPauseConfiguration(); + + return + _create( + abi.encode( + getVault(), + name, + symbol, + tokens, + weights, + assetManagers, + swapFeePercentage, + pauseWindowDuration, + bufferPeriodDuration, + owner + ) + ); + } +} \ No newline at end of file From b56aa963c7c68c08451420fee8d7b8c18422a117 Mon Sep 17 00:00:00 2001 From: ncitron Date: Sat, 11 Sep 2021 01:25:36 -0400 Subject: [PATCH 8/9] add BPoolV2 source and bytecode --- external/abi/balancer/v2/BPoolV2.json | 9 + external/contracts/balancer/v2/BPoolV2.sol | 705 +++++++++++++++++++++ 2 files changed, 714 insertions(+) create mode 100644 external/abi/balancer/v2/BPoolV2.json create mode 100644 external/contracts/balancer/v2/BPoolV2.sol diff --git a/external/abi/balancer/v2/BPoolV2.json b/external/abi/balancer/v2/BPoolV2.json new file mode 100644 index 000000000..f622a68ee --- /dev/null +++ b/external/abi/balancer/v2/BPoolV2.json @@ -0,0 +1,9 @@ +{ + "contractName": "BPoolV2", + "abi":[{"inputs":[{"internalType":"contract IVault","name":"vault","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"contract IERC20[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"normalizedWeights","type":"uint256[]"},{"internalType":"uint256","name":"swapFeePercentage","type":"uint256"},{"internalType":"uint256","name":"pauseWindowDuration","type":"uint256"},{"internalType":"uint256","name":"bufferPeriodDuration","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"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":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"PausedStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"swapFeePercentage","type":"uint256"}],"name":"SwapFeePercentageChanged","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":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","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":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"decreaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"getActionId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAuthorizer","outputs":[{"internalType":"contract IAuthorizer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInvariant","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastInvariant","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNormalizedWeights","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPausedState","outputs":[{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"uint256","name":"pauseWindowEndTime","type":"uint256"},{"internalType":"uint256","name":"bufferPeriodEndTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPoolId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSwapFeePercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVault","outputs":[{"internalType":"contract IVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"increaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"uint256","name":"protocolSwapFeePercentage","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"onExitPool","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"uint256","name":"protocolSwapFeePercentage","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"onJoinPool","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"enum IVault.SwapKind","name":"kind","type":"uint8"},{"internalType":"contract IERC20","name":"tokenIn","type":"address"},{"internalType":"contract IERC20","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"userData","type":"bytes"}],"internalType":"struct IPoolSwapStructs.SwapRequest","name":"request","type":"tuple"},{"internalType":"uint256","name":"balanceTokenIn","type":"uint256"},{"internalType":"uint256","name":"balanceTokenOut","type":"uint256"}],"name":"onSwap","outputs":[{"internalType":"uint256","name":"","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":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"uint256","name":"protocolSwapFeePercentage","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"queryExit","outputs":[{"internalType":"uint256","name":"bptIn","type":"uint256"},{"internalType":"uint256[]","name":"amountsOut","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"},{"internalType":"uint256","name":"lastChangeBlock","type":"uint256"},{"internalType":"uint256","name":"protocolSwapFeePercentage","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"queryJoin","outputs":[{"internalType":"uint256","name":"bptOut","type":"uint256"},{"internalType":"uint256[]","name":"amountsIn","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"swapFeePercentage","type":"uint256"}],"name":"setSwapFeePercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}], + "bytecode": "6105006040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9610120523480156200003757600080fd5b50604051620058b6380380620058b68339810160408190526200005a9162000cf2565b88888888878787878785516002146200007557600162000078565b60025b6040805180820190915260018152603160f81b6020808301918252336080526001600160601b0319606087901b1660a0528b51908c0190812060c0529151902060e0527f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6101005289518a918a918a918a918a918a918a91849184918a918a9162000107916003919062000abb565b5080516200011d90600490602084019062000abb565b50620001359150506276a70083111561019462000865565b6200014962278d0082111561019562000865565b42909101610140819052016101605284516200016b906002111560c862000865565b6200018360088651111560c96200086560201b60201c565b62000199856200087a60201b62000d571760201c565b620001a48462000886565b6040516309b2760f60e01b81526000906001600160a01b038b16906309b2760f90620001d5908c9060040162000eab565b602060405180830381600087803b158015620001f057600080fd5b505af115801562000205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022b919062000cd9565b9050896001600160a01b03166366a9c7d2828889516001600160401b03811180156200025657600080fd5b5060405190808252806020026020018201604052801562000281578160200160208202803683370190505b506040518463ffffffff1660e01b8152600401620002a29392919062000e0f565b600060405180830381600087803b158015620002bd57600080fd5b505af1158015620002d2573d6000803e3d6000fd5b5050506001600160601b031960608c901b1661018052506101a081905285516101c0528551620003045760006200031b565b856000815181106200031257fe5b60200260200101515b60601b6001600160601b0319166101e05285516001106200033e57600062000355565b856001815181106200034c57fe5b60200260200101515b60601b6001600160601b031916610200528551600210620003785760006200038f565b856002815181106200038657fe5b60200260200101515b60601b6001600160601b031916610220528551600310620003b2576000620003c9565b85600381518110620003c057fe5b60200260200101515b60601b6001600160601b031916610240528551600410620003ec57600062000403565b85600481518110620003fa57fe5b60200260200101515b60601b6001600160601b031916610260528551600510620004265760006200043d565b856005815181106200043457fe5b60200260200101515b60601b6001600160601b0319166102805285516006106200046057600062000477565b856006815181106200046e57fe5b60200260200101515b60601b6001600160601b0319166102a05285516007106200049a576000620004b1565b85600781518110620004a857fe5b60200260200101515b60601b6001600160601b0319166102c0528551620004d1576000620004f7565b620004f786600081518110620004e357fe5b6020026020010151620008f560201b60201c565b6102e05285516001106200050d5760006200051f565b6200051f86600181518110620004e357fe5b6103005285516002106200053557600062000547565b6200054786600281518110620004e357fe5b6103205285516003106200055d5760006200056f565b6200056f86600381518110620004e357fe5b6103405285516004106200058557600062000597565b6200059786600481518110620004e357fe5b610360528551600510620005ad576000620005bf565b620005bf86600581518110620004e357fe5b610380528551600610620005d5576000620005e7565b620005e786600681518110620004e357fe5b6103a0528551600710620005fd5760006200060f565b6200060f86600781518110620004e357fe5b6103c08181525050505050505050505050505050505050505050600086519050620006478187516200099760201b62000d651760201c565b6000806000805b848160ff161015620006cd5760008a8260ff16815181106200066c57fe5b6020026020010151905062000694662386f26fc1000082101561012e6200086560201b60201c565b620006ae8186620009a660201b62000d721790919060201c565b945082811115620006c3578160ff1693508092505b506001016200064e565b50620006e6670de0b6b3a7640000841461013462000865565b6103e08290528851620006fb57600062000712565b886000815181106200070957fe5b60200260200101515b610400528851600110620007285760006200073f565b886001815181106200073657fe5b60200260200101515b610420528851600210620007555760006200076c565b886002815181106200076357fe5b60200260200101515b6104405288516003106200078257600062000799565b886003815181106200079057fe5b60200260200101515b610460528851600410620007af576000620007c6565b88600481518110620007bd57fe5b60200260200101515b610480528851600510620007dc576000620007f3565b88600581518110620007ea57fe5b60200260200101515b6104a05288516006106200080957600062000820565b886006815181106200081757fe5b60200260200101515b6104c0528851600710620008365760006200084d565b886007815181106200084457fe5b60200260200101515b6104e0525062000f329b505050505050505050505050565b8162000876576200087681620009c3565b5050565b80620008768162000a16565b6200089b64e8d4a5100082101560cb62000865565b620008b367016345785d8a000082111560ca62000865565b60078190556040517fa9ba3ffe0b6c366b81232caab38605a0699ad5398d6cce76f91ee809e322dafc90620008ea90839062000ec0565b60405180910390a150565b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156200093257600080fd5b505afa15801562000947573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200096d919062000dec565b60ff16905060006200098c60128362000aa360201b62000d841760201c565b600a0a949350505050565b62000876828214606762000865565b6000828201620009ba848210158362000865565b90505b92915050565b62461bcd60e51b6000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b60028151101562000a275762000aa0565b60008160008151811062000a3757fe5b602002602001015190506000600190505b825181101562000a9d57600083828151811062000a6157fe5b6020026020010151905062000a92816001600160a01b0316846001600160a01b03161060656200086560201b60201c565b915060010162000a48565b50505b50565b600062000ab583831115600162000865565b50900390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1062000afe57805160ff191683800117855562000b2e565b8280016001018555821562000b2e579182015b8281111562000b2e57825182559160200191906001019062000b11565b5062000b3c92915062000b40565b5090565b5b8082111562000b3c576000815560010162000b41565b8051620009bd8162000f1c565b600082601f83011262000b75578081fd5b815162000b8c62000b868262000ef0565b62000ec9565b81815291506020808301908481018184028601820187101562000bae57600080fd5b60005b8481101562000bda57815162000bc78162000f1c565b8452928201929082019060010162000bb1565b505050505092915050565b600082601f83011262000bf6578081fd5b815162000c0762000b868262000ef0565b81815291506020808301908481018184028601820187101562000c2957600080fd5b60005b8481101562000bda5781518452928201929082019060010162000c2c565b600082601f83011262000c5b578081fd5b81516001600160401b0381111562000c71578182fd5b602062000c87601f8301601f1916820162000ec9565b9250818352848183860101111562000c9e57600080fd5b60005b8281101562000cbe57848101820151848201830152810162000ca1565b8281111562000cd05760008284860101525b50505092915050565b60006020828403121562000ceb578081fd5b5051919050565b60008060008060008060008060006101208a8c03121562000d11578485fd5b62000d1d8b8b62000b57565b60208b01519099506001600160401b038082111562000d3a578687fd5b62000d488d838e0162000c4a565b995060408c015191508082111562000d5e578687fd5b62000d6c8d838e0162000c4a565b985060608c015191508082111562000d82578687fd5b62000d908d838e0162000b64565b975060808c015191508082111562000da6578687fd5b5062000db58c828d0162000be5565b95505060a08a0151935060c08a0151925060e08a0151915062000ddd8b6101008c0162000b57565b90509295985092959850929598565b60006020828403121562000dfe578081fd5b815160ff81168114620009ba578182fd5b60006060820185835260206060818501528186518084526080860191508288019350845b8181101562000e5b5762000e48855162000f10565b8352938301939183019160010162000e33565b505084810360408601528551808252908201925081860190845b8181101562000e9d5762000e8a835162000f10565b8552938301939183019160010162000e75565b509298975050505050505050565b602081016003831062000eba57fe5b91905290565b90815260200190565b6040518181016001600160401b038111828210171562000ee857600080fd5b604052919050565b60006001600160401b0382111562000f06578081fd5b5060209081020190565b6001600160a01b031690565b6001600160a01b038116811462000aa057600080fd5b60805160a05160601c60c05160e051610100516101205161014051610160516101805160601c6101a0516101c0516101e05160601c6102005160601c6102205160601c6102405160601c6102605160601c6102805160601c6102a05160601c6102c05160601c6102e05161030051610320516103405161036051610380516103a0516103c0516103e05161040051610420516104405161046051610480516104a0516104c0516104e05161476e6200114860003980611ec55280612857525080611e8252806127f6525080611e3f5280612795525080611dfc5280612734525080611db952806126d3525080611d765280612672525080611d335280612611525080611cf052806125b05250806122d0528061230452806123405250806116285280611b1e5250806115e55280611abd5250806115a25280611a5c52508061155f52806119fb52508061151c528061199a5250806114d9528061193952508061149652806118d85250806114455280611877525080611ae3528061281c525080611a8252806127bb525080611a21528061275a5250806119c052806126f952508061195f52806126985250806118fe528061263752508061189d52806125d652508061183c52806125755250806111025250806105d7525080610835525080610ef1525080610ecd525080610ab5525080610ff452508061103652508061101552508061081152508061079b525061476e6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80637ecebe001161010f578063a9059cbb116100a2578063d5c096c411610071578063d5c096c4146103e6578063d73dd623146103f9578063dd62ed3e1461040c578063f89f27ed1461041f576101f0565b8063a9059cbb146103b0578063aaabadc5146103c3578063c0ff1a15146103cb578063d505accf146103d3576101f0565b80638d928af8116100de5780638d928af81461038557806395d89b411461038d5780639b02cdde146103955780639d2c110c1461039d576101f0565b80637ecebe0014610337578063851c1bb31461034a57806387ec68171461035d578063893d20e814610370576101f0565b806338e9922e11610187578063661884631161015657806366188463146102e8578063679aefce146102fb57806370a082311461030357806374f3b00914610316576101f0565b806338e9922e146102a457806338fff2d0146102b757806355c67628146102bf5780636028bfd4146102c7576101f0565b80631c0de051116101c35780631c0de0511461025d57806323b872dd14610274578063313ce567146102875780633644e5151461029c576101f0565b806306fdde03146101f5578063095ea7b31461021357806316c38b3c1461023357806318160ddd14610248575b600080fd5b6101fd610434565b60405161020a9190614647565b60405180910390f35b61022661022136600461401c565b6104cb565b60405161020a919061457e565b610246610241366004614113565b6104e2565b005b6102506104f6565b60405161020a91906145a1565b6102656104fc565b60405161020a93929190614589565b610226610282366004613f67565b610525565b61028f6105a8565b60405161020a91906146b3565b6102506105ad565b6102466102b236600461449d565b6105bc565b6102506105d5565b6102506105f9565b6102da6102d536600461414b565b6105ff565b60405161020a92919061469a565b6102266102f636600461401c565b610636565b610250610690565b610250610311366004613f13565b6106bb565b61032961032436600461414b565b6106da565b60405161020a929190614559565b610250610345366004613f13565b61077c565b610250610358366004614248565b610797565b6102da61036b36600461414b565b6107e9565b61037861080f565b60405161020a9190614532565b610378610833565b6101fd610857565b6102506108b8565b6102506103ab3660046143a1565b6108be565b6102266103be36600461401c565b6109a5565b6103786109b2565b6102506109bc565b6102466103e1366004613fa7565b610a80565b6103296103f436600461414b565b610bc9565b61022661040736600461401c565b610cec565b61025061041a366004613f2f565b610d22565b610427610d4d565b60405161020a9190614546565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104c05780601f10610495576101008083540402835291602001916104c0565b820191906000526020600020905b8154815290600101906020018083116104a357829003601f168201915b505050505090505b90565b60006104d8338484610d9a565b5060015b92915050565b6104ea610e02565b6104f381610e30565b50565b60025490565b6000806000610509610eae565b159250610514610ecb565b915061051e610eef565b9050909192565b6001600160a01b0383166000818152600160209081526040808320338085529252822054919261056391148061055b5750838210155b610197610f13565b61056e858585610f21565b336001600160a01b0386161480159061058957506000198114155b1561059b5761059b8533858403610d9a565b60019150505b9392505050565b601290565b60006105b7610ff0565b905090565b6105c4610e02565b6105cc61108d565b6104f3816110a2565b7f000000000000000000000000000000000000000000000000000000000000000090565b60075490565b600060606106158651610610611100565b610d65565b61062a898989898989896111246111ec611252565b97509795505050505050565b3360009081526001602090815260408083206001600160a01b03861684529091528120548083106106725761066d33856000610d9a565b610686565b61068633856106818487610d84565b610d9a565b5060019392505050565b60006105b761069d6104f6565b6106b56106a86109bc565b6106b0611100565b611374565b90611398565b6001600160a01b0381166000908152602081905260409020545b919050565b606080886107046106e9610833565b6001600160a01b0316336001600160a01b03161460cd610f13565b61071961070f6105d5565b82146101f4610f13565b60606107236113e9565b905061072f8882611666565b60006060806107438e8e8e8e8e8e8e611124565b9250925092506107538d846116c7565b61075d82856111ec565b61076781856111ec565b909550935050505b5097509795505050505050565b6001600160a01b031660009081526005602052604090205490565b60007f0000000000000000000000000000000000000000000000000000000000000000826040516020016107cc9291906144ef565b604051602081830303815290604052805190602001209050919050565b600060606107fa8651610610611100565b61062a8989898989898961175a6117d7611252565b7f000000000000000000000000000000000000000000000000000000000000000090565b7f000000000000000000000000000000000000000000000000000000000000000090565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104c05780601f10610495576101008083540402835291602001916104c0565b60085490565b6000806108ce8560200151611838565b905060006108df8660400151611838565b90506000865160018111156108f057fe5b1415610956576109038660600151611b4d565b60608701526109128583611b71565b945061091e8482611b71565b935061092e866060015183611b71565b60608701526000610940878787611b7d565b905061094c8183611bb8565b93505050506105a1565b6109608583611b71565b945061096c8482611b71565b935061097c866060015182611b71565b6060870152600061098e878787611bc4565b905061099a8184611bf7565b905061094c81611c03565b60006104d8338484610f21565b60006105b7611c1a565b600060606109c8610833565b6001600160a01b031663f94d46686109de6105d5565b6040518263ffffffff1660e01b81526004016109fa91906145a1565b60006040518083038186803b158015610a1257600080fd5b505afa158015610a26573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a4e9190810190614047565b50915050610a6381610a5e6113e9565b611666565b6060610a6d611c94565b9050610a798183611ef1565b9250505090565b610a8e8442111560d1610f13565b6001600160a01b0387166000908152600560209081526040808320549051909291610ae5917f0000000000000000000000000000000000000000000000000000000000000000918c918c918c9188918d91016145c9565b6040516020818303038152906040528051906020012090506000610b0882611f63565b9050600060018288888860405160008152602001604052604051610b2f9493929190614629565b6020604051602081039080840390855afa158015610b51573d6000803e3d6000fd5b5050604051601f1901519150610b9390506001600160a01b03821615801590610b8b57508b6001600160a01b0316826001600160a01b0316145b6101f8610f13565b6001600160a01b038b166000908152600560205260409020600185019055610bbc8b8b8b610d9a565b5050505050505050505050565b60608088610bd86106e9610833565b610be361070f6105d5565b6060610bed6113e9565b9050610bf76104f6565b610c9d5760006060610c0b8d8d8d8a611f7f565b91509150610c20620f424083101560cc610f13565b610c2e6000620f424061201a565b610c3d8b620f4240840361201a565b610c4781846117d7565b80610c50611100565b67ffffffffffffffff81118015610c6657600080fd5b50604051908082528060200260200182016040528015610c90578160200160208202803683370190505b509550955050505061076f565b610ca78882611666565b6000606080610cbb8e8e8e8e8e8e8e61175a565b925092509250610ccb8c8461201a565b610cd582856117d7565b610cdf81856111ec565b909550935061076f915050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916104d89185906106819086610d72565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60606105b7611c94565b80610d61816120b0565b5050565b610d618183146067610f13565b60008282016105a18482101583610f13565b6000610d94838311156001610f13565b50900390565b6001600160a01b0380841660008181526001602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610df59085906145a1565b60405180910390a3505050565b6000610e196000356001600160e01b031916610797565b90506104f3610e288233612129565b610191610f13565b8015610e5057610e4b610e41610ecb565b4210610193610f13565b610e65565b610e65610e5b610eef565b42106101a9610f13565b6006805460ff19168215151790556040517f9e3a5e37224532dea67b89face185703738a228a6e8a23dee546960180d3be6490610ea390839061457e565b60405180910390a150565b6000610eb8610eef565b4211806105b757505060065460ff161590565b7f000000000000000000000000000000000000000000000000000000000000000090565b7f000000000000000000000000000000000000000000000000000000000000000090565b81610d6157610d6181612219565b6001600160a01b038316600090815260208190526040902054610f4982821015610196610f13565b610f606001600160a01b0384161515610199610f13565b6001600160a01b03808516600090815260208190526040808220858503905591851681522054610f909083610d72565b6001600160a01b0380851660008181526020819052604090819020939093559151908616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610fe29086906145a1565b60405180910390a350505050565b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061105d61226c565b306040516020016110729594939291906145fd565b60405160208183030381529060405280519060200120905090565b6110a0611098610eae565b610192610f13565b565b6110b564e8d4a5100082101560cb610f13565b6110cb67016345785d8a000082111560ca610f13565b60078190556040517fa9ba3ffe0b6c366b81232caab38605a0699ad5398d6cce76f91ee809e322dafc90610ea39083906145a1565b7f000000000000000000000000000000000000000000000000000000000000000090565b60006060806060611133611c94565b905061113d610eae565b1561117457600061114e828a611ef1565b905061115f8983600854848b612270565b925061116e8984610d84612380565b506111c0565b61117c611100565b67ffffffffffffffff8111801561119257600080fd5b506040519080825280602002602001820160405280156111bc578160200160208202803683370190505b5091505b6111cb8882876123eb565b90945092506111db888483612458565b600855509750975097945050505050565b60005b6111f7611100565b81101561124d5761122e83828151811061120d57fe5b602002602001015183838151811061122157fe5b6020026020010151612471565b83828151811061123a57fe5b60209081029190910101526001016111ef565b505050565b333014611310576000306001600160a01b0316600036604051611276929190614507565b6000604051808303816000865af19150503d80600081146112b3576040519150601f19603f3d011682016040523d82523d6000602084013e6112b8565b606091505b5050905080600081146112c757fe5b60046000803e6000516001600160e01b0319166343adbafb60e01b81146112f2573d6000803e3d6000fd5b506020600460003e604060205260243d03602460403e601c3d016000f35b606061131a6113e9565b90506113268782611666565b6000606061133d8c8c8c8c8c8c8c8c63ffffffff16565b509150915061135081848663ffffffff16565b8051601f1982018390526343adbafb603f1983015260200260231982016044820181fd5b60008282026105a184158061139157508385838161138e57fe5b04145b6003610f13565b60006113a78215156004610f13565b826113b4575060006104dc565b670de0b6b3a7640000838102906113d7908583816113ce57fe5b04146005610f13565b8281816113e057fe5b049150506104dc565b606060006113f5611100565b905060608167ffffffffffffffff8111801561141057600080fd5b5060405190808252806020026020018201604052801561143a578160200160208202803683370190505b5090508115611482577f00000000000000000000000000000000000000000000000000000000000000008160008151811061147157fe5b60200260200101818152505061148b565b91506104c89050565b6001821115611482577f0000000000000000000000000000000000000000000000000000000000000000816001815181106114c257fe5b6020026020010181815250506002821115611482577f00000000000000000000000000000000000000000000000000000000000000008160028151811061150557fe5b6020026020010181815250506003821115611482577f00000000000000000000000000000000000000000000000000000000000000008160038151811061154857fe5b6020026020010181815250506004821115611482577f00000000000000000000000000000000000000000000000000000000000000008160048151811061158b57fe5b6020026020010181815250506005821115611482577f0000000000000000000000000000000000000000000000000000000000000000816005815181106115ce57fe5b6020026020010181815250506006821115611482577f00000000000000000000000000000000000000000000000000000000000000008160068151811061161157fe5b6020026020010181815250506007821115611482577f00000000000000000000000000000000000000000000000000000000000000008160078151811061165457fe5b60200260200101818152505091505090565b60005b611671611100565b81101561124d576116a883828151811061168757fe5b602002602001015183838151811061169b57fe5b6020026020010151611374565b8382815181106116b457fe5b6020908102919091010152600101611669565b6001600160a01b0382166000908152602081905260409020546116ef82821015610196610f13565b6001600160a01b038316600090815260208190526040902082820390556002546117199083610d84565b6002556040516000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610df59086906145a1565b600060608061176761108d565b6060611771611c94565b9050600061177f828a611ef1565b905060606117928a84600854858c612270565b90506117a18a82610d84612380565b600060606117b08c868b612491565b915091506117bf8c82876124eb565b600855909e909d50909b509950505050505050505050565b60005b6117e2611100565b81101561124d576118198382815181106117f857fe5b602002602001015183838151811061180c57fe5b60200260200101516124fa565b83828151811061182557fe5b60209081029190910101526001016117da565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561189b57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156118fc57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561195d57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156119be57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611a1f57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611a8057507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611ae157507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611b4257507f00000000000000000000000000000000000000000000000000000000000000006106d5565b6106d5610135612219565b600080611b656007548461252d90919063ffffffff16565b90506105a18382610d84565b60006105a18383611374565b6000611b8761108d565b611bb083611b988660200151612571565b84611ba68860400151612571565b886060015161287b565b949350505050565b60006105a18383612471565b6000611bce61108d565b611bb083611bdf8660200151612571565b84611bed8860400151612571565b88606001516128f6565b60006105a183836124fa565b60006104dc611c1360075461296c565b8390612992565b6000611c24610833565b6001600160a01b031663aaabadc56040518163ffffffff1660e01b815260040160206040518083038186803b158015611c5c57600080fd5b505afa158015611c70573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b79190614270565b60606000611ca0611100565b905060608167ffffffffffffffff81118015611cbb57600080fd5b50604051908082528060200260200182016040528015611ce5578160200160208202803683370190505b5090508115611482577f000000000000000000000000000000000000000000000000000000000000000081600081518110611d1c57fe5b6020026020010181815250506001821115611482577f000000000000000000000000000000000000000000000000000000000000000081600181518110611d5f57fe5b6020026020010181815250506002821115611482577f000000000000000000000000000000000000000000000000000000000000000081600281518110611da257fe5b6020026020010181815250506003821115611482577f000000000000000000000000000000000000000000000000000000000000000081600381518110611de557fe5b6020026020010181815250506004821115611482577f000000000000000000000000000000000000000000000000000000000000000081600481518110611e2857fe5b6020026020010181815250506005821115611482577f000000000000000000000000000000000000000000000000000000000000000081600581518110611e6b57fe5b6020026020010181815250506006821115611482577f000000000000000000000000000000000000000000000000000000000000000081600681518110611eae57fe5b6020026020010181815250506007821115611482577f00000000000000000000000000000000000000000000000000000000000000008160078151811061165457fe5b670de0b6b3a764000060005b8351811015611f5357611f49611f42858381518110611f1857fe5b6020026020010151858481518110611f2c57fe5b60200260200101516129d490919063ffffffff16565b8390612a23565b9150600101611efd565b506104dc60008211610137610f13565b6000611f6d610ff0565b826040516020016107cc929190614517565b60006060611f8b61108d565b6000611f9684612a4f565b9050611fb16000826002811115611fa957fe5b1460ce610f13565b6060611fbc85612a65565b9050611fd0611fc9611100565b8251610d65565b611fdc81610a5e6113e9565b6060611fe6611c94565b90506000611ff48284611ef1565b90506000612004826106b0611100565b6008929092555099919850909650505050505050565b6001600160a01b03821660009081526020819052604090205461203d9082610d72565b6001600160a01b0383166000908152602081905260409020556002546120639082610d72565b6002556040516001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906120a49085906145a1565b60405180910390a35050565b6002815110156120bf576104f3565b6000816000815181106120ce57fe5b602002602001015190506000600190505b825181101561124d5760008382815181106120f657fe5b6020026020010151905061211f816001600160a01b0316846001600160a01b0316106065610f13565b91506001016120df565b600073ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1ba1b61214861080f565b6001600160a01b031614158015612163575061216383612a7b565b1561218b5761217061080f565b6001600160a01b0316336001600160a01b03161490506104dc565b612193611c1a565b6001600160a01b0316639be2a8848484306040518463ffffffff1660e01b81526004016121c2939291906145aa565b60206040518083038186803b1580156121da57600080fd5b505afa1580156121ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612212919061412f565b90506104dc565b62461bcd60e51b6000908152602060045260076024526642414c23000030600a808404818106603090810160081b95839006959095019082900491820690940160101b939093010160c81b604452606490fd5b4690565b60608061227b611100565b67ffffffffffffffff8111801561229157600080fd5b506040519080825280602002602001820160405280156122bb578160200160208202803683370190505b509050826122ca579050612377565b61233d877f0000000000000000000000000000000000000000000000000000000000000000815181106122f957fe5b6020026020010151877f00000000000000000000000000000000000000000000000000000000000000008151811061232d57fe5b6020026020010151878787612a95565b817f00000000000000000000000000000000000000000000000000000000000000008151811061236957fe5b602090810291909101015290505b95945050505050565b60005b61238b611100565b8110156123e5576123c68482815181106123a157fe5b60200260200101518483815181106123b557fe5b60200260200101518463ffffffff16565b8482815181106123d257fe5b6020908102919091010152600101612383565b50505050565b6000606060006123fa84612a4f565b9050600081600281111561240a57fe5b14156124255761241b868686612b0d565b9250925050612450565b600181600281111561243357fe5b14156124435761241b8685612beb565b61241b868686612c1d565b505b935093915050565b60006124678484610d84612380565b611bb08285611ef1565b60006124808215156004610f13565b81838161248957fe5b049392505050565b6000606060006124a084612a4f565b905060018160028111156124b057fe5b14156124c15761241b868686612c88565b60028160028111156124cf57fe5b14156124e05761241b868686612ce2565b61244e610136612219565b60006124678484610d72612380565b60006125098215156004610f13565b82612516575060006104dc565b81600184038161252257fe5b0460010190506104dc565b600082820261254784158061139157508385838161138e57fe5b806125565760009150506104dc565b670de0b6b3a764000060001982015b046001019150506104dc565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156125d457507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561263557507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561269657507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156126f757507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561275857507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156127b957507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316141561281a57507f00000000000000000000000000000000000000000000000000000000000000006106d5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611b4257507f00000000000000000000000000000000000000000000000000000000000000006106d5565b600061289d61289287670429d069189e0000612a23565b831115610130610f13565b60006128a98784610d72565b905060006128b78883612992565b905060006128c58887611398565b905060006128d38383612d8a565b90506128e86128e18261296c565b8990612a23565b9a9950505050505050505050565b600061291861290d85670429d069189e0000612a23565b831115610131610f13565b600061292e6129278685610d84565b8690612992565b9050600061293c8588612992565b9050600061294a8383612d8a565b9050600061296082670de0b6b3a7640000610d84565b90506128e88a8261252d565b6000670de0b6b3a764000082106129845760006104dc565b50670de0b6b3a76400000390565b60006129a18215156004610f13565b826129ae575060006104dc565b670de0b6b3a7640000838102906129c8908583816113ce57fe5b82600182038161256557fe5b6000806129e18484612db6565b905060006129fb6129f48361271061252d565b6001610d72565b905080821015612a10576000925050506104dc565b612a1a8282610d84565b925050506104dc565b6000828202612a3d84158061139157508385838161138e57fe5b670de0b6b3a764000090049392505050565b6000818060200190518101906104dc919061428c565b6060818060200190518101906105a19190614352565b6000612a8d631c74c91760e11b610797565b909114919050565b6000838311612aa657506000612377565b6000612ab28585612992565b90506000612ac8670de0b6b3a764000088611398565b9050612adc826709b6e64a8ec60000612ec1565b91506000612aea8383612d8a565b90506000612b01612afa8361296c565b8b90612a23565b90506128e88187612a23565b60006060612b1961108d565b600080612b2585612ed8565b91509150612b3d612b34611100565b82106064610f13565b6060612b47611100565b67ffffffffffffffff81118015612b5d57600080fd5b50604051908082528060200260200182016040528015612b87578160200160208202803683370190505b509050612bc6888381518110612b9957fe5b6020026020010151888481518110612bad57fe5b602002602001015185612bbe6104f6565b600754612efa565b818381518110612bd257fe5b6020908102919091010152919791965090945050505050565b600060606000612bfa84612fb7565b90506060612c108683612c0b6104f6565b612fcd565b9196919550909350505050565b60006060612c2961108d565b60606000612c368561307f565b91509150612c478251610610611100565b612c5382610a5e6113e9565b6000612c6b888885612c636104f6565b600754613097565b9050612c7b8282111560cf610f13565b9791965090945050505050565b60006060806000612c988561307f565b91509150612cae612ca7611100565b8351610d65565b612cba82610a5e6113e9565b6000612cd2888885612cca6104f6565b6007546132bc565b9050612c7b8282101560d0610f13565b60006060600080612cf285612ed8565b91509150612d01612b34611100565b6060612d0b611100565b67ffffffffffffffff81118015612d2157600080fd5b50604051908082528060200260200182016040528015612d4b578160200160208202803683370190505b509050612bc6888381518110612d5d57fe5b6020026020010151888481518110612d7157fe5b602002602001015185612d826104f6565b6007546134cd565b600080612d978484612db6565b90506000612daa6129f48361271061252d565b90506123778282610d72565b600081612dcc5750670de0b6b3a76400006104dc565b82612dd9575060006104dc565b612dea600160ff1b84106006610f13565b82612e10770bce5086492111aea88f4bb1ca6bcf584181ea8059f7653284106007610f13565b826000670c7d713b49da000083138015612e315750670f43fc2c04ee000083125b15612e68576000612e418461356f565b9050670de0b6b3a764000080820784020583670de0b6b3a764000083050201915050612e76565b81612e7284613696565b0290505b670de0b6b3a76400009005612eae680238fd42c5cf03ffff198212801590612ea7575068070c1cc73b00c800008213155b6008610f13565b612eb781613a44565b9695505050505050565b600081831015612ed157816105a1565b5090919050565b60008082806020019051810190612eef919061431c565b909590945092505050565b600080612f1184612f0b8188610d84565b90612992565b9050612f2a6709b6e64a8ec60000821015610132610f13565b6000612f48612f41670de0b6b3a764000089611398565b8390612d8a565b90506000612f5f612f588361296c565b8a90612a23565b90506000612f6c8961296c565b90506000612f7a838361252d565b90506000612f888483610d84565b9050612fa7612fa0612f998a61296c565b8490612a23565b8290610d72565b9c9b505050505050505050505050565b6000818060200190518101906105a191906142ef565b60606000612fdb8484611398565b90506060855167ffffffffffffffff81118015612ff757600080fd5b50604051908082528060200260200182016040528015613021578160200160208202803683370190505b50905060005b8651811015613075576130568388838151811061304057fe5b6020026020010151612a2390919063ffffffff16565b82828151811061306257fe5b6020908102919091010152600101613027565b5095945050505050565b6060600082806020019051810190612eef91906142a8565b60006060845167ffffffffffffffff811180156130b357600080fd5b506040519080825280602002602001820160405280156130dd578160200160208202803683370190505b5090506000805b88518110156131a25761313d8982815181106130fc57fe5b6020026020010151612f0b89848151811061311357fe5b60200260200101518c858151811061312757fe5b6020026020010151610d8490919063ffffffff16565b83828151811061314957fe5b60200260200101818152505061319861319189838151811061316757fe5b602002602001015185848151811061317b57fe5b602002602001015161252d90919063ffffffff16565b8390610d72565b91506001016130e4565b50670de0b6b3a764000060005b895181101561329b5760008482815181106131c657fe5b602002602001015184111561321d5760006131ef6131e38661296c565b8d858151811061304057fe5b90506000613203828c868151811061312757fe5b9050613214613191611c138b61296c565b92505050613234565b88828151811061322957fe5b602002602001015190505b600061325d8c848151811061324557fe5b60200260200101516106b5848f878151811061312757fe5b905061328f6132888c858151811061327157fe5b6020026020010151836129d490919063ffffffff16565b8590612a23565b935050506001016131af565b506132af6132a88261296c565b879061252d565b9998505050505050505050565b60006060845167ffffffffffffffff811180156132d857600080fd5b50604051908082528060200260200182016040528015613302578160200160208202803683370190505b5090506000805b88518110156133aa5761336289828151811061332157fe5b60200260200101516106b589848151811061333857fe5b60200260200101518c858151811061334c57fe5b6020026020010151610d7290919063ffffffff16565b83828151811061336e57fe5b6020026020010181815250506133a061319189838151811061338c57fe5b602002602001015185848151811061304057fe5b9150600101613309565b50670de0b6b3a764000060005b895181101561348b576000838583815181106133cf57fe5b6020026020010151111561342b5760006133f46131e386670de0b6b3a7640000610d84565b90506000613408828c868151811061312757fe5b9050613422613191611f42670de0b6b3a76400008c610d84565b92505050613442565b88828151811061343757fe5b602002602001015190505b600061346b8c848151811061345357fe5b60200260200101516106b5848f878151811061334c57fe5b905061347f6132888c858151811061327157fe5b935050506001016133b7565b50670de0b6b3a764000081106134c1576134b76134b082670de0b6b3a7640000610d84565b8790612a23565b9350505050612377565b60009350505050612377565b6000806134de84612f0b8188610d72565b90506134f76729a2241af62c0000821115610133610f13565b600061350e612f41670de0b6b3a764000089612992565b9050600061352e61352783670de0b6b3a7640000610d84565b8a9061252d565b9050600061353b8961296c565b90506000613549838361252d565b905060006135578483610d84565b9050612fa7612fa06135688a61296c565b8490612992565b670de0b6b3a7640000026000806ec097ce7bc90715b34b9f1000000000808401906ec097ce7bc90715b34b9f0fffffffff19850102816135ab57fe5b05905060006ec097ce7bc90715b34b9f100000000082800205905081806ec097ce7bc90715b34b9f100000000081840205915060038205016ec097ce7bc90715b34b9f100000000082840205915060058205016ec097ce7bc90715b34b9f100000000082840205915060078205016ec097ce7bc90715b34b9f100000000082840205915060098205016ec097ce7bc90715b34b9f1000000000828402059150600b8205016ec097ce7bc90715b34b9f1000000000828402059150600d8205016ec097ce7bc90715b34b9f1000000000828402059150600f826002919005919091010295945050505050565b60006136a6600083136064610f13565b670de0b6b3a76400008212156136e1576136d7826ec097ce7bc90715b34b9f1000000000816136d157fe5b05613696565b60000390506106d5565b60007e1600ef3172e58d2e933ec884fde10064c63b5372d805e203c0000000000000831261373257770195e54c5dd42177f53a27172fa9ec630262827000000000830592506806f05b59d3b2000000015b73011798004d755d3c8bc8e03204cf44619e000000831261376a576b1425982cf597cd205cef7380830592506803782dace9d9000000015b606492830292026e01855144814a7ff805980ff008400083126137b2576e01855144814a7ff805980ff008400068056bc75e2d63100000840205925068ad78ebc5ac62000000015b6b02df0ab5a80a22c61ab5a70083126137ed576b02df0ab5a80a22c61ab5a70068056bc75e2d6310000084020592506856bc75e2d631000000015b693f1fce3da636ea5cf850831261382457693f1fce3da636ea5cf85068056bc75e2d631000008402059250682b5e3af16b18800000015b690127fa27722cc06cc5e2831261385b57690127fa27722cc06cc5e268056bc75e2d6310000084020592506815af1d78b58c400000015b68280e60114edb805d0383126138905768280e60114edb805d0368056bc75e2d631000008402059250680ad78ebc5ac6200000015b680ebc5fb4174612111083126138bb57680ebc5fb4174612111068056bc75e2d631000009384020592015b6808f00f760a4b2db55d83126138f0576808f00f760a4b2db55d68056bc75e2d6310000084020592506802b5e3af16b1880000015b6806f5f17757889379378312613925576806f5f177578893793768056bc75e2d63100000840205925068015af1d78b58c40000015b6806248f33704b2866038312613959576806248f33704b28660368056bc75e2d63100000840205925067ad78ebc5ac620000015b6805c548670b9510e7ac831261398d576805c548670b9510e7ac68056bc75e2d6310000084020592506756bc75e2d6310000015b600068056bc75e2d63100000840168056bc75e2d6310000080860302816139b057fe5b059050600068056bc75e2d63100000828002059050818068056bc75e2d63100000818402059150600382050168056bc75e2d63100000828402059150600582050168056bc75e2d63100000828402059150600782050168056bc75e2d63100000828402059150600982050168056bc75e2d63100000828402059150600b820501600202606485820105979650505050505050565b6000613a73680238fd42c5cf03ffff198312158015613a6c575068070c1cc73b00c800008313155b6009610f13565b6000821215613aa757613a8882600003613a44565b6ec097ce7bc90715b34b9f100000000081613a9f57fe5b0590506106d5565b60006806f05b59d3b20000008312613ae757506806f05b59d3b1ffffff1990910190770195e54c5dd42177f53a27172fa9ec630262827000000000613b1d565b6803782dace9d90000008312613b1957506803782dace9d8ffffff19909101906b1425982cf597cd205cef7380613b1d565b5060015b6064929092029168056bc75e2d6310000068ad78ebc5ac620000008412613b6d5768ad78ebc5ac61ffffff199093019268056bc75e2d631000006e01855144814a7ff805980ff008400082020590505b6856bc75e2d6310000008412613ba9576856bc75e2d630ffffff199093019268056bc75e2d631000006b02df0ab5a80a22c61ab5a70082020590505b682b5e3af16b188000008412613be357682b5e3af16b187fffff199093019268056bc75e2d63100000693f1fce3da636ea5cf85082020590505b6815af1d78b58c4000008412613c1d576815af1d78b58c3fffff199093019268056bc75e2d63100000690127fa27722cc06cc5e282020590505b680ad78ebc5ac62000008412613c5657680ad78ebc5ac61fffff199093019268056bc75e2d6310000068280e60114edb805d0382020590505b68056bc75e2d631000008412613c8f5768056bc75e2d630fffff199093019268056bc75e2d63100000680ebc5fb4174612111082020590505b6802b5e3af16b18800008412613cc8576802b5e3af16b187ffff199093019268056bc75e2d631000006808f00f760a4b2db55d82020590505b68015af1d78b58c400008412613d015768015af1d78b58c3ffff199093019268056bc75e2d631000006806f5f177578893793782020590505b68056bc75e2d631000008481019085906002908280020505918201919050600368056bc75e2d631000008783020505918201919050600468056bc75e2d631000008783020505918201919050600568056bc75e2d631000008783020505918201919050600668056bc75e2d631000008783020505918201919050600768056bc75e2d631000008783020505918201919050600868056bc75e2d631000008783020505918201919050600968056bc75e2d631000008783020505918201919050600a68056bc75e2d631000008783020505918201919050600b68056bc75e2d631000008783020505918201919050600c68056bc75e2d631000008783020505918201919050606468056bc75e2d63100000848402058502059695505050505050565b80356104dc81614708565b600082601f830112613e3d578081fd5b8151613e50613e4b826146e8565b6146c1565b818152915060208083019084810181840286018201871015613e7157600080fd5b60005b84811015613e9057815184529282019290820190600101613e74565b505050505092915050565b600082601f830112613eab578081fd5b813567ffffffffffffffff811115613ec1578182fd5b613ed4601f8201601f19166020016146c1565b9150808252836020828501011115613eeb57600080fd5b8060208401602084013760009082016020015292915050565b8035600281106104dc57600080fd5b600060208284031215613f24578081fd5b81356105a181614708565b60008060408385031215613f41578081fd5b8235613f4c81614708565b91506020830135613f5c81614708565b809150509250929050565b600080600060608486031215613f7b578081fd5b8335613f8681614708565b92506020840135613f9681614708565b929592945050506040919091013590565b600080600080600080600060e0888a031215613fc1578283fd5b8735613fcc81614708565b96506020880135613fdc81614708565b95506040880135945060608801359350608088013560ff81168114613fff578384fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561402e578182fd5b823561403981614708565b946020939093013593505050565b60008060006060848603121561405b578081fd5b835167ffffffffffffffff80821115614072578283fd5b818601915086601f830112614085578283fd5b8151614093613e4b826146e8565b80828252602080830192508086018b8283870289010111156140b3578788fd5b8796505b848710156140de5780516140ca81614708565b8452600196909601959281019281016140b7565b5089015190975093505050808211156140f5578283fd5b5061410286828701613e2d565b925050604084015190509250925092565b600060208284031215614124578081fd5b81356105a18161471d565b600060208284031215614140578081fd5b81516105a18161471d565b600080600080600080600060e0888a031215614165578081fd5b8735965060208089013561417881614708565b9650604089013561418881614708565b9550606089013567ffffffffffffffff808211156141a4578384fd5b818b0191508b601f8301126141b7578384fd5b81356141c5613e4b826146e8565b8082825285820191508585018f8788860288010111156141e3578788fd5b8795505b838610156142055780358352600195909501949186019186016141e7565b509850505060808b0135955060a08b0135945060c08b013592508083111561422b578384fd5b50506142398a828b01613e9b565b91505092959891949750929550565b600060208284031215614259578081fd5b81356001600160e01b0319811681146105a1578182fd5b600060208284031215614281578081fd5b81516105a181614708565b60006020828403121561429d578081fd5b81516105a18161472b565b6000806000606084860312156142bc578081fd5b83516142c78161472b565b602085015190935067ffffffffffffffff8111156142e3578182fd5b61410286828701613e2d565b60008060408385031215614301578182fd5b825161430c8161472b565b6020939093015192949293505050565b600080600060608486031215614330578081fd5b835161433b8161472b565b602085015160409095015190969495509392505050565b60008060408385031215614364578182fd5b825161436f8161472b565b602084015190925067ffffffffffffffff81111561438b578182fd5b61439785828601613e2d565b9150509250929050565b6000806000606084860312156143b5578081fd5b833567ffffffffffffffff808211156143cc578283fd5b81860191506101208083890312156143e2578384fd5b6143eb816146c1565b90506143f78884613f04565b81526144068860208501613e22565b60208201526144188860408501613e22565b6040820152606083013560608201526080830135608082015260a083013560a08201526144488860c08501613e22565b60c082015261445a8860e08501613e22565b60e08201526101008084013583811115614472578586fd5b61447e8a828701613e9b565b9183019190915250976020870135975060409096013595945050505050565b6000602082840312156144ae578081fd5b5035919050565b6000815180845260208085019450808401835b838110156144e4578151875295820195908201906001016144c8565b509495945050505050565b9182526001600160e01b031916602082015260240190565b6000828483379101908152919050565b61190160f01b81526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6000602082526105a160208301846144b5565b60006040825261456c60408301856144b5565b828103602084015261237781856144b5565b901515815260200190565b92151583526020830191909152604082015260600190565b90815260200190565b9283526001600160a01b03918216602084015216604082015260600190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b6000602080835283518082850152825b8181101561467357858101830151858201604001528201614657565b818111156146845783604083870101525b50601f01601f1916929092016040019392505050565b600083825260406020830152611bb060408301846144b5565b60ff91909116815260200190565b60405181810167ffffffffffffffff811182821017156146e057600080fd5b604052919050565b600067ffffffffffffffff8211156146fe578081fd5b5060209081020190565b6001600160a01b03811681146104f357600080fd5b80151581146104f357600080fd5b600381106104f357600080fdfea2646970667358221220a2c3b62e0bc50507598395387e1557612d7ad59e817ddae4d5279907402fedb464736f6c63430007010033", + "deployedBytecode": "", + "linkReferences": {}, + "deployedLinkReferences": {} +} + \ No newline at end of file diff --git a/external/contracts/balancer/v2/BPoolV2.sol b/external/contracts/balancer/v2/BPoolV2.sol new file mode 100644 index 000000000..755ae4e52 --- /dev/null +++ b/external/contracts/balancer/v2/BPoolV2.sol @@ -0,0 +1,705 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +import "@balancer-labs/v2-solidity-utils/contracts/math/Math.sol"; +import "@balancer-labs/v2-solidity-utils/contracts/math/FixedPoint.sol"; +import "@balancer-labs/v2-solidity-utils/contracts/helpers/InputHelpers.sol"; +import "@balancer-labs/v2-solidity-utils/contracts/helpers/TemporarilyPausable.sol"; +import "@balancer-labs/v2-solidity-utils/contracts/helpers/WordCodec.sol"; +import "@balancer-labs/v2-solidity-utils/contracts/openzeppelin/ERC20.sol"; + +import "@balancer-labs/v2-vault/contracts/interfaces/IVault.sol"; +import "@balancer-labs/v2-vault/contracts/interfaces/IBasePool.sol"; + +import "@balancer-labs/v2-asset-manager-utils/contracts/IAssetManager.sol"; + +import "./BalancerPoolToken.sol"; +import "./BasePoolAuthorization.sol"; + +// solhint-disable max-states-count + +/** + * @dev Reference implementation for the base layer of a Pool contract that manages a single Pool with optional + * Asset Managers, an admin-controlled swap fee percentage, and an emergency pause mechanism. + * + * Note that neither swap fees nor the pause mechanism are used by this contract. They are passed through so that + * derived contracts can use them via the `_addSwapFeeAmount` and `_subtractSwapFeeAmount` functions, and the + * `whenNotPaused` modifier. + * + * No admin permissions are checked here: instead, this contract delegates that to the Vault's own Authorizer. + * + * Because this contract doesn't implement the swap hooks, derived contracts should generally inherit from + * BaseGeneralPool or BaseMinimalSwapInfoPool. Otherwise, subclasses must inherit from the corresponding interfaces + * and implement the swap callbacks themselves. + */ +abstract contract BasePool is IBasePool, BasePoolAuthorization, BalancerPoolToken, TemporarilyPausable { + using WordCodec for bytes32; + using FixedPoint for uint256; + + uint256 private constant _MIN_TOKENS = 2; + + uint256 private constant _MINIMUM_BPT = 1e6; + + // 1e18 corresponds to 1.0, or a 100% fee + uint256 private constant _MIN_SWAP_FEE_PERCENTAGE = 1e12; // 0.0001% + uint256 private constant _MAX_SWAP_FEE_PERCENTAGE = 1e17; // 10% - this fits in 64 bits + + // Storage slot that can be used to store unrelated pieces of information. In particular, by default is used + // to store only the swap fee percentage of a pool. But it can be extended to store some more pieces of information. + // The swap fee percentage is stored in the most-significant 64 bits, therefore the remaining 192 bits can be + // used to store any other piece of information. + bytes32 private _miscData; + uint256 private constant _SWAP_FEE_PERCENTAGE_OFFSET = 192; + + IVault private immutable _vault; + bytes32 private immutable _poolId; + + event SwapFeePercentageChanged(uint256 swapFeePercentage); + + constructor( + IVault vault, + IVault.PoolSpecialization specialization, + string memory name, + string memory symbol, + IERC20[] memory tokens, + address[] memory assetManagers, + uint256 swapFeePercentage, + uint256 pauseWindowDuration, + uint256 bufferPeriodDuration, + address owner + ) + // Base Pools are expected to be deployed using factories. By using the factory address as the action + // disambiguator, we make all Pools deployed by the same factory share action identifiers. This allows for + // simpler management of permissions (such as being able to manage granting the 'set fee percentage' action in + // any Pool created by the same factory), while still making action identifiers unique among different factories + // if the selectors match, preventing accidental errors. + Authentication(bytes32(uint256(msg.sender))) + BalancerPoolToken(name, symbol) + BasePoolAuthorization(owner) + TemporarilyPausable(pauseWindowDuration, bufferPeriodDuration) + { + _require(tokens.length >= _MIN_TOKENS, Errors.MIN_TOKENS); + _require(tokens.length <= _getMaxTokens(), Errors.MAX_TOKENS); + + // The Vault only requires the token list to be ordered for the Two Token Pools specialization. However, + // to make the developer experience consistent, we are requiring this condition for all the native pools. + // Also, since these Pools will register tokens only once, we can ensure the Pool tokens will follow the same + // order. We rely on this property to make Pools simpler to write, as it lets us assume that the + // order of token-specific parameters (such as token weights) will not change. + InputHelpers.ensureArrayIsSorted(tokens); + + _setSwapFeePercentage(swapFeePercentage); + + bytes32 poolId = vault.registerPool(specialization); + + vault.registerTokens(poolId, tokens, assetManagers); + + // Set immutable state variables - these cannot be read from during construction + _vault = vault; + _poolId = poolId; + } + + // Getters / Setters + + function getVault() public view returns (IVault) { + return _vault; + } + + function getPoolId() public view override returns (bytes32) { + return _poolId; + } + + function _getTotalTokens() internal view virtual returns (uint256); + + function _getMaxTokens() internal pure virtual returns (uint256); + + function _getMinimumBpt() internal pure virtual returns (uint256) { + return _MINIMUM_BPT; + } + + function getSwapFeePercentage() public view returns (uint256) { + return _miscData.decodeUint64(_SWAP_FEE_PERCENTAGE_OFFSET); + } + + function setSwapFeePercentage(uint256 swapFeePercentage) external virtual authenticate whenNotPaused { + _setSwapFeePercentage(swapFeePercentage); + } + + function _setSwapFeePercentage(uint256 swapFeePercentage) private { + _require(swapFeePercentage >= _MIN_SWAP_FEE_PERCENTAGE, Errors.MIN_SWAP_FEE_PERCENTAGE); + _require(swapFeePercentage <= _MAX_SWAP_FEE_PERCENTAGE, Errors.MAX_SWAP_FEE_PERCENTAGE); + + _miscData = _miscData.insertUint64(swapFeePercentage, _SWAP_FEE_PERCENTAGE_OFFSET); + emit SwapFeePercentageChanged(swapFeePercentage); + } + + function setAssetManagerPoolConfig(IERC20 token, bytes memory poolConfig) + public + virtual + authenticate + whenNotPaused + { + _setAssetManagerPoolConfig(token, poolConfig); + } + + function _setAssetManagerPoolConfig(IERC20 token, bytes memory poolConfig) private { + bytes32 poolId = getPoolId(); + (, , , address assetManager) = getVault().getPoolTokenInfo(poolId, token); + + IAssetManager(assetManager).setConfig(poolId, poolConfig); + } + + function setPaused(bool paused) external authenticate { + _setPaused(paused); + } + + function _isOwnerOnlyAction(bytes32 actionId) internal view virtual override returns (bool) { + return + (actionId == getActionId(this.setSwapFeePercentage.selector)) || + (actionId == getActionId(this.setAssetManagerPoolConfig.selector)); + } + + function _getMiscData() internal view returns (bytes32) { + return _miscData; + } + + /** + * Inserts data into the least-significant 192 bits of the misc data storage slot. + * Note that the remaining 64 bits are used for the swap fee percentage and cannot be overloaded. + */ + function _setMiscData(bytes32 newData) internal { + _miscData = _miscData.insertBits192(newData, 0); + } + + // Join / Exit Hooks + + modifier onlyVault(bytes32 poolId) { + _require(msg.sender == address(getVault()), Errors.CALLER_NOT_VAULT); + _require(poolId == getPoolId(), Errors.INVALID_POOL_ID); + _; + } + + function onJoinPool( + bytes32 poolId, + address sender, + address recipient, + uint256[] memory balances, + uint256 lastChangeBlock, + uint256 protocolSwapFeePercentage, + bytes memory userData + ) public virtual override onlyVault(poolId) returns (uint256[] memory, uint256[] memory) { + uint256[] memory scalingFactors = _scalingFactors(); + + if (totalSupply() == 0) { + (uint256 bptAmountOut, uint256[] memory amountsIn) = _onInitializePool( + poolId, + sender, + recipient, + scalingFactors, + userData + ); + + // On initialization, we lock _getMinimumBpt() by minting it for the zero address. This BPT acts as a + // minimum as it will never be burned, which reduces potential issues with rounding, and also prevents the + // Pool from ever being fully drained. + _require(bptAmountOut >= _getMinimumBpt(), Errors.MINIMUM_BPT); + _mintPoolTokens(address(0), _getMinimumBpt()); + _mintPoolTokens(recipient, bptAmountOut - _getMinimumBpt()); + + // amountsIn are amounts entering the Pool, so we round up. + _downscaleUpArray(amountsIn, scalingFactors); + + return (amountsIn, new uint256[](_getTotalTokens())); + } else { + _upscaleArray(balances, scalingFactors); + (uint256 bptAmountOut, uint256[] memory amountsIn, uint256[] memory dueProtocolFeeAmounts) = _onJoinPool( + poolId, + sender, + recipient, + balances, + lastChangeBlock, + protocolSwapFeePercentage, + scalingFactors, + userData + ); + + // Note we no longer use `balances` after calling `_onJoinPool`, which may mutate it. + + _mintPoolTokens(recipient, bptAmountOut); + + // amountsIn are amounts entering the Pool, so we round up. + _downscaleUpArray(amountsIn, scalingFactors); + // dueProtocolFeeAmounts are amounts exiting the Pool, so we round down. + _downscaleDownArray(dueProtocolFeeAmounts, scalingFactors); + + return (amountsIn, dueProtocolFeeAmounts); + } + } + + function onExitPool( + bytes32 poolId, + address sender, + address recipient, + uint256[] memory balances, + uint256 lastChangeBlock, + uint256 protocolSwapFeePercentage, + bytes memory userData + ) public virtual override onlyVault(poolId) returns (uint256[] memory, uint256[] memory) { + uint256[] memory scalingFactors = _scalingFactors(); + _upscaleArray(balances, scalingFactors); + + (uint256 bptAmountIn, uint256[] memory amountsOut, uint256[] memory dueProtocolFeeAmounts) = _onExitPool( + poolId, + sender, + recipient, + balances, + lastChangeBlock, + protocolSwapFeePercentage, + scalingFactors, + userData + ); + + // Note we no longer use `balances` after calling `_onExitPool`, which may mutate it. + + _burnPoolTokens(sender, bptAmountIn); + + // Both amountsOut and dueProtocolFeeAmounts are amounts exiting the Pool, so we round down. + _downscaleDownArray(amountsOut, scalingFactors); + _downscaleDownArray(dueProtocolFeeAmounts, scalingFactors); + + return (amountsOut, dueProtocolFeeAmounts); + } + + // Query functions + + /** + * @dev Returns the amount of BPT that would be granted to `recipient` if the `onJoinPool` hook were called by the + * Vault with the same arguments, along with the number of tokens `sender` would have to supply. + * + * This function is not meant to be called directly, but rather from a helper contract that fetches current Vault + * data, such as the protocol swap fee percentage and Pool balances. + * + * Like `IVault.queryBatchSwap`, this function is not view due to internal implementation details: the caller must + * explicitly use eth_call instead of eth_sendTransaction. + */ + function queryJoin( + bytes32 poolId, + address sender, + address recipient, + uint256[] memory balances, + uint256 lastChangeBlock, + uint256 protocolSwapFeePercentage, + bytes memory userData + ) external returns (uint256 bptOut, uint256[] memory amountsIn) { + InputHelpers.ensureInputLengthMatch(balances.length, _getTotalTokens()); + + _queryAction( + poolId, + sender, + recipient, + balances, + lastChangeBlock, + protocolSwapFeePercentage, + userData, + _onJoinPool, + _downscaleUpArray + ); + + // The `return` opcode is executed directly inside `_queryAction`, so execution never reaches this statement, + // and we don't need to return anything here - it just silences compiler warnings. + return (bptOut, amountsIn); + } + + /** + * @dev Returns the amount of BPT that would be burned from `sender` if the `onExitPool` hook were called by the + * Vault with the same arguments, along with the number of tokens `recipient` would receive. + * + * This function is not meant to be called directly, but rather from a helper contract that fetches current Vault + * data, such as the protocol swap fee percentage and Pool balances. + * + * Like `IVault.queryBatchSwap`, this function is not view due to internal implementation details: the caller must + * explicitly use eth_call instead of eth_sendTransaction. + */ + function queryExit( + bytes32 poolId, + address sender, + address recipient, + uint256[] memory balances, + uint256 lastChangeBlock, + uint256 protocolSwapFeePercentage, + bytes memory userData + ) external returns (uint256 bptIn, uint256[] memory amountsOut) { + InputHelpers.ensureInputLengthMatch(balances.length, _getTotalTokens()); + + _queryAction( + poolId, + sender, + recipient, + balances, + lastChangeBlock, + protocolSwapFeePercentage, + userData, + _onExitPool, + _downscaleDownArray + ); + + // The `return` opcode is executed directly inside `_queryAction`, so execution never reaches this statement, + // and we don't need to return anything here - it just silences compiler warnings. + return (bptIn, amountsOut); + } + + // Internal hooks to be overridden by derived contracts - all token amounts (except BPT) in these interfaces are + // upscaled. + + /** + * @dev Called when the Pool is joined for the first time; that is, when the BPT total supply is zero. + * + * Returns the amount of BPT to mint, and the token amounts the Pool will receive in return. + * + * Minted BPT will be sent to `recipient`, except for _getMinimumBpt(), which will be deducted from this amount and + * sent to the zero address instead. This will cause that BPT to remain forever locked there, preventing total BTP + * from ever dropping below that value, and ensuring `_onInitializePool` can only be called once in the entire + * Pool's lifetime. + * + * The tokens granted to the Pool will be transferred from `sender`. These amounts are considered upscaled and will + * be downscaled (rounding up) before being returned to the Vault. + */ + function _onInitializePool( + bytes32 poolId, + address sender, + address recipient, + uint256[] memory scalingFactors, + bytes memory userData + ) internal virtual returns (uint256 bptAmountOut, uint256[] memory amountsIn); + + /** + * @dev Called whenever the Pool is joined after the first initialization join (see `_onInitializePool`). + * + * Returns the amount of BPT to mint, the token amounts that the Pool will receive in return, and the number of + * tokens to pay in protocol swap fees. + * + * Implementations of this function might choose to mutate the `balances` array to save gas (e.g. when + * performing intermediate calculations, such as subtraction of due protocol fees). This can be done safely. + * + * Minted BPT will be sent to `recipient`. + * + * The tokens granted to the Pool will be transferred from `sender`. These amounts are considered upscaled and will + * be downscaled (rounding up) before being returned to the Vault. + * + * Due protocol swap fees will be taken from the Pool's balance in the Vault (see `IBasePool.onJoinPool`). These + * amounts are considered upscaled and will be downscaled (rounding down) before being returned to the Vault. + */ + function _onJoinPool( + bytes32 poolId, + address sender, + address recipient, + uint256[] memory balances, + uint256 lastChangeBlock, + uint256 protocolSwapFeePercentage, + uint256[] memory scalingFactors, + bytes memory userData + ) + internal + virtual + returns ( + uint256 bptAmountOut, + uint256[] memory amountsIn, + uint256[] memory dueProtocolFeeAmounts + ); + + /** + * @dev Called whenever the Pool is exited. + * + * Returns the amount of BPT to burn, the token amounts for each Pool token that the Pool will grant in return, and + * the number of tokens to pay in protocol swap fees. + * + * Implementations of this function might choose to mutate the `balances` array to save gas (e.g. when + * performing intermediate calculations, such as subtraction of due protocol fees). This can be done safely. + * + * BPT will be burnt from `sender`. + * + * The Pool will grant tokens to `recipient`. These amounts are considered upscaled and will be downscaled + * (rounding down) before being returned to the Vault. + * + * Due protocol swap fees will be taken from the Pool's balance in the Vault (see `IBasePool.onExitPool`). These + * amounts are considered upscaled and will be downscaled (rounding down) before being returned to the Vault. + */ + function _onExitPool( + bytes32 poolId, + address sender, + address recipient, + uint256[] memory balances, + uint256 lastChangeBlock, + uint256 protocolSwapFeePercentage, + uint256[] memory scalingFactors, + bytes memory userData + ) + internal + virtual + returns ( + uint256 bptAmountIn, + uint256[] memory amountsOut, + uint256[] memory dueProtocolFeeAmounts + ); + + // Internal functions + + /** + * @dev Adds swap fee amount to `amount`, returning a higher value. + */ + function _addSwapFeeAmount(uint256 amount) internal view returns (uint256) { + // This returns amount + fee amount, so we round up (favoring a higher fee amount). + return amount.divUp(FixedPoint.ONE.sub(getSwapFeePercentage())); + } + + /** + * @dev Subtracts swap fee amount from `amount`, returning a lower value. + */ + function _subtractSwapFeeAmount(uint256 amount) internal view returns (uint256) { + // This returns amount - fee amount, so we round up (favoring a higher fee amount). + uint256 feeAmount = amount.mulUp(getSwapFeePercentage()); + return amount.sub(feeAmount); + } + + // Scaling + + /** + * @dev Returns a scaling factor that, when multiplied to a token amount for `token`, normalizes its balance as if + * it had 18 decimals. + */ + function _computeScalingFactor(IERC20 token) internal view returns (uint256) { + // Tokens that don't implement the `decimals` method are not supported. + uint256 tokenDecimals = ERC20(address(token)).decimals(); + + // Tokens with more than 18 decimals are not supported. + uint256 decimalsDifference = Math.sub(18, tokenDecimals); + return FixedPoint.ONE * 10**decimalsDifference; + } + + /** + * @dev Returns the scaling factor for one of the Pool's tokens. Reverts if `token` is not a token registered by the + * Pool. + * + * All scaling factors are fixed-point values with 18 decimals, to allow for this function to be overridden by + * derived contracts that need to apply further scaling, making these factors potentially non-integer. + * + * The largest 'base' scaling factor (i.e. in tokens with less than 18 decimals) is 10**18, which in fixed-point is + * 10**36. This value can be multiplied with a 112 bit Vault balance with no overflow by a factor of ~1e7, making + * even relatively 'large' factors safe to use. + * + * The 1e7 figure is the result of 2**256 / (1e18 * 1e18 * 2**112). + */ + function _scalingFactor(IERC20 token) internal view virtual returns (uint256); + + /** + * @dev Same as `_scalingFactor()`, except for all registered tokens (in the same order as registered). The Vault + * will always pass balances in this order when calling any of the Pool hooks. + */ + function _scalingFactors() internal view virtual returns (uint256[] memory); + + function getScalingFactors() external view returns (uint256[] memory) { + return _scalingFactors(); + } + + /** + * @dev Applies `scalingFactor` to `amount`, resulting in a larger or equal value depending on whether it needed + * scaling or not. + */ + function _upscale(uint256 amount, uint256 scalingFactor) internal pure returns (uint256) { + // Upscale rounding wouldn't necessarily always go in the same direction: in a swap for example the balance of + // token in should be rounded up, and that of token out rounded down. This is the only place where we round in + // the same direction for all amounts, as the impact of this rounding is expected to be minimal (and there's no + // rounding error unless `_scalingFactor()` is overriden). + return FixedPoint.mulDown(amount, scalingFactor); + } + + /** + * @dev Same as `_upscale`, but for an entire array. This function does not return anything, but instead *mutates* + * the `amounts` array. + */ + function _upscaleArray(uint256[] memory amounts, uint256[] memory scalingFactors) internal view { + for (uint256 i = 0; i < _getTotalTokens(); ++i) { + amounts[i] = FixedPoint.mulDown(amounts[i], scalingFactors[i]); + } + } + + /** + * @dev Reverses the `scalingFactor` applied to `amount`, resulting in a smaller or equal value depending on + * whether it needed scaling or not. The result is rounded down. + */ + function _downscaleDown(uint256 amount, uint256 scalingFactor) internal pure returns (uint256) { + return FixedPoint.divDown(amount, scalingFactor); + } + + /** + * @dev Same as `_downscaleDown`, but for an entire array. This function does not return anything, but instead + * *mutates* the `amounts` array. + */ + function _downscaleDownArray(uint256[] memory amounts, uint256[] memory scalingFactors) internal view { + for (uint256 i = 0; i < _getTotalTokens(); ++i) { + amounts[i] = FixedPoint.divDown(amounts[i], scalingFactors[i]); + } + } + + /** + * @dev Reverses the `scalingFactor` applied to `amount`, resulting in a smaller or equal value depending on + * whether it needed scaling or not. The result is rounded up. + */ + function _downscaleUp(uint256 amount, uint256 scalingFactor) internal pure returns (uint256) { + return FixedPoint.divUp(amount, scalingFactor); + } + + /** + * @dev Same as `_downscaleUp`, but for an entire array. This function does not return anything, but instead + * *mutates* the `amounts` array. + */ + function _downscaleUpArray(uint256[] memory amounts, uint256[] memory scalingFactors) internal view { + for (uint256 i = 0; i < _getTotalTokens(); ++i) { + amounts[i] = FixedPoint.divUp(amounts[i], scalingFactors[i]); + } + } + + function _getAuthorizer() internal view override returns (IAuthorizer) { + // Access control management is delegated to the Vault's Authorizer. This lets Balancer Governance manage which + // accounts can call permissioned functions: for example, to perform emergency pauses. + // If the owner is delegated, then *all* permissioned functions, including `setSwapFeePercentage`, will be under + // Governance control. + return getVault().getAuthorizer(); + } + + function _queryAction( + bytes32 poolId, + address sender, + address recipient, + uint256[] memory balances, + uint256 lastChangeBlock, + uint256 protocolSwapFeePercentage, + bytes memory userData, + function(bytes32, address, address, uint256[] memory, uint256, uint256, uint256[] memory, bytes memory) + internal + returns (uint256, uint256[] memory, uint256[] memory) _action, + function(uint256[] memory, uint256[] memory) internal view _downscaleArray + ) private { + // This uses the same technique used by the Vault in queryBatchSwap. Refer to that function for a detailed + // explanation. + + if (msg.sender != address(this)) { + // We perform an external call to ourselves, forwarding the same calldata. In this call, the else clause of + // the preceding if statement will be executed instead. + + // solhint-disable-next-line avoid-low-level-calls + (bool success, ) = address(this).call(msg.data); + + // solhint-disable-next-line no-inline-assembly + assembly { + // This call should always revert to decode the bpt and token amounts from the revert reason + switch success + case 0 { + // Note we are manually writing the memory slot 0. We can safely overwrite whatever is + // stored there as we take full control of the execution and then immediately return. + + // We copy the first 4 bytes to check if it matches with the expected signature, otherwise + // there was another revert reason and we should forward it. + returndatacopy(0, 0, 0x04) + let error := and(mload(0), 0xffffffff00000000000000000000000000000000000000000000000000000000) + + // If the first 4 bytes don't match with the expected signature, we forward the revert reason. + if eq(eq(error, 0x43adbafb00000000000000000000000000000000000000000000000000000000), 0) { + returndatacopy(0, 0, returndatasize()) + revert(0, returndatasize()) + } + + // The returndata contains the signature, followed by the raw memory representation of the + // `bptAmount` and `tokenAmounts` (array: length + data). We need to return an ABI-encoded + // representation of these. + // An ABI-encoded response will include one additional field to indicate the starting offset of + // the `tokenAmounts` array. The `bptAmount` will be laid out in the first word of the + // returndata. + // + // In returndata: + // [ signature ][ bptAmount ][ tokenAmounts length ][ tokenAmounts values ] + // [ 4 bytes ][ 32 bytes ][ 32 bytes ][ (32 * length) bytes ] + // + // We now need to return (ABI-encoded values): + // [ bptAmount ][ tokeAmounts offset ][ tokenAmounts length ][ tokenAmounts values ] + // [ 32 bytes ][ 32 bytes ][ 32 bytes ][ (32 * length) bytes ] + + // We copy 32 bytes for the `bptAmount` from returndata into memory. + // Note that we skip the first 4 bytes for the error signature + returndatacopy(0, 0x04, 32) + + // The offsets are 32-bytes long, so the array of `tokenAmounts` will start after + // the initial 64 bytes. + mstore(0x20, 64) + + // We now copy the raw memory array for the `tokenAmounts` from returndata into memory. + // Since bpt amount and offset take up 64 bytes, we start copying at address 0x40. We also + // skip the first 36 bytes from returndata, which correspond to the signature plus bpt amount. + returndatacopy(0x40, 0x24, sub(returndatasize(), 36)) + + // We finally return the ABI-encoded uint256 and the array, which has a total length equal to + // the size of returndata, plus the 32 bytes of the offset but without the 4 bytes of the + // error signature. + return(0, add(returndatasize(), 28)) + } + default { + // This call should always revert, but we fail nonetheless if that didn't happen + invalid() + } + } + } else { + uint256[] memory scalingFactors = _scalingFactors(); + _upscaleArray(balances, scalingFactors); + + (uint256 bptAmount, uint256[] memory tokenAmounts, ) = _action( + poolId, + sender, + recipient, + balances, + lastChangeBlock, + protocolSwapFeePercentage, + scalingFactors, + userData + ); + + _downscaleArray(tokenAmounts, scalingFactors); + + // solhint-disable-next-line no-inline-assembly + assembly { + // We will return a raw representation of `bptAmount` and `tokenAmounts` in memory, which is composed of + // a 32-byte uint256, followed by a 32-byte for the array length, and finally the 32-byte uint256 values + // Because revert expects a size in bytes, we multiply the array length (stored at `tokenAmounts`) by 32 + let size := mul(mload(tokenAmounts), 32) + + // We store the `bptAmount` in the previous slot to the `tokenAmounts` array. We can make sure there + // will be at least one available slot due to how the memory scratch space works. + // We can safely overwrite whatever is stored in this slot as we will revert immediately after that. + let start := sub(tokenAmounts, 0x20) + mstore(start, bptAmount) + + // We send one extra value for the error signature "QueryError(uint256,uint256[])" which is 0x43adbafb + // We use the previous slot to `bptAmount`. + mstore(sub(start, 0x20), 0x0000000000000000000000000000000000000000000000000000000043adbafb) + start := sub(start, 0x04) + + // When copying from `tokenAmounts` into returndata, we copy the additional 68 bytes to also return + // the `bptAmount`, the array 's length, and the error signature. + revert(start, add(size, 68)) + } + } + } +} \ No newline at end of file From c897252c3b01c33ff3ea79d73404f6beefe385b3 Mon Sep 17 00:00:00 2001 From: ncitron Date: Sat, 11 Sep 2021 02:51:51 -0400 Subject: [PATCH 9/9] fix fixture tests --- test/fixtures/balancerV2.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/fixtures/balancerV2.spec.ts b/test/fixtures/balancerV2.spec.ts index d1dc470e2..b04a7f9be 100644 --- a/test/fixtures/balancerV2.spec.ts +++ b/test/fixtures/balancerV2.spec.ts @@ -36,7 +36,7 @@ describe("BalancerFixture", () => { describe("#initialize", async () => { async function subject(): Promise { - await balancerSetup.initialize(owner, setup.weth, setup.dai); + await balancerSetup.initialize(owner, setup.weth, setup.wbtc, setup.dai); } it("should deploy core balancer V2 contacts", async () => { @@ -58,7 +58,7 @@ describe("BalancerFixture", () => { let subjectWeights: BigNumber[]; beforeEach(async () => { - await balancerSetup.initialize(owner, setup.weth, setup.dai); + await balancerSetup.initialize(owner, setup.weth, setup.wbtc, setup.dai); subjectTokens = [setup.wbtc.address, setup.weth.address]; subjectWeights = [ether(0.3), ether(0.7)];