Feature Tip: Add private address tag to any address under My Name Tag !
Overview
Max Total Supply
106,737.306755841744386599 PIPT
Holders
739 (0.00%)
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
0 PIPTValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
PowerIndexPool
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 2 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
/* https://powerpool.finance/ wrrrw r wrr ppwr rrr wppr0 prwwwrp prwwwrp wr0 rr 0rrrwrrprpwp0 pp pr prrrr0 pp 0r prrrr0 0rwrrr pp pr prrrr0 prrrr0 r0 rrp pr wr00rrp prwww0 pp wr pp w00r prwwwpr 0rw prwww0 pp wr pp wr r0 r0rprprwrrrp pr0 pp wr pr pp rwwr wr 0r pp wr pr wr pr r0 prwr wrr0wpwr 00 www0 0w0ww www0 0w 00 www0 www0 0www0 wrr ww0rrrr */ // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; import "./balancer-core/BPool.sol"; import "./interfaces/PowerIndexPoolInterface.sol"; contract PowerIndexPool is BPool { /// @notice The event emitted when a dynamic weight set to token event SetDynamicWeight( address indexed token, uint256 fromDenorm, uint256 targetDenorm, uint256 fromTimestamp, uint256 targetTimestamp ); /// @notice The event emitted when weight per second bounds set event SetWeightPerSecondBounds(uint256 minWeightPerSecond, uint256 maxWeightPerSecond); struct DynamicWeight { uint256 fromTimestamp; uint256 targetTimestamp; uint256 targetDenorm; } /// @dev Mapping for storing dynamic weights settings. fromDenorm stored in _records mapping as denorm variable mapping(address => DynamicWeight) private _dynamicWeights; /// @dev Min weight per second limit uint256 private _minWeightPerSecond; /// @dev Max weight per second limit uint256 private _maxWeightPerSecond; constructor( string memory name, string memory symbol, uint256 minWeightPerSecond, uint256 maxWeightPerSecond ) public BPool(name, symbol) { _minWeightPerSecond = minWeightPerSecond; _maxWeightPerSecond = maxWeightPerSecond; } /*** Controller Interface ***/ /** * @notice Set weight per second bounds by controller * @param minWeightPerSecond Min weight per second * @param maxWeightPerSecond Max weight per second */ function setWeightPerSecondBounds(uint256 minWeightPerSecond, uint256 maxWeightPerSecond) public _logs_ _lock_ { _onlyController(); _minWeightPerSecond = minWeightPerSecond; _maxWeightPerSecond = maxWeightPerSecond; emit SetWeightPerSecondBounds(minWeightPerSecond, maxWeightPerSecond); } /** * @notice Set dynamic weight for token by controller * @param token Token for change settings * @param targetDenorm Target weight. fromDenorm will be fetch by current value of _getDenormWeight * @param fromTimestamp From timestamp of dynamic weight * @param targetTimestamp Target timestamp of dynamic weight */ function setDynamicWeight( address token, uint256 targetDenorm, uint256 fromTimestamp, uint256 targetTimestamp ) public _logs_ _lock_ { _onlyController(); _requireTokenIsBound(token); require(fromTimestamp > block.timestamp, "CANT_SET_PAST_TIMESTAMP"); require(targetTimestamp > fromTimestamp, "TIMESTAMP_INCORRECT_DELTA"); require(targetDenorm >= MIN_WEIGHT && targetDenorm <= MAX_WEIGHT, "TARGET_WEIGHT_BOUNDS"); uint256 fromDenorm = _getDenormWeight(token); uint256 weightPerSecond = _getWeightPerSecond(fromDenorm, targetDenorm, fromTimestamp, targetTimestamp); require(weightPerSecond <= _maxWeightPerSecond, "MAX_WEIGHT_PER_SECOND"); require(weightPerSecond >= _minWeightPerSecond, "MIN_WEIGHT_PER_SECOND"); _records[token].denorm = fromDenorm; _dynamicWeights[token] = DynamicWeight({ fromTimestamp: fromTimestamp, targetTimestamp: targetTimestamp, targetDenorm: targetDenorm }); uint256 denormSum = 0; uint256 len = _tokens.length; for (uint256 i = 0; i < len; i++) { denormSum = badd(denormSum, _dynamicWeights[_tokens[i]].targetDenorm); } require(denormSum <= MAX_TOTAL_WEIGHT, "MAX_TARGET_TOTAL_WEIGHT"); emit SetDynamicWeight(token, fromDenorm, targetDenorm, fromTimestamp, targetTimestamp); } /** * @notice Bind and setDynamicWeight at the same time * @param token Token for bind * @param balance Initial balance * @param targetDenorm Target weight * @param fromTimestamp From timestamp of dynamic weight * @param targetTimestamp Target timestamp of dynamic weight */ function bind( address token, uint256 balance, uint256 targetDenorm, uint256 fromTimestamp, uint256 targetTimestamp ) external _logs_ // _lock_ Bind does not lock because it jumps to `rebind` and `setDynamicWeight`, which does { super.bind(token, balance, MIN_WEIGHT); setDynamicWeight(token, targetDenorm, fromTimestamp, targetTimestamp); } /** * @notice Override parent unbind function * @param token Token for unbind */ function unbind(address token) public override { super.unbind(token); _dynamicWeights[token] = DynamicWeight(0, 0, 0); } /** * @notice Override parent bind function and disable. */ function bind( address, uint256, uint256 ) public override { revert("DISABLED"); // Only new bind function is allowed } /** * @notice Override parent rebind function. Allowed only for calling from bind function * @param token Token for rebind * @param balance Balance for rebind * @param denorm Weight for rebind */ function rebind( address token, uint256 balance, uint256 denorm ) public override { require(denorm == MIN_WEIGHT && _dynamicWeights[token].fromTimestamp == 0, "ONLY_NEW_TOKENS_ALLOWED"); super.rebind(token, balance, denorm); } /*** View Functions ***/ function getDynamicWeightSettings(address token) external view returns ( uint256 fromTimestamp, uint256 targetTimestamp, uint256 fromDenorm, uint256 targetDenorm ) { DynamicWeight storage dw = _dynamicWeights[token]; return (dw.fromTimestamp, dw.targetTimestamp, _records[token].denorm, dw.targetDenorm); } function getWeightPerSecondBounds() external view returns (uint256 minWeightPerSecond, uint256 maxWeightPerSecond) { return (_minWeightPerSecond, _maxWeightPerSecond); } /*** Internal Functions ***/ function _getDenormWeight(address token) internal view override returns (uint256) { DynamicWeight memory dw = _dynamicWeights[token]; uint256 fromDenorm = _records[token].denorm; if (dw.fromTimestamp == 0 || dw.targetDenorm == fromDenorm || block.timestamp <= dw.fromTimestamp) { return fromDenorm; } if (block.timestamp >= dw.targetTimestamp) { return dw.targetDenorm; } uint256 weightPerSecond = _getWeightPerSecond(fromDenorm, dw.targetDenorm, dw.fromTimestamp, dw.targetTimestamp); uint256 deltaCurrentTime = bsub(block.timestamp, dw.fromTimestamp); if (dw.targetDenorm > fromDenorm) { return badd(fromDenorm, deltaCurrentTime * weightPerSecond); } else { return bsub(fromDenorm, deltaCurrentTime * weightPerSecond); } } function _getWeightPerSecond( uint256 fromDenorm, uint256 targetDenorm, uint256 fromTimestamp, uint256 targetTimestamp ) internal pure returns (uint256) { uint256 delta = targetDenorm > fromDenorm ? bsub(targetDenorm, fromDenorm) : bsub(fromDenorm, targetDenorm); return div(delta, bsub(targetTimestamp, fromTimestamp)); } function _getTotalWeight() internal view override returns (uint256) { uint256 sum = 0; uint256 len = _tokens.length; for (uint256 i = 0; i < len; i++) { sum = badd(sum, _getDenormWeight(_tokens[i])); } return sum; } function _addTotalWeight(uint256 _amount) internal virtual override { // storage total weight don't change, it's calculated only by _getTotalWeight() } function _subTotalWeight(uint256 _amount) internal virtual override { // storage total weight don't change, it's calculated only by _getTotalWeight() } }
// SPDX-License-Identifier: GPL-3.0 // 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 <http://www.gnu.org/licenses/>. pragma solidity 0.6.12; contract BConst { uint public constant BONE = 10**18; uint public constant MIN_BOUND_TOKENS = 2; uint public constant MAX_BOUND_TOKENS = 9; uint public constant MIN_FEE = BONE / 10**6; uint public constant MAX_FEE = BONE / 10; uint public constant MIN_WEIGHT = 1000000000; uint public constant MAX_WEIGHT = BONE * 50; uint public constant MAX_TOTAL_WEIGHT = BONE * 50; uint public constant MIN_BALANCE = BONE / 10**12; uint public constant INIT_POOL_SUPPLY = BONE * 100; uint public constant MIN_BPOW_BASE = 1 wei; uint public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei; uint public constant BPOW_PRECISION = BONE / 10**10; uint public constant MAX_IN_RATIO = BONE / 2; uint public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei; }
// SPDX-License-Identifier: GPL-3.0 // 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 <http://www.gnu.org/licenses/>. pragma solidity 0.6.12; import "./BConst.sol"; contract BNum is BConst { function btoi(uint a) internal pure returns (uint) { return a / BONE; } function bfloor(uint a) internal pure returns (uint) { return btoi(a) * BONE; } function badd(uint a, uint b) internal pure returns (uint) { uint c = a + b; require(c >= a, "ERR_ADD_OVERFLOW"); return c; } function bsub(uint a, uint b) internal pure returns (uint) { (uint c, bool flag) = bsubSign(a, b); require(!flag, "ERR_SUB_UNDERFLOW"); return c; } function bsubSign(uint a, uint b) internal pure returns (uint, bool) { if (a >= b) { return (a - b, false); } else { return (b - a, true); } } function bmul(uint a, uint b) internal pure returns (uint) { uint c0 = a * b; require(a == 0 || c0 / a == b, "ERR_MUL_OVERFLOW"); uint c1 = c0 + (BONE / 2); require(c1 >= c0, "ERR_MUL_OVERFLOW"); uint c2 = c1 / BONE; return c2; } function bdiv(uint a, uint b) internal pure returns (uint) { require(b != 0, "ERR_DIV_ZERO"); uint c0 = a * BONE; require(a == 0 || c0 / a == BONE, "ERR_DIV_INTERNAL"); // bmul overflow uint c1 = c0 + (b / 2); require(c1 >= c0, "ERR_DIV_INTERNAL"); // badd require uint c2 = c1 / b; return c2; } function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "ERR_DIV_ZERO"); return a / b; } // DSMath.wpow function bpowi(uint a, uint n) internal pure returns (uint) { uint z = n % 2 != 0 ? a : BONE; for (n /= 2; n != 0; n /= 2) { a = bmul(a, a); if (n % 2 != 0) { z = bmul(z, a); } } return z; } // Compute b^(e.w) by splitting it into (b^e)*(b^0.w). // Use `bpowi` for `b^e` and `bpowK` for k iterations // of approximation of b^0.w function bpow(uint base, uint exp) internal pure returns (uint) { require(base >= MIN_BPOW_BASE, "ERR_BPOW_BASE_TOO_LOW"); require(base <= MAX_BPOW_BASE, "ERR_BPOW_BASE_TOO_HIGH"); uint whole = bfloor(exp); uint remain = bsub(exp, whole); uint wholePow = bpowi(base, btoi(whole)); if (remain == 0) { return wholePow; } uint partialResult = bpowApprox(base, remain, BPOW_PRECISION); return bmul(wholePow, partialResult); } function bpowApprox(uint base, uint exp, uint precision) internal pure returns (uint) { // term 0: uint a = exp; (uint x, bool xneg) = bsubSign(base, BONE); uint term = BONE; uint sum = term; bool negative = false; // term(k) = numer / denom // = (product(a - i - 1, i=1-->k) * x^k) / (k!) // each iteration, multiply previous term by (a-(k-1)) * x / k // continue until term is less than precision for (uint i = 1; term >= precision; i++) { uint bigK = i * BONE; (uint c, bool cneg) = bsubSign(a, bsub(bigK, BONE)); term = bmul(term, bmul(c, x)); term = bdiv(term, bigK); if (term == 0) break; if (xneg) negative = !negative; if (cneg) negative = !negative; if (negative) { sum = bsub(sum, term); } else { sum = badd(sum, term); } } return sum; } }
// SPDX-License-Identifier: GPL-3.0 // 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 <http://www.gnu.org/licenses/>. pragma solidity 0.6.12; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./BNum.sol"; contract BTokenBase is BNum { mapping(address => uint) internal _balance; mapping(address => mapping(address=>uint)) internal _allowance; uint internal _totalSupply; event Approval(address indexed src, address indexed dst, uint amt); event Transfer(address indexed src, address indexed dst, uint amt); function _mint(uint amt) internal { _balance[address(this)] = badd(_balance[address(this)], amt); _totalSupply = badd(_totalSupply, amt); emit Transfer(address(0), address(this), amt); } function _burn(uint amt) internal { require(_balance[address(this)] >= amt, "ERR_INSUFFICIENT_BAL"); _balance[address(this)] = bsub(_balance[address(this)], amt); _totalSupply = bsub(_totalSupply, amt); emit Transfer(address(this), address(0), amt); } function _move(address src, address dst, uint amt) internal { require(_balance[src] >= amt, "ERR_INSUFFICIENT_BAL"); _validateAddress(src); _validateAddress(dst); _balance[src] = bsub(_balance[src], amt); _balance[dst] = badd(_balance[dst], amt); emit Transfer(src, dst, amt); } function _push(address to, uint amt) internal { _move(address(this), to, amt); } function _pull(address from, uint amt) internal { _move(from, address(this), amt); } function _validateAddress(address addr) internal { require(addr != address(0), "ERR_NULL_ADDRESS"); } } contract BToken is BTokenBase, IERC20 { string internal _name; string internal _symbol; uint8 private _decimals = 18; function name() public view returns (string memory) { return _name; } function symbol() public view returns (string memory) { return _symbol; } function decimals() public view returns(uint8) { return _decimals; } function allowance(address src, address dst) external override view returns (uint) { return _allowance[src][dst]; } function balanceOf(address whom) external override view returns (uint) { return _balance[whom]; } function totalSupply() public override view returns (uint) { return _totalSupply; } function approve(address dst, uint amt) external override returns (bool) { _validateAddress(dst); _allowance[msg.sender][dst] = amt; emit Approval(msg.sender, dst, amt); return true; } function increaseApproval(address dst, uint amt) external returns (bool) { _validateAddress(dst); _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt); emit Approval(msg.sender, dst, _allowance[msg.sender][dst]); return true; } function decreaseApproval(address dst, uint amt) external returns (bool) { _validateAddress(dst); uint oldValue = _allowance[msg.sender][dst]; if (amt > oldValue) { _allowance[msg.sender][dst] = 0; } else { _allowance[msg.sender][dst] = bsub(oldValue, amt); } emit Approval(msg.sender, dst, _allowance[msg.sender][dst]); return true; } function transfer(address dst, uint amt) external override returns (bool) { _move(msg.sender, dst, amt); return true; } function transferFrom(address src, address dst, uint amt) external override returns (bool) { require(msg.sender == src || amt <= _allowance[src][msg.sender], "ERR_BTOKEN_BAD_CALLER"); _move(src, dst, amt); if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) { _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt); emit Approval(src, msg.sender, _allowance[src][msg.sender]); } return true; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./BMathInterface.sol"; interface BPoolInterface is IERC20, BMathInterface { function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external; function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external; function swapExactAmountIn( address, uint256, address, uint256, uint256 ) external returns (uint256, uint256); function swapExactAmountOut( address, uint256, address, uint256, uint256 ) external returns (uint256, uint256); function joinswapExternAmountIn( address, uint256, uint256 ) external returns (uint256); function joinswapPoolAmountOut( address, uint256, uint256 ) external returns (uint256); function exitswapPoolAmountIn( address, uint256, uint256 ) external returns (uint256); function exitswapExternAmountOut( address, uint256, uint256 ) external returns (uint256); function getDenormalizedWeight(address) external view returns (uint256); function getBalance(address) external view returns (uint256); function getSwapFee() external view returns (uint256); function getTotalDenormalizedWeight() external view returns (uint256); function getCommunityFee() external view returns ( uint256, uint256, uint256, address ); function calcAmountWithCommunityFee( uint256, uint256, address ) external view returns (uint256, uint256); function getRestrictions() external view returns (address); function isPublicSwap() external view returns (bool); function isFinalized() external view returns (bool); function isBound(address t) external view returns (bool); function getCurrentTokens() external view returns (address[] memory tokens); function getFinalTokens() external view returns (address[] memory tokens); function setSwapFee(uint256) external; function setCommunityFeeAndReceiver( uint256, uint256, uint256, address ) external; function setController(address) external; function setPublicSwap(bool) external; function finalize() external; function bind( address, uint256, uint256 ) external; function rebind( address, uint256, uint256 ) external; function unbind(address) external; function callVoting( address voting, bytes4 signature, bytes calldata args, uint256 value ) external; function getMinWeight() external view returns (uint256); function getMaxBoundTokens() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; interface BMathInterface { function calcInGivenOut( uint256 tokenBalanceIn, uint256 tokenWeightIn, uint256 tokenBalanceOut, uint256 tokenWeightOut, uint256 tokenAmountOut, uint256 swapFee ) external pure returns (uint256 tokenAmountIn); }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; import "./BPoolInterface.sol"; interface PowerIndexPoolInterface is BPoolInterface { function bind( address, uint256, uint256, uint256, uint256 ) external; function setDynamicWeight( address token, uint256 targetDenorm, uint256 fromTimestamp, uint256 targetTimestamp ) external; function getDynamicWeightSettings(address token) external view returns ( uint256 fromTimestamp, uint256 targetTimestamp, uint256 fromDenorm, uint256 targetDenorm ); function getMinWeight() external view override returns (uint256); }
// SPDX-License-Identifier: GPL-3.0 // 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 <http://www.gnu.org/licenses/>. pragma solidity 0.6.12; import "./BToken.sol"; import "./BMath.sol"; import "../interfaces/IPoolRestrictions.sol"; import "../interfaces/BPoolInterface.sol"; contract BPool is BToken, BMath, BPoolInterface { struct Record { bool bound; // is token bound to pool uint index; // private uint denorm; // denormalized weight uint balance; } event LOG_SWAP( address indexed caller, address indexed tokenIn, address indexed tokenOut, uint256 tokenAmountIn, uint256 tokenAmountOut ); event LOG_JOIN( address indexed caller, address indexed tokenIn, uint256 tokenAmountIn ); event LOG_EXIT( address indexed caller, address indexed tokenOut, uint256 tokenAmountOut ); event LOG_CALL( bytes4 indexed sig, address indexed caller, bytes data ) anonymous; event LOG_CALL_VOTING( address indexed voting, bool indexed success, bytes4 indexed inputSig, bytes inputData, bytes outputData ); event LOG_COMMUNITY_FEE( address indexed caller, address indexed receiver, address indexed token, uint256 tokenAmount ); modifier _logs_() { emit LOG_CALL(msg.sig, msg.sender, msg.data); _; } modifier _lock_() { _preventReentrancy(); _mutex = true; _; _mutex = false; } modifier _viewlock_() { _preventReentrancy(); _; } bool private _mutex; address private _controller; // has CONTROL role bool private _publicSwap; // true if PUBLIC can call SWAP functions address private _wrapper; // can join, exit and swaps when _wrapperMode is true bool private _wrapperMode; IPoolRestrictions private _restrictions; // `setSwapFee` and `finalize` require CONTROL // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN` uint private _swapFee; uint private _communitySwapFee; uint private _communityJoinFee; uint private _communityExitFee; address private _communityFeeReceiver; bool private _finalized; address[] internal _tokens; mapping(address => Record) internal _records; uint internal _totalWeight; mapping(address => uint256) internal _lastSwapBlock; constructor(string memory name, string memory symbol) public { _name = name; _symbol = symbol; _controller = msg.sender; _swapFee = MIN_FEE; _communitySwapFee = 0; _communityJoinFee = 0; _communityExitFee = 0; _publicSwap = false; _finalized = false; } function isPublicSwap() external view override returns (bool) { return _publicSwap; } function isFinalized() external view override returns (bool) { return _finalized; } function isBound(address t) external view override returns (bool) { return _records[t].bound; } function getNumTokens() external view returns (uint) { return _tokens.length; } function getCurrentTokens() external view override _viewlock_ returns (address[] memory tokens) { return _tokens; } function getFinalTokens() external view override _viewlock_ returns (address[] memory tokens) { _requireContractIsFinalized(); return _tokens; } function getDenormalizedWeight(address token) external view override _viewlock_ returns (uint) { _requireTokenIsBound(token); return _getDenormWeight(token); } function getTotalDenormalizedWeight() external view override _viewlock_ returns (uint) { return _getTotalWeight(); } function getNormalizedWeight(address token) external view _viewlock_ returns (uint) { _requireTokenIsBound(token); return bdiv(_getDenormWeight(token), _getTotalWeight()); } function getBalance(address token) external view override _viewlock_ returns (uint) { _requireTokenIsBound(token); return _records[token].balance; } function getSwapFee() external view override _viewlock_ returns (uint) { return _swapFee; } function getCommunityFee() external view override _viewlock_ returns (uint communitySwapFee, uint communityJoinFee, uint communityExitFee, address communityFeeReceiver) { return (_communitySwapFee, _communityJoinFee, _communityExitFee, _communityFeeReceiver); } function getController() external view _viewlock_ returns (address) { return _controller; } function getWrapper() external view _viewlock_ returns (address) { return _wrapper; } function getWrapperMode() external view _viewlock_ returns (bool) { return _wrapperMode; } function getRestrictions() external view override _viewlock_ returns (address) { return address(_restrictions); } function setSwapFee(uint swapFee) external override _logs_ _lock_ { _onlyController(); _requireFeeInBounds(swapFee); _swapFee = swapFee; } function setCommunityFeeAndReceiver( uint communitySwapFee, uint communityJoinFee, uint communityExitFee, address communityFeeReceiver ) external override _logs_ _lock_ { _onlyController(); _requireFeeInBounds(communitySwapFee); _requireFeeInBounds(communityJoinFee); _requireFeeInBounds(communityExitFee); _communitySwapFee = communitySwapFee; _communityJoinFee = communityJoinFee; _communityExitFee = communityExitFee; _communityFeeReceiver = communityFeeReceiver; } function setRestrictions(IPoolRestrictions restrictions) external _logs_ _lock_ { _onlyController(); _restrictions = restrictions; } function setController(address manager) external override _logs_ _lock_ { _onlyController(); _controller = manager; } function setPublicSwap(bool public_) external override _logs_ _lock_ { _requireContractIsNotFinalized(); _onlyController(); _publicSwap = public_; } function setWrapper(address wrapper, bool wrapperMode) external _logs_ _lock_ { _onlyController(); _wrapper = wrapper; _wrapperMode = wrapperMode; } function finalize() external override _logs_ _lock_ { _onlyController(); _requireContractIsNotFinalized(); require(_tokens.length >= MIN_BOUND_TOKENS, "MIN_TOKENS"); _finalized = true; _publicSwap = true; _mintPoolShare(INIT_POOL_SUPPLY); _pushPoolShare(msg.sender, INIT_POOL_SUPPLY); } function callVoting(address voting, bytes4 signature, bytes calldata args, uint256 value) external override _logs_ _lock_ { require(_restrictions.isVotingSignatureAllowed(voting, signature), "NOT_ALLOWED_SIG"); _onlyController(); (bool success, bytes memory data) = voting.call{ value: value }(abi.encodePacked(signature, args)); require(success, "NOT_SUCCESS"); emit LOG_CALL_VOTING(voting, success, signature, args, data); } function bind(address token, uint balance, uint denorm) public override virtual _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does { _onlyController(); require(!_records[token].bound, "IS_BOUND"); require(_tokens.length < MAX_BOUND_TOKENS, "MAX_TOKENS"); _records[token] = Record({ bound: true, index: _tokens.length, denorm: 0, // balance and denorm will be validated balance: 0 // and set by `rebind` }); _tokens.push(token); rebind(token, balance, denorm); } function rebind(address token, uint balance, uint denorm) public override virtual _logs_ _lock_ { _onlyController(); _requireTokenIsBound(token); require(denorm >= MIN_WEIGHT && denorm <= MAX_WEIGHT, "WEIGHT_BOUNDS"); require(balance >= MIN_BALANCE, "MIN_BALANCE"); // Adjust the denorm and totalWeight uint oldWeight = _records[token].denorm; if (denorm > oldWeight) { _addTotalWeight(bsub(denorm, oldWeight)); } else if (denorm < oldWeight) { _subTotalWeight(bsub(oldWeight, denorm)); } _records[token].denorm = denorm; // Adjust the balance record and actual token balance uint oldBalance = _records[token].balance; _records[token].balance = balance; if (balance > oldBalance) { _pullUnderlying(token, msg.sender, bsub(balance, oldBalance)); } else if (balance < oldBalance) { uint tokenBalanceWithdrawn = bsub(oldBalance, balance); _pushUnderlying(token, msg.sender, tokenBalanceWithdrawn); } } function unbind(address token) public override virtual _logs_ _lock_ { _onlyController(); _requireTokenIsBound(token); uint tokenBalance = _records[token].balance; _subTotalWeight(_records[token].denorm); // Swap the token-to-unbind with the last token, // then delete the last token uint index = _records[token].index; uint last = _tokens.length - 1; _tokens[index] = _tokens[last]; _records[_tokens[index]].index = index; _tokens.pop(); _records[token] = Record({ bound: false, index: 0, denorm: 0, balance: 0 }); _pushUnderlying(token, msg.sender, tokenBalance); } // Absorb any tokens that have been sent to this contract into the pool function gulp(address token) external _logs_ _lock_ { _requireTokenIsBound(token); _records[token].balance = IERC20(token).balanceOf(address(this)); } function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint spotPrice) { require(_records[tokenIn].bound && _records[tokenOut].bound, "NOT_BOUND"); Record storage inRecord = _records[tokenIn]; Record storage outRecord = _records[tokenOut]; return calcSpotPrice(inRecord.balance, _getDenormWeight(tokenIn), outRecord.balance, _getDenormWeight(tokenOut), _swapFee); } function getSpotPriceSansFee(address tokenIn, address tokenOut) external view _viewlock_ returns (uint spotPrice) { _requireTokenIsBound(tokenIn); _requireTokenIsBound(tokenOut); Record storage inRecord = _records[tokenIn]; Record storage outRecord = _records[tokenOut]; return calcSpotPrice(inRecord.balance, _getDenormWeight(tokenIn), outRecord.balance, _getDenormWeight(tokenOut), 0); } function joinPool(uint poolAmountOut, uint[] calldata maxAmountsIn) external override _logs_ _lock_ { _preventSameTxOrigin(); _onlyWrapperOrNotWrapperMode(); _requireContractIsFinalized(); uint poolTotal = totalSupply(); uint ratio = bdiv(poolAmountOut, poolTotal); _requireMathApprox(ratio); for (uint i = 0; i < _tokens.length; i++) { address t = _tokens[i]; uint bal = _records[t].balance; uint tokenAmountIn = bmul(ratio, bal); _requireMathApprox(tokenAmountIn); require(tokenAmountIn <= maxAmountsIn[i], "LIMIT_IN"); _records[t].balance = badd(_records[t].balance, tokenAmountIn); emit LOG_JOIN(msg.sender, t, tokenAmountIn); _pullUnderlying(t, msg.sender, tokenAmountIn); } (uint poolAmountOutAfterFee, uint poolAmountOutFee) = calcAmountWithCommunityFee( poolAmountOut, _communityJoinFee, msg.sender ); _mintPoolShare(poolAmountOut); _pushPoolShare(msg.sender, poolAmountOutAfterFee); _pushPoolShare(_communityFeeReceiver, poolAmountOutFee); emit LOG_COMMUNITY_FEE(msg.sender, _communityFeeReceiver, address(this), poolAmountOutFee); } function exitPool(uint poolAmountIn, uint[] calldata minAmountsOut) external override _logs_ _lock_ { _preventSameTxOrigin(); _onlyWrapperOrNotWrapperMode(); _requireContractIsFinalized(); (uint poolAmountInAfterFee, uint poolAmountInFee) = calcAmountWithCommunityFee( poolAmountIn, _communityExitFee, msg.sender ); uint poolTotal = totalSupply(); uint ratio = bdiv(poolAmountInAfterFee, poolTotal); _requireMathApprox(ratio); _pullPoolShare(msg.sender, poolAmountIn); _pushPoolShare(_communityFeeReceiver, poolAmountInFee); _burnPoolShare(poolAmountInAfterFee); for (uint i = 0; i < _tokens.length; i++) { address t = _tokens[i]; uint bal = _records[t].balance; uint tokenAmountOut = bmul(ratio, bal); _requireMathApprox(tokenAmountOut); require(tokenAmountOut >= minAmountsOut[i], "LIMIT_OUT"); _records[t].balance = bsub(_records[t].balance, tokenAmountOut); emit LOG_EXIT(msg.sender, t, tokenAmountOut); _pushUnderlying(t, msg.sender, tokenAmountOut); } emit LOG_COMMUNITY_FEE(msg.sender, _communityFeeReceiver, address(this), poolAmountInFee); } function swapExactAmountIn( address tokenIn, uint tokenAmountIn, address tokenOut, uint minAmountOut, uint maxPrice ) external override _logs_ _lock_ returns (uint tokenAmountOut, uint spotPriceAfter) { _preventSameTxOrigin(); _onlyWrapperOrNotWrapperMode(); _requireTokenIsBound(tokenIn); _requireTokenIsBound(tokenOut); require(_publicSwap, "NOT_PUBLIC"); Record storage inRecord = _records[address(tokenIn)]; Record storage outRecord = _records[address(tokenOut)]; uint spotPriceBefore = calcSpotPrice( inRecord.balance, _getDenormWeight(tokenIn), outRecord.balance, _getDenormWeight(tokenOut), _swapFee ); require(spotPriceBefore <= maxPrice, "LIMIT_PRICE"); (uint tokenAmountInAfterFee, uint tokenAmountInFee) = calcAmountWithCommunityFee( tokenAmountIn, _communitySwapFee, msg.sender ); require(tokenAmountInAfterFee <= bmul(inRecord.balance, MAX_IN_RATIO), "MAX_IN_RATIO"); tokenAmountOut = calcOutGivenIn( inRecord.balance, _getDenormWeight(tokenIn), outRecord.balance, _getDenormWeight(tokenOut), tokenAmountInAfterFee, _swapFee ); require(tokenAmountOut >= minAmountOut, "LIMIT_OUT"); inRecord.balance = badd(inRecord.balance, tokenAmountInAfterFee); outRecord.balance = bsub(outRecord.balance, tokenAmountOut); spotPriceAfter = calcSpotPrice( inRecord.balance, _getDenormWeight(tokenIn), outRecord.balance, _getDenormWeight(tokenOut), _swapFee ); require( spotPriceAfter >= spotPriceBefore && spotPriceBefore <= bdiv(tokenAmountInAfterFee, tokenAmountOut), "MATH_APPROX" ); require(spotPriceAfter <= maxPrice, "LIMIT_PRICE"); emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountInAfterFee, tokenAmountOut); _pullCommunityFeeUnderlying(tokenIn, msg.sender, tokenAmountInFee); _pullUnderlying(tokenIn, msg.sender, tokenAmountInAfterFee); _pushUnderlying(tokenOut, msg.sender, tokenAmountOut); emit LOG_COMMUNITY_FEE(msg.sender, _communityFeeReceiver, tokenIn, tokenAmountInFee); return (tokenAmountOut, spotPriceAfter); } function swapExactAmountOut( address tokenIn, uint maxAmountIn, address tokenOut, uint tokenAmountOut, uint maxPrice ) external override _logs_ _lock_ returns (uint tokenAmountIn, uint spotPriceAfter) { _preventSameTxOrigin(); _onlyWrapperOrNotWrapperMode(); _requireTokenIsBound(tokenIn); _requireTokenIsBound(tokenOut); require(_publicSwap, "NOT_PUBLIC"); Record storage inRecord = _records[address(tokenIn)]; Record storage outRecord = _records[address(tokenOut)]; require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), "OUT_RATIO"); uint spotPriceBefore = calcSpotPrice( inRecord.balance, _getDenormWeight(tokenIn), outRecord.balance, _getDenormWeight(tokenOut), _swapFee ); require(spotPriceBefore <= maxPrice, "LIMIT_PRICE"); (uint tokenAmountOutAfterFee, uint tokenAmountOutFee) = calcAmountWithCommunityFee( tokenAmountOut, _communitySwapFee, msg.sender ); tokenAmountIn = calcInGivenOut( inRecord.balance, _getDenormWeight(tokenIn), outRecord.balance, _getDenormWeight(tokenOut), tokenAmountOut, _swapFee ); require(tokenAmountIn <= maxAmountIn, "LIMIT_IN"); inRecord.balance = badd(inRecord.balance, tokenAmountIn); outRecord.balance = bsub(outRecord.balance, tokenAmountOut); spotPriceAfter = calcSpotPrice( inRecord.balance, _getDenormWeight(tokenIn), outRecord.balance, _getDenormWeight(tokenOut), _swapFee ); require( spotPriceAfter >= spotPriceBefore && spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOutAfterFee), "MATH_APPROX" ); require(spotPriceAfter <= maxPrice, "LIMIT_PRICE"); emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOutAfterFee); _pullUnderlying(tokenIn, msg.sender, tokenAmountIn); _pushUnderlying(tokenOut, msg.sender, tokenAmountOutAfterFee); _pushUnderlying(tokenOut, _communityFeeReceiver, tokenAmountOutFee); emit LOG_COMMUNITY_FEE(msg.sender, _communityFeeReceiver, tokenOut, tokenAmountOutFee); return (tokenAmountIn, spotPriceAfter); } function joinswapExternAmountIn(address tokenIn, uint tokenAmountIn, uint minPoolAmountOut) external override _logs_ _lock_ returns (uint poolAmountOut) { _preventSameTxOrigin(); _requireContractIsFinalized(); _onlyWrapperOrNotWrapperMode(); _requireTokenIsBound(tokenIn); require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), "MAX_IN_RATIO"); (uint tokenAmountInAfterFee, uint tokenAmountInFee) = calcAmountWithCommunityFee( tokenAmountIn, _communityJoinFee, msg.sender ); Record storage inRecord = _records[tokenIn]; poolAmountOut = calcPoolOutGivenSingleIn( inRecord.balance, _getDenormWeight(tokenIn), _totalSupply, _getTotalWeight(), tokenAmountInAfterFee, _swapFee ); require(poolAmountOut >= minPoolAmountOut, "LIMIT_OUT"); inRecord.balance = badd(inRecord.balance, tokenAmountInAfterFee); emit LOG_JOIN(msg.sender, tokenIn, tokenAmountInAfterFee); _mintPoolShare(poolAmountOut); _pushPoolShare(msg.sender, poolAmountOut); _pullCommunityFeeUnderlying(tokenIn, msg.sender, tokenAmountInFee); _pullUnderlying(tokenIn, msg.sender, tokenAmountInAfterFee); emit LOG_COMMUNITY_FEE(msg.sender, _communityFeeReceiver, tokenIn, tokenAmountInFee); return poolAmountOut; } function joinswapPoolAmountOut(address tokenIn, uint poolAmountOut, uint maxAmountIn) external override _logs_ _lock_ returns (uint tokenAmountIn) { _preventSameTxOrigin(); _requireContractIsFinalized(); _onlyWrapperOrNotWrapperMode(); _requireTokenIsBound(tokenIn); Record storage inRecord = _records[tokenIn]; (uint poolAmountOutAfterFee, uint poolAmountOutFee) = calcAmountWithCommunityFee( poolAmountOut, _communityJoinFee, msg.sender ); tokenAmountIn = calcSingleInGivenPoolOut( inRecord.balance, _getDenormWeight(tokenIn), _totalSupply, _getTotalWeight(), poolAmountOut, _swapFee ); _requireMathApprox(tokenAmountIn); require(tokenAmountIn <= maxAmountIn, "LIMIT_IN"); require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), "MAX_IN_RATIO"); inRecord.balance = badd(inRecord.balance, tokenAmountIn); emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn); _mintPoolShare(poolAmountOut); _pushPoolShare(msg.sender, poolAmountOutAfterFee); _pushPoolShare(_communityFeeReceiver, poolAmountOutFee); _pullUnderlying(tokenIn, msg.sender, tokenAmountIn); emit LOG_COMMUNITY_FEE(msg.sender, _communityFeeReceiver, address(this), poolAmountOutFee); return tokenAmountIn; } function exitswapPoolAmountIn(address tokenOut, uint poolAmountIn, uint minAmountOut) external override _logs_ _lock_ returns (uint tokenAmountOut) { _preventSameTxOrigin(); _requireContractIsFinalized(); _onlyWrapperOrNotWrapperMode(); _requireTokenIsBound(tokenOut); Record storage outRecord = _records[tokenOut]; tokenAmountOut = calcSingleOutGivenPoolIn( outRecord.balance, _getDenormWeight(tokenOut), _totalSupply, _getTotalWeight(), poolAmountIn, _swapFee ); require(tokenAmountOut >= minAmountOut, "LIMIT_OUT"); require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), "OUT_RATIO"); outRecord.balance = bsub(outRecord.balance, tokenAmountOut); (uint tokenAmountOutAfterFee, uint tokenAmountOutFee) = calcAmountWithCommunityFee( tokenAmountOut, _communityExitFee, msg.sender ); emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOutAfterFee); _pullPoolShare(msg.sender, poolAmountIn); _burnPoolShare(poolAmountIn); _pushUnderlying(tokenOut, msg.sender, tokenAmountOutAfterFee); _pushUnderlying(tokenOut, _communityFeeReceiver, tokenAmountOutFee); emit LOG_COMMUNITY_FEE(msg.sender, _communityFeeReceiver, tokenOut, tokenAmountOutFee); return tokenAmountOutAfterFee; } function exitswapExternAmountOut(address tokenOut, uint tokenAmountOut, uint maxPoolAmountIn) external override _logs_ _lock_ returns (uint poolAmountIn) { _preventSameTxOrigin(); _requireContractIsFinalized(); _onlyWrapperOrNotWrapperMode(); _requireTokenIsBound(tokenOut); require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), "OUT_RATIO"); Record storage outRecord = _records[tokenOut]; (uint tokenAmountOutAfterFee, uint tokenAmountOutFee) = calcAmountWithCommunityFee( tokenAmountOut, _communityExitFee, msg.sender ); poolAmountIn = calcPoolInGivenSingleOut( outRecord.balance, _getDenormWeight(tokenOut), _totalSupply, _getTotalWeight(), tokenAmountOut, _swapFee ); _requireMathApprox(poolAmountIn); require(poolAmountIn <= maxPoolAmountIn, "LIMIT_IN"); outRecord.balance = bsub(outRecord.balance, tokenAmountOut); emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOutAfterFee); _pullPoolShare(msg.sender, poolAmountIn); _burnPoolShare(poolAmountIn); _pushUnderlying(tokenOut, msg.sender, tokenAmountOutAfterFee); _pushUnderlying(tokenOut, _communityFeeReceiver, tokenAmountOutFee); emit LOG_COMMUNITY_FEE(msg.sender, _communityFeeReceiver, tokenOut, tokenAmountOutFee); return poolAmountIn; } // == // 'Underlying' token-manipulation functions make external calls but are NOT locked // You must `_lock_` or otherwise ensure reentry-safety function _pullUnderlying(address erc20, address from, uint amount) internal { bool xfer = IERC20(erc20).transferFrom(from, address(this), amount); require(xfer, "ERC20_FALSE"); } function _pushUnderlying(address erc20, address to, uint amount) internal { bool xfer = IERC20(erc20).transfer(to, amount); require(xfer, "ERC20_FALSE"); } function _pullCommunityFeeUnderlying(address erc20, address from, uint amount) internal { bool xfer = IERC20(erc20).transferFrom(from, _communityFeeReceiver, amount); require(xfer, "ERC20_FALSE"); } function _pullPoolShare(address from, uint amount) internal { _pull(from, amount); } function _pushPoolShare(address to, uint amount) internal { _push(to, amount); } function _mintPoolShare(uint amount) internal { if(address(_restrictions) != address(0)) { uint maxTotalSupply = _restrictions.getMaxTotalSupply(address(this)); require(badd(_totalSupply, amount) <= maxTotalSupply, "MAX_SUPPLY"); } _mint(amount); } function _burnPoolShare(uint amount) internal { _burn(amount); } function _requireTokenIsBound(address token) internal view { require(_records[token].bound, "NOT_BOUND"); } function _onlyController() internal view { require(msg.sender == _controller, "NOT_CONTROLLER"); } function _requireContractIsNotFinalized() internal view { require(!_finalized, "IS_FINALIZED"); } function _requireContractIsFinalized() internal view { require(_finalized, "NOT_FINALIZED"); } function _requireFeeInBounds(uint256 _fee) internal pure { require(_fee >= MIN_FEE && _fee <= MAX_FEE, "FEE_BOUNDS"); } function _requireMathApprox(uint256 _value) internal pure { require(_value != 0, "MATH_APPROX"); } function _preventReentrancy() internal view { require(!_mutex, "REENTRY"); } function _onlyWrapperOrNotWrapperMode() internal view { require(!_wrapperMode || msg.sender == _wrapper, "ONLY_WRAPPER"); } function _preventSameTxOrigin() internal { require(block.number > _lastSwapBlock[tx.origin], "SAME_TX_ORIGIN"); _lastSwapBlock[tx.origin] = block.number; } function _getDenormWeight(address token) internal view virtual returns (uint) { return _records[token].denorm; } function _getTotalWeight() internal view virtual returns (uint) { return _totalWeight; } function _addTotalWeight(uint _amount) internal virtual { _totalWeight = badd(_totalWeight, _amount); require(_totalWeight <= MAX_TOTAL_WEIGHT, "MAX_TOTAL_WEIGHT"); } function _subTotalWeight(uint _amount) internal virtual { _totalWeight = bsub(_totalWeight, _amount); } function calcAmountWithCommunityFee( uint tokenAmountIn, uint communityFee, address operator ) public view override returns (uint tokenAmountInAfterFee, uint tokenAmountFee) { if (address(_restrictions) != address(0) && _restrictions.isWithoutFee(operator)) { return (tokenAmountIn, 0); } uint adjustedIn = bsub(BONE, communityFee); tokenAmountInAfterFee = bmul(tokenAmountIn, adjustedIn); tokenAmountFee = bsub(tokenAmountIn, tokenAmountInAfterFee); return (tokenAmountInAfterFee, tokenAmountFee); } function getMinWeight() external view override returns (uint) { return MIN_WEIGHT; } function getMaxBoundTokens() external view override returns (uint) { return MAX_BOUND_TOKENS; } }
// SPDX-License-Identifier: GPL-3.0 // 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 <http://www.gnu.org/licenses/>. pragma solidity 0.6.12; import "./BNum.sol"; import "../interfaces/BMathInterface.sol"; contract BMath is BConst, BNum, BMathInterface { /********************************************************************************************** // calcSpotPrice // // sP = spotPrice // // bI = tokenBalanceIn ( bI / wI ) 1 // // bO = tokenBalanceOut sP = ----------- * ---------- // // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) // // wO = tokenWeightOut // // sF = swapFee // **********************************************************************************************/ function calcSpotPrice( uint tokenBalanceIn, uint tokenWeightIn, uint tokenBalanceOut, uint tokenWeightOut, uint swapFee ) public pure returns (uint spotPrice) { uint numer = bdiv(tokenBalanceIn, tokenWeightIn); uint denom = bdiv(tokenBalanceOut, tokenWeightOut); uint ratio = bdiv(numer, denom); uint scale = bdiv(BONE, bsub(BONE, swapFee)); return (spotPrice = bmul(ratio, scale)); } /********************************************************************************************** // calcOutGivenIn // // aO = tokenAmountOut // // bO = tokenBalanceOut // // bI = tokenBalanceIn / / bI \ (wI / wO) \ // // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | // // wI = tokenWeightIn \ \ ( bI + ( aI * ( 1 - sF )) / / // // wO = tokenWeightOut // // sF = swapFee // **********************************************************************************************/ function calcOutGivenIn( uint tokenBalanceIn, uint tokenWeightIn, uint tokenBalanceOut, uint tokenWeightOut, uint tokenAmountIn, uint swapFee ) public pure returns (uint tokenAmountOut) { uint weightRatio = bdiv(tokenWeightIn, tokenWeightOut); uint adjustedIn = bsub(BONE, swapFee); adjustedIn = bmul(tokenAmountIn, adjustedIn); uint y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn)); uint foo = bpow(y, weightRatio); uint bar = bsub(BONE, foo); tokenAmountOut = bmul(tokenBalanceOut, bar); return tokenAmountOut; } /********************************************************************************************** // calcInGivenOut // // aI = tokenAmountIn // // bO = tokenBalanceOut / / bO \ (wO / wI) \ // // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | // // aO = tokenAmountOut aI = \ \ ( bO - aO ) / / // // wI = tokenWeightIn -------------------------------------------- // // wO = tokenWeightOut ( 1 - sF ) // // sF = swapFee // **********************************************************************************************/ function calcInGivenOut( uint tokenBalanceIn, uint tokenWeightIn, uint tokenBalanceOut, uint tokenWeightOut, uint tokenAmountOut, uint swapFee ) public pure override returns (uint tokenAmountIn) { uint weightRatio = bdiv(tokenWeightOut, tokenWeightIn); uint diff = bsub(tokenBalanceOut, tokenAmountOut); uint y = bdiv(tokenBalanceOut, diff); uint foo = bpow(y, weightRatio); foo = bsub(foo, BONE); tokenAmountIn = bsub(BONE, swapFee); tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn); return tokenAmountIn; } /********************************************************************************************** // calcPoolOutGivenSingleIn // // pAo = poolAmountOut / \ // // tAi = tokenAmountIn /// / // wI \ \\ \ wI \ // // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \ -- \ // // tW = totalWeight pAo=|| \ \ \\ tW / // | ^ tW | * pS - pS // // tBi = tokenBalanceIn \\ ------------------------------------- / / // // pS = poolSupply \\ tBi / / // // sF = swapFee \ / // **********************************************************************************************/ function calcPoolOutGivenSingleIn( uint tokenBalanceIn, uint tokenWeightIn, uint poolSupply, uint totalWeight, uint tokenAmountIn, uint swapFee ) public pure returns (uint poolAmountOut) { // Charge the trading fee for the proportion of tokenAi /// which is implicitly traded to the other pool tokens. // That proportion is (1- weightTokenIn) // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee); uint normalizedWeight = bdiv(tokenWeightIn, totalWeight); uint zaz = bmul(bsub(BONE, normalizedWeight), swapFee); uint tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz)); uint newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee); uint tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn); // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply; uint poolRatio = bpow(tokenInRatio, normalizedWeight); uint newPoolSupply = bmul(poolRatio, poolSupply); poolAmountOut = bsub(newPoolSupply, poolSupply); return poolAmountOut; } /********************************************************************************************** // calcSingleInGivenPoolOut // // tAi = tokenAmountIn //(pS + pAo)\ / 1 \\ // // pS = poolSupply || --------- | ^ | --------- || * bI - bI // // pAo = poolAmountOut \\ pS / \(wI / tW)// // // bI = balanceIn tAi = -------------------------------------------- // // wI = weightIn / wI \ // // tW = totalWeight | 1 - ---- | * sF // // sF = swapFee \ tW / // **********************************************************************************************/ function calcSingleInGivenPoolOut( uint tokenBalanceIn, uint tokenWeightIn, uint poolSupply, uint totalWeight, uint poolAmountOut, uint swapFee ) public pure returns (uint tokenAmountIn) { uint normalizedWeight = bdiv(tokenWeightIn, totalWeight); uint newPoolSupply = badd(poolSupply, poolAmountOut); uint poolRatio = bdiv(newPoolSupply, poolSupply); //uint newBalTi = poolRatio^(1/weightTi) * balTi; uint boo = bdiv(BONE, normalizedWeight); uint tokenInRatio = bpow(poolRatio, boo); uint newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn); uint tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn); // Do reverse order of fees charged in joinswap_ExternAmountIn, this way // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ``` //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ; uint zar = bmul(bsub(BONE, normalizedWeight), swapFee); tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar)); return tokenAmountIn; } /********************************************************************************************** // calcSingleOutGivenPoolIn // // tAo = tokenAmountOut / / \\ // // bO = tokenBalanceOut / // pS - pAi \ / 1 \ \\ // // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || // // ps = poolSupply \ \\ pS / \(wO / tW)/ // // // wI = tokenWeightIn tAo = \ \ // // // tW = totalWeight / / wO \ \ // // sF = swapFee * | 1 - | 1 - ---- | * sF | // // eF = exitFee \ \ tW / / // **********************************************************************************************/ function calcSingleOutGivenPoolIn( uint tokenBalanceOut, uint tokenWeightOut, uint poolSupply, uint totalWeight, uint poolAmountIn, uint swapFee ) public pure returns (uint tokenAmountOut) { uint normalizedWeight = bdiv(tokenWeightOut, totalWeight); uint newPoolSupply = bsub(poolSupply, poolAmountIn); uint poolRatio = bdiv(newPoolSupply, poolSupply); // newBalTo = poolRatio^(1/weightTo) * balTo; uint tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight)); uint newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut); uint tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut); // charge swap fee on the output token side //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee) uint zaz = bmul(bsub(BONE, normalizedWeight), swapFee); tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz)); return tokenAmountOut; } /********************************************************************************************** // calcPoolInGivenSingleOut // // pAi = poolAmountIn // / tAo \\ / wO \ \ // // bO = tokenBalanceOut // | bO - -------------------------- |\ | ---- | \ // // tAo = tokenAmountOut pS - || \ 1 - ((1 - (tO / tW)) * sF)/ | ^ \ tW / * pS | // // ps = poolSupply \\ -----------------------------------/ / // // wO = tokenWeightOut pAi = \\ bO / / // // tW = totalWeight // // sF = swapFee // **********************************************************************************************/ function calcPoolInGivenSingleOut( uint tokenBalanceOut, uint tokenWeightOut, uint poolSupply, uint totalWeight, uint tokenAmountOut, uint swapFee ) public pure returns (uint poolAmountIn) { // charge swap fee on the output token side uint normalizedWeight = bdiv(tokenWeightOut, totalWeight); //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ; uint zoo = bsub(BONE, normalizedWeight); uint zar = bmul(zoo, swapFee); uint tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar)); uint newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee); uint tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut); //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply; uint poolRatio = bpow(tokenOutRatio, normalizedWeight); uint newPoolSupply = bmul(poolRatio, poolSupply); uint poolAmountIn = bsub(poolSupply, newPoolSupply); return poolAmountIn; } }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; interface IPoolRestrictions { function getMaxTotalSupply(address _pool) external view returns (uint256); function isVotingSignatureAllowed(address _votingAddress, bytes4 _signature) external view returns (bool); function isVotingSenderAllowed(address _votingAddress, address _sender) external view returns (bool); function isWithoutFee(address _addr) external view returns (bool); }
{ "optimizer": { "enabled": true, "runs": 2 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"minWeightPerSecond","type":"uint256"},{"internalType":"uint256","name":"maxWeightPerSecond","type":"uint256"}],"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":true,"inputs":[{"indexed":true,"internalType":"bytes4","name":"sig","type":"bytes4"},{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"LOG_CALL","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voting","type":"address"},{"indexed":true,"internalType":"bool","name":"success","type":"bool"},{"indexed":true,"internalType":"bytes4","name":"inputSig","type":"bytes4"},{"indexed":false,"internalType":"bytes","name":"inputData","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"outputData","type":"bytes"}],"name":"LOG_CALL_VOTING","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"LOG_COMMUNITY_FEE","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmountOut","type":"uint256"}],"name":"LOG_EXIT","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmountIn","type":"uint256"}],"name":"LOG_JOIN","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":true,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenAmountOut","type":"uint256"}],"name":"LOG_SWAP","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"fromDenorm","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"targetDenorm","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fromTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"targetTimestamp","type":"uint256"}],"name":"SetDynamicWeight","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minWeightPerSecond","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxWeightPerSecond","type":"uint256"}],"name":"SetWeightPerSecondBounds","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":"BONE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BPOW_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INIT_POOL_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BOUND_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BPOW_BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_IN_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_OUT_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOTAL_WEIGHT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_WEIGHT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_BALANCE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_BOUND_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_BPOW_BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_WEIGHT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"whom","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"targetDenorm","type":"uint256"},{"internalType":"uint256","name":"fromTimestamp","type":"uint256"},{"internalType":"uint256","name":"targetTimestamp","type":"uint256"}],"name":"bind","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"bind","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"internalType":"uint256","name":"communityFee","type":"uint256"},{"internalType":"address","name":"operator","type":"address"}],"name":"calcAmountWithCommunityFee","outputs":[{"internalType":"uint256","name":"tokenAmountInAfterFee","type":"uint256"},{"internalType":"uint256","name":"tokenAmountFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenBalanceIn","type":"uint256"},{"internalType":"uint256","name":"tokenWeightIn","type":"uint256"},{"internalType":"uint256","name":"tokenBalanceOut","type":"uint256"},{"internalType":"uint256","name":"tokenWeightOut","type":"uint256"},{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"},{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"calcInGivenOut","outputs":[{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenBalanceIn","type":"uint256"},{"internalType":"uint256","name":"tokenWeightIn","type":"uint256"},{"internalType":"uint256","name":"tokenBalanceOut","type":"uint256"},{"internalType":"uint256","name":"tokenWeightOut","type":"uint256"},{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"calcOutGivenIn","outputs":[{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenBalanceOut","type":"uint256"},{"internalType":"uint256","name":"tokenWeightOut","type":"uint256"},{"internalType":"uint256","name":"poolSupply","type":"uint256"},{"internalType":"uint256","name":"totalWeight","type":"uint256"},{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"},{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"calcPoolInGivenSingleOut","outputs":[{"internalType":"uint256","name":"poolAmountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenBalanceIn","type":"uint256"},{"internalType":"uint256","name":"tokenWeightIn","type":"uint256"},{"internalType":"uint256","name":"poolSupply","type":"uint256"},{"internalType":"uint256","name":"totalWeight","type":"uint256"},{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"calcPoolOutGivenSingleIn","outputs":[{"internalType":"uint256","name":"poolAmountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenBalanceIn","type":"uint256"},{"internalType":"uint256","name":"tokenWeightIn","type":"uint256"},{"internalType":"uint256","name":"poolSupply","type":"uint256"},{"internalType":"uint256","name":"totalWeight","type":"uint256"},{"internalType":"uint256","name":"poolAmountOut","type":"uint256"},{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"calcSingleInGivenPoolOut","outputs":[{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenBalanceOut","type":"uint256"},{"internalType":"uint256","name":"tokenWeightOut","type":"uint256"},{"internalType":"uint256","name":"poolSupply","type":"uint256"},{"internalType":"uint256","name":"totalWeight","type":"uint256"},{"internalType":"uint256","name":"poolAmountIn","type":"uint256"},{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"calcSingleOutGivenPoolIn","outputs":[{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenBalanceIn","type":"uint256"},{"internalType":"uint256","name":"tokenWeightIn","type":"uint256"},{"internalType":"uint256","name":"tokenBalanceOut","type":"uint256"},{"internalType":"uint256","name":"tokenWeightOut","type":"uint256"},{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"calcSpotPrice","outputs":[{"internalType":"uint256","name":"spotPrice","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"voting","type":"address"},{"internalType":"bytes4","name":"signature","type":"bytes4"},{"internalType":"bytes","name":"args","type":"bytes"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"callVoting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"decreaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"poolAmountIn","type":"uint256"},{"internalType":"uint256[]","name":"minAmountsOut","type":"uint256[]"}],"name":"exitPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"},{"internalType":"uint256","name":"maxPoolAmountIn","type":"uint256"}],"name":"exitswapExternAmountOut","outputs":[{"internalType":"uint256","name":"poolAmountIn","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"poolAmountIn","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"}],"name":"exitswapPoolAmountIn","outputs":[{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCommunityFee","outputs":[{"internalType":"uint256","name":"communitySwapFee","type":"uint256"},{"internalType":"uint256","name":"communityJoinFee","type":"uint256"},{"internalType":"uint256","name":"communityExitFee","type":"uint256"},{"internalType":"address","name":"communityFeeReceiver","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getController","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentTokens","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getDenormalizedWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getDynamicWeightSettings","outputs":[{"internalType":"uint256","name":"fromTimestamp","type":"uint256"},{"internalType":"uint256","name":"targetTimestamp","type":"uint256"},{"internalType":"uint256","name":"fromDenorm","type":"uint256"},{"internalType":"uint256","name":"targetDenorm","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFinalTokens","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxBoundTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getNormalizedWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRestrictions","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"}],"name":"getSpotPrice","outputs":[{"internalType":"uint256","name":"spotPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"}],"name":"getSpotPriceSansFee","outputs":[{"internalType":"uint256","name":"spotPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSwapFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDenormalizedWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWeightPerSecondBounds","outputs":[{"internalType":"uint256","name":"minWeightPerSecond","type":"uint256"},{"internalType":"uint256","name":"maxWeightPerSecond","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWrapper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWrapperMode","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"gulp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"increaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"t","type":"address"}],"name":"isBound","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFinalized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPublicSwap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"poolAmountOut","type":"uint256"},{"internalType":"uint256[]","name":"maxAmountsIn","type":"uint256[]"}],"name":"joinPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"internalType":"uint256","name":"minPoolAmountOut","type":"uint256"}],"name":"joinswapExternAmountIn","outputs":[{"internalType":"uint256","name":"poolAmountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"poolAmountOut","type":"uint256"},{"internalType":"uint256","name":"maxAmountIn","type":"uint256"}],"name":"joinswapPoolAmountOut","outputs":[{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"denorm","type":"uint256"}],"name":"rebind","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"communitySwapFee","type":"uint256"},{"internalType":"uint256","name":"communityJoinFee","type":"uint256"},{"internalType":"uint256","name":"communityExitFee","type":"uint256"},{"internalType":"address","name":"communityFeeReceiver","type":"address"}],"name":"setCommunityFeeAndReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"manager","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"targetDenorm","type":"uint256"},{"internalType":"uint256","name":"fromTimestamp","type":"uint256"},{"internalType":"uint256","name":"targetTimestamp","type":"uint256"}],"name":"setDynamicWeight","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"public_","type":"bool"}],"name":"setPublicSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IPoolRestrictions","name":"restrictions","type":"address"}],"name":"setRestrictions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"setSwapFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minWeightPerSecond","type":"uint256"},{"internalType":"uint256","name":"maxWeightPerSecond","type":"uint256"}],"name":"setWeightPerSecondBounds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"bool","name":"wrapperMode","type":"bool"}],"name":"setWrapper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"name":"swapExactAmountIn","outputs":[{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"},{"internalType":"uint256","name":"spotPriceAfter","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"maxAmountIn","type":"uint256"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"tokenAmountOut","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"name":"swapExactAmountOut","outputs":[{"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"internalType":"uint256","name":"spotPriceAfter","type":"uint256"}],"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":"dst","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"unbind","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526005805460ff191660121790553480156200001e57600080fd5b5060405162005bf738038062005bf7833981810160405260808110156200004457600080fd5b81019080805160405193929190846401000000008211156200006557600080fd5b9083019060208201858111156200007b57600080fd5b82516401000000008111828201881017156200009657600080fd5b82525081516020918201929091019080838360005b83811015620000c5578181015183820152602001620000ab565b50505050905090810190601f168015620000f35780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011757600080fd5b9083019060208201858111156200012d57600080fd5b82516401000000008111828201881017156200014857600080fd5b82525081516020918201929091019080838360005b83811015620001775781810151838201526020016200015d565b50505050905090810190601f168015620001a55780820380516001836020036101000a031916815260200191505b50604090815260208281015192909101518651929450925085918591620001d29160039185019062000242565b508051620001e890600490602084019062000242565b50506005805464e8d4a5100060085560006009819055600a819055600b5562010000600160b01b0319163362010000021760ff60b01b1916905550600c805460ff60a01b1916905560129190915560135550620002de9050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200028557805160ff1916838001178555620002b5565b82800160010185558215620002b5579182015b82811115620002b557825182559160200191906001019062000298565b50620002c3929150620002c7565b5090565b5b80821115620002c35760008155600101620002c8565b61590980620002ee6000396000f3fe608060405234801561001057600080fd5b50600436106103855760003560e01c806302c967481461038a57806306fdde03146103ce578063095ea7b31461044b57806309a3bbe41461048b5780630f7b1e3e146104935780631446a7ff146104cd57806315e84af9146104fb57806318160ddd14610529578063189d00ca14610531578063218b5382146105395780632245a08e1461054157806323b872dd1461058c5780632f37b624146105c25780633018205f146105e8578063313ce5671461060c57806334e199071461062a5780633fdddaa21461064757806341e5a5d414610679578063442e2152146106c557806346ab38f11461075257806349b59552146107845780634bb278f3146107a35780634d752ec3146107ab5780634f69c0d4146107e95780635c1bbaf71461085e5780635db342771461089957806366188463146108cb57806367cc71f0146108f75780636d06dfa0146108ff57806370a082311461093157806370eb8e7f1461095757806376c7a3c71461095f5780637c5e9ea4146109675780638201aa3f146109a757806382f652ad146109e75780638656b65314610a22578063867378c514610a5d5780638733ad7114610a655780638929801214610a885780638c28cbe814610ac35780638d4e408314610ae95780638f6b707014610af157806390ad688b14610af957806392eefe9b14610b30578063936c347714610b565780639381cd2b14610b5e578063948d8ce614610b6657806395d89b4114610b8c578063992e2a9214610b945780639a737aa214610b9c578063a221ee4914610ba4578063a9059cbb14610bd9578063b02f0b7314610c05578063b0e0d13614610c7a578063b7b800a414610c82578063ba019dab14610c8a578063ba9530a614610c92578063bc063e1a14610ccd578063bc694ea214610cd5578063be3bbd2e14610cdd578063c36596a614610d35578063c4195cb814610d3d578063c61641cd14610d45578063cc77828d14610d6b578063cd2ed8fb14610d73578063cf5e7bd314610d7b578063cfb2794514610da1578063d4cadf6814610dd9578063d73dd62314610de1578063d80817fb14610e0d578063dd62ed3e14610e15578063e0e5228d14610e43578063e4a28a521461048b578063e4e1e53814610e71578063ec09302114610ea3578063f1b8a9b714610eab578063f8b2cb4f14610ed1578063f8d6aed414610ef7578063fde924f714610f32575b600080fd5b6103bc600480360360608110156103a057600080fd5b506001600160a01b038135169060208101359060400135610f3a565b60408051918252519081900360200190f35b6103d66111aa565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104105781810151838201526020016103f8565b50505050905090810190601f16801561043d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6104776004803603604081101561046157600080fd5b506001600160a01b038135169060200135611240565b604080519115158252519081900360200190f35b6103bc6112a1565b6104cb600480360360808110156104a957600080fd5b50803590602081013590604081013590606001356001600160a01b03166112ae565b005b6103bc600480360360408110156104e357600080fd5b506001600160a01b0381358116916020013516611384565b6103bc6004803603604081101561051157600080fd5b506001600160a01b03813581169160200135166113f1565b6103bc6114c1565b6103bc6114c7565b6103bc6114db565b6105736004803603606081101561055757600080fd5b50803590602081013590604001356001600160a01b03166114e3565b6040805192835260208301919091528051918290030190f35b610477600480360360608110156105a257600080fd5b506001600160a01b038135811691602081013590911690604001356115bf565b610477600480360360208110156105d857600080fd5b50356001600160a01b0316611715565b6105f0611737565b604080516001600160a01b039092168252519081900360200190f35b610614611757565b6040805160ff9092168252519081900360200190f35b6104cb6004803603602081101561064057600080fd5b5035611760565b6104cb6004803603606081101561065d57600080fd5b506001600160a01b0381351690602081013590604001356117f9565b61069f6004803603602081101561068f57600080fd5b50356001600160a01b031661187d565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6104cb600480360360808110156106db57600080fd5b6001600160a01b03823516916001600160e01b031960208201351691810190606081016040820135600160201b81111561071457600080fd5b82018360208201111561072657600080fd5b803590602001918460018302840111600160201b8311171561074757600080fd5b9193509150356118b7565b6103bc6004803603606081101561076857600080fd5b506001600160a01b038135169060208101359060400135611c1f565b6104cb6004803603602081101561079a57600080fd5b50351515611e8d565b6104cb611f38565b6104cb600480360360a08110156107c157600080fd5b506001600160a01b03813516906020810135906040810135906060810135906080013561205d565b6104cb600480360360408110156107ff57600080fd5b81359190810190604081016020820135600160201b81111561082057600080fd5b82018360208201111561083257600080fd5b803590602001918460208302840111600160201b8311171561085357600080fd5b5090925090506120e0565b6103bc600480360360c081101561087457600080fd5b5080359060208101359060408101359060608101359060808101359060a00135612347565b6103bc600480360360608110156108af57600080fd5b506001600160a01b0381351690602081013590604001356123ff565b610477600480360360408110156108e157600080fd5b506001600160a01b03813516906020013561265a565b61047761273d565b6103bc6004803603606081101561091557600080fd5b506001600160a01b038135169060208101359060400135612758565b6103bc6004803603602081101561094757600080fd5b50356001600160a01b03166129c2565b6103bc6129dd565b6103bc6129e5565b610573600480360360a081101561097d57600080fd5b506001600160a01b03813581169160208101359160408201351690606081013590608001356129f7565b610573600480360360a08110156109bd57600080fd5b506001600160a01b0381358116916020810135916040820135169060608101359060800135612ddb565b6103bc600480360360c08110156109fd57600080fd5b5080359060208101359060408101359060608101359060808101359060a001356131c2565b6103bc600480360360c0811015610a3857600080fd5b5080359060208101359060408101359060608101359060808101359060a00135613268565b6103bc613309565b6104cb60048036036040811015610a7b57600080fd5b508035906020013561331d565b6103bc600480360360c0811015610a9e57600080fd5b5080359060208101359060408101359060608101359060808101359060a001356133f1565b6104cb60048036036020811015610ad957600080fd5b50356001600160a01b031661348c565b6104776135a9565b6105f06135b9565b610b016135d3565b604080519485526020850193909352838301919091526001600160a01b03166060830152519081900360800190f35b6104cb60048036036020811015610b4657600080fd5b50356001600160a01b0316613604565b6103bc6136b3565b6103bc6136ca565b6103bc60048036036020811015610b7c57600080fd5b50356001600160a01b03166136d7565b6103d66136f3565b6103bc613754565b6103bc613760565b6103bc600480360360a0811015610bba57600080fd5b5080359060208101359060408101359060608101359060800135613765565b61047760048036036040811015610bef57600080fd5b506001600160a01b0381351690602001356137ca565b6104cb60048036036040811015610c1b57600080fd5b81359190810190604081016020820135600160201b811115610c3c57600080fd5b820183602082011115610c4e57600080fd5b803590602001918460208302840111600160201b83111715610c6f57600080fd5b5090925090506137e0565b6103bc613a48565b6103bc613a4d565b6103bc613a52565b6103bc600480360360c0811015610ca857600080fd5b5080359060208101359060408101359060608101359060808101359060a00135613a57565b6103bc613ad8565b6103bc613ae8565b610ce5613af4565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610d21578181015183820152602001610d09565b505050509050019250505060405180910390f35b6103bc613b65565b6105f0613b71565b6104cb60048036036020811015610d5b57600080fd5b50356001600160a01b0316613b8b565b610ce5613c38565b6103bc613c42565b6104cb60048036036020811015610d9157600080fd5b50356001600160a01b0316613c48565b6104cb60048036036080811015610db757600080fd5b506001600160a01b038135169060208101359060408101359060600135613c98565b6103bc614051565b61047760048036036040811015610df757600080fd5b506001600160a01b038135169060200135614062565b6105736140ee565b6103bc60048036036040811015610e2b57600080fd5b506001600160a01b03813581169160200135166140f8565b6104cb60048036036040811015610e5957600080fd5b506001600160a01b0381351690602001351515614123565b6104cb60048036036060811015610e8757600080fd5b506001600160a01b0381351690602081013590604001356141e4565b6103bc61421c565b6103bc60048036036020811015610ec157600080fd5b50356001600160a01b031661422c565b6103bc60048036036020811015610ee757600080fd5b50356001600160a01b0316614253565b6103bc600480360360c0811015610f0d57600080fd5b5080359060208101359060408101359060608101359060808101359060a00135614285565b610477614308565b6000336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2610fa5614318565b6005805461ff001916610100179055610fbc614361565b610fc46143c9565b610fcc614417565b610fd58461447a565b6001600160a01b0384166000908152600e6020526040902060039081015461100a91670de0b6b3a76400005b046001016144d6565b83111561104a576040805162461bcd60e51b81526020600482015260096024820152684f55545f524154494f60b81b604482015290519081900360640190fd5b6001600160a01b0384166000908152600e60205260408120600b549091908190611076908790336114e3565b9150915061109f836003015461108b8961459f565b600254611096614690565b8a6008546131c2565b93506110aa846146e7565b848411156110ea576040805162461bcd60e51b81526020600482015260086024820152672624a6a4aa2fa4a760c11b604482015290519081900360640190fd5b6110f8836003015487614727565b60038401556040805183815290516001600160a01b0389169133916000805160206158748339815191529181900360200190a36111353385614789565b61113e84614797565b6111498733846147a0565b600c546111619088906001600160a01b0316836147a0565b600c546040805183815290516001600160a01b03808b1693169133916000805160206158948339815191529181900360200190a45050506005805461ff00191690559392505050565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156112365780601f1061120b57610100808354040283529160200191611236565b820191906000526020600020905b81548152906001019060200180831161121957829003601f168201915b5050505050905090565b600061124b8361486d565b3360008181526001602090815260408083206001600160a01b03881680855290835292819020869055805186815290519293926000805160206158b4833981519152929181900390910190a35060015b92915050565b6802b5e3af16b188000081565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2611317614318565b6005805461ff00191661010017905561132e6148bb565b61133784614911565b61134083614911565b61134982614911565b600993909355600a91909155600b55600c80546001600160a01b0319166001600160a01b039092169190911790556005805461ff0019169055565b600061138e614318565b6113978361447a565b6113a08261447a565b6001600160a01b038084166000908152600e60205260408082209285168252902060038201546113e8906113d38761459f565b83600301546113e18861459f565b6000613765565b95945050505050565b60006113fb614318565b6001600160a01b0383166000908152600e602052604090205460ff16801561143b57506001600160a01b0382166000908152600e602052604090205460ff165b611478576040805162461bcd60e51b81526020600482015260096024820152681393d517d093d5539160ba1b604482015290519081900360640190fd5b6001600160a01b038084166000908152600e60205260408082209285168252902060038201546113e8906114ab8761459f565b83600301546114b98861459f565b600854613765565b60025490565b6402540be400670de0b6b3a76400005b0481565b633b9aca0081565b60075460009081906001600160a01b031615801590611577575060075460408051630a499ad360e01b81526001600160a01b03868116600483015291519190921691630a499ad3916024808301926020929190829003018186803b15801561154a57600080fd5b505afa15801561155e573d6000803e3d6000fd5b505050506040513d602081101561157457600080fd5b50515b15611587575083905060006115b7565b600061159b670de0b6b3a764000086614727565b90506115a786826144d6565b92506115b38684614727565b9150505b935093915050565b6000336001600160a01b03851614806115fb57506001600160a01b03841660009081526001602090815260408083203384529091529020548211155b611644576040805162461bcd60e51b815260206004820152601560248201527422a9292fa12a27a5a2a72fa120a22fa1a0a62622a960591b604482015290519081900360640190fd5b61164f84848461496c565b336001600160a01b0385161480159061168d57506001600160a01b038416600090815260016020908152604080832033845290915290205460001914155b1561170b576001600160a01b03841660009081526001602090815260408083203384529091529020546116c09083614727565b6001600160a01b0385166000818152600160209081526040808320338085529083529281902085905580519485525191936000805160206158b4833981519152929081900390910190a35b5060019392505050565b6001600160a01b0381166000908152600e602052604090205460ff165b919050565b6000611741614318565b506005546201000090046001600160a01b031690565b60055460ff1690565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a26117c9614318565b6005805461ff0019166101001790556117e06148bb565b6117e981614911565b6008556005805461ff0019169055565b633b9aca008114801561182257506001600160a01b038316600090815260116020526040902054155b61186d576040805162461bcd60e51b815260206004820152601760248201527613d3931657d39155d7d513d2d15394d7d0531313d5d151604a1b604482015290519081900360640190fd5b611878838383614a7c565b505050565b6001600160a01b0316600090815260116020908152604080832080546001820154600e909452919093206002908101549301549093919291565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2611920614318565b6005805461ff0019166101001790556007546040805163ea3457b760e01b81526001600160a01b0388811660048301526001600160e01b0319881660248301529151919092169163ea3457b7916044808301926020929190829003018186803b15801561198c57600080fd5b505afa1580156119a0573d6000803e3d6000fd5b505050506040513d60208110156119b657600080fd5b50516119fb576040805162461bcd60e51b815260206004820152600f60248201526e4e4f545f414c4c4f5745445f53494760881b604482015290519081900360640190fd5b611a036148bb565b60006060866001600160a01b03168387878760405160200180846001600160e01b03191681526004018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310611a7c5780518252601f199092019160209182019101611a5d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611ade576040519150601f19603f3d011682016040523d82523d6000602084013e611ae3565b606091505b509150915081611b28576040805162461bcd60e51b815260206004820152600b60248201526a4e4f545f5355434345535360a81b604482015290519081900360640190fd5b856001600160e01b031916821515886001600160a01b03167f32258dd51d74a04508615e0840c1fc905dff28c96b7335e69d9a41023ecd286e88888660405180806020018060200183810383528686828181526020019250808284376000838201819052601f909101601f191690920185810384528651815286516020918201939188019250908190849084905b83811015611bce578181015183820152602001611bb6565b50505050905090810190601f168015611bfb5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a450506005805461ff00191690555050505050565b6000336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2611c8a614318565b6005805461ff001916610100179055611ca1614361565b611ca96143c9565b611cb1614417565b611cba8461447a565b6001600160a01b0384166000908152600e602052604090206003810154611cf890611ce48761459f565b600254611cef614690565b886008546133f1565b915082821015611d3b576040805162461bcd60e51b8152602060048201526009602482015268131253525517d3d55560ba1b604482015290519081900360640190fd5b6001600160a01b0385166000908152600e60205260409020600390810154611d6b91670de0b6b3a7640000611001565b821115611dab576040805162461bcd60e51b81526020600482015260096024820152684f55545f524154494f60b81b604482015290519081900360640190fd5b611db9816003015483614727565b8160030181905550600080611dd184600b54336114e3565b91509150866001600160a01b0316336001600160a01b0316600080516020615874833981519152846040518082815260200191505060405180910390a3611e183387614789565b611e2186614797565b611e2c8733846147a0565b600c54611e449088906001600160a01b0316836147a0565b600c546040805183815290516001600160a01b03808b1693169133916000805160206158948339815191529181900360200190a4506005805461ff001916905595945050505050565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2611ef6614318565b6005805461ff001916610100179055611f0d614c77565b611f156148bb565b6005805461ff0019921515600160b01b0260ff60b01b1990911617919091169055565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2611fa1614318565b6005805461ff001916610100179055611fb86148bb565b611fc0614c77565b600d5460021115612005576040805162461bcd60e51b815260206004820152600a6024820152694d494e5f544f4b454e5360b01b604482015290519081900360640190fd5b600c805460ff60a01b1916600160a01b1790556005805460ff60b01b1916600160b01b17905561203d68056bc75e2d63100000614cc5565b6120503368056bc75e2d63100000614daa565b6005805461ff0019169055565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a26120cd8585633b9aca00614db4565b6120d985848484613c98565b5050505050565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2612149614318565b6005805461ff001916610100179055612160614361565b612168614417565b6121706143c9565b600061217a6114c1565b905060006121888583614f67565b9050612193816146e7565b60005b600d548110156122c3576000600d82815481106121af57fe5b60009182526020808320909101546001600160a01b0316808352600e9091526040822060030154909250906121e485836144d6565b90506121ef816146e7565b8787858181106121fb57fe5b90506020020135811115612241576040805162461bcd60e51b81526020600482015260086024820152672624a6a4aa2fa4a760c11b604482015290519081900360640190fd5b6001600160a01b0383166000908152600e6020526040902060030154612267908261506f565b6001600160a01b0384166000818152600e60209081526040918290206003019390935580518481529051919233926000805160206158148339815191529281900390910190a36122b88333836150c3565b505050600101612196565b506000806122d487600a54336114e3565b915091506122e187614cc5565b6122eb3383614daa565b600c54612301906001600160a01b031682614daa565b600c5460408051838152905130926001600160a01b03169133916000805160206158948339815191529181900360200190a450506005805461ff00191690555050505050565b6000806123548786614f67565b90506000612362878661506f565b905060006123708289614f67565b90506000612386670de0b6b3a764000085614f67565b90506000612394838361511c565b905060006123a2828e6144d6565b905060006123b0828f614727565b905060006123cf6123c9670de0b6b3a76400008a614727565b8b6144d6565b90506123ec826123e7670de0b6b3a764000084614727565b614f67565b9f9e505050505050505050505050505050565b6000336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a261246a614318565b6005805461ff001916610100179055612481614361565b6124896143c9565b612491614417565b61249a8461447a565b6001600160a01b0384166000908152600e60205260409020600301546124cc906002670de0b6b3a76400005b046144d6565b83111561250f576040805162461bcd60e51b815260206004820152600c60248201526b4d41585f494e5f524154494f60a01b604482015290519081900360640190fd5b60008061251f85600a54336114e3565b6001600160a01b0388166000908152600e60205260409020600381015492945090925090612564906125508961459f565b60025461255b614690565b87600854613268565b9350848410156125a7576040805162461bcd60e51b8152602060048201526009602482015268131253525517d3d55560ba1b604482015290519081900360640190fd5b6125b581600301548461506f565b60038201556040805184815290516001600160a01b0389169133916000805160206158148339815191529181900360200190a36125f184614cc5565b6125fb3385614daa565b61260687338461522a565b6126118733856150c3565b600c546040805184815290516001600160a01b03808b1693169133916000805160206158948339815191529181900360200190a45050506005805461ff00191690559392505050565b60006126658361486d565b3360009081526001602090815260408083206001600160a01b0387168452909152902054808311156126ba573360009081526001602090815260408083206001600160a01b03881684529091528120556126e9565b6126c48184614727565b3360009081526001602090815260408083206001600160a01b03891684529091529020555b3360008181526001602090815260408083206001600160a01b0389168085529083529281902054815190815290519293926000805160206158b4833981519152929181900390910190a35060019392505050565b6000612747614318565b50600654600160a01b900460ff1690565b6000336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a26127c3614318565b6005805461ff0019166101001790556127da614361565b6127e26143c9565b6127ea614417565b6127f38461447a565b6001600160a01b0384166000908152600e60205260408120600a54909190819061281f908790336114e3565b9150915061284883600301546128348961459f565b60025461283f614690565b8a600854612347565b9350612853846146e7565b84841115612893576040805162461bcd60e51b81526020600482015260086024820152672624a6a4aa2fa4a760c11b604482015290519081900360640190fd5b6001600160a01b0387166000908152600e60205260409020600301546128c3906002670de0b6b3a76400006124c6565b841115612906576040805162461bcd60e51b815260206004820152600c60248201526b4d41585f494e5f524154494f60a01b604482015290519081900360640190fd5b61291483600301548561506f565b60038401556040805185815290516001600160a01b0389169133916000805160206158148339815191529181900360200190a361295086614cc5565b61295a3383614daa565b600c54612970906001600160a01b031682614daa565b61297b8733866150c3565b600c5460408051838152905130926001600160a01b03169133916000805160206158948339815191529181900360200190a45050506005805461ff00191690559392505050565b6001600160a01b031660009081526020819052604090205490565b633b9aca0090565b620f4240670de0b6b3a76400006114d7565b60408051602080825236908201819052600092839233926001600160e01b03198535169285929081908101848480828437600083820152604051601f909101601f19169092018290039550909350505050a2612a51614318565b6005805461ff001916610100179055612a68614361565b612a70614417565b612a798761447a565b612a828561447a565b600554600160b01b900460ff16612acd576040805162461bcd60e51b815260206004820152600a6024820152694e4f545f5055424c494360b01b604482015290519081900360640190fd5b6001600160a01b038088166000908152600e602052604080822092881682529020600380820154612b0691670de0b6b3a7640000611001565b861115612b46576040805162461bcd60e51b81526020600482015260096024820152684f55545f524154494f60b81b604482015290519081900360640190fd5b6000612b678360030154612b598c61459f565b84600301546114b98c61459f565b905085811115612bac576040805162461bcd60e51b815260206004820152600b60248201526a4c494d49545f505249434560a81b604482015290519081900360640190fd5b600080612bbc89600954336114e3565b91509150612be88560030154612bd18e61459f565b8660030154612bdf8e61459f565b8d600854614285565b96508a871115612c2a576040805162461bcd60e51b81526020600482015260086024820152672624a6a4aa2fa4a760c11b604482015290519081900360640190fd5b612c3885600301548861506f565b8560030181905550612c4e84600301548a614727565b8460030181905550612c758560030154612c678e61459f565b86600301546114b98e61459f565b9550828610158015612c905750612c8c8783614f67565b8311155b612ccf576040805162461bcd60e51b815260206004820152600b60248201526a09a82a890be82a0a0a49eb60ab1b604482015290519081900360640190fd5b87861115612d12576040805162461bcd60e51b815260206004820152600b60248201526a4c494d49545f505249434560a81b604482015290519081900360640190fd5b896001600160a01b03168c6001600160a01b0316336001600160a01b03166000805160206158348339815191528a86604051808381526020018281526020019250505060405180910390a4612d688c33896150c3565b612d738a33846147a0565b600c54612d8b908b906001600160a01b0316836147a0565b600c546040805183815290516001600160a01b03808e1693169133916000805160206158948339815191529181900360200190a450505050506005805461ff001916905590969095509350505050565b60408051602080825236908201819052600092839233926001600160e01b03198535169285929081908101848480828437600083820152604051601f909101601f19169092018290039550909350505050a2612e35614318565b6005805461ff001916610100179055612e4c614361565b612e54614417565b612e5d8761447a565b612e668561447a565b600554600160b01b900460ff16612eb1576040805162461bcd60e51b815260206004820152600a6024820152694e4f545f5055424c494360b01b604482015290519081900360640190fd5b6001600160a01b038088166000908152600e6020526040808220928816825281206003830154909190612ee790612b598c61459f565b905085811115612f2c576040805162461bcd60e51b815260206004820152600b60248201526a4c494d49545f505249434560a81b604482015290519081900360640190fd5b600080612f3c8b600954336114e3565b91509150612f5a85600301546002670de0b6b3a7640000816124c657fe5b821115612f9d576040805162461bcd60e51b815260206004820152600c60248201526b4d41585f494e5f524154494f60a01b604482015290519081900360640190fd5b612fc58560030154612fae8e61459f565b8660030154612fbc8e61459f565b86600854613a57565b965088871015613008576040805162461bcd60e51b8152602060048201526009602482015268131253525517d3d55560ba1b604482015290519081900360640190fd5b61301685600301548361506f565b856003018190555061302c846003015488614727565b84600301819055506130458560030154612c678e61459f565b9550828610158015613060575061305c8288614f67565b8311155b61309f576040805162461bcd60e51b815260206004820152600b60248201526a09a82a890be82a0a0a49eb60ab1b604482015290519081900360640190fd5b878611156130e2576040805162461bcd60e51b815260206004820152600b60248201526a4c494d49545f505249434560a81b604482015290519081900360640190fd5b896001600160a01b03168c6001600160a01b0316336001600160a01b0316600080516020615834833981519152858b604051808381526020018281526020019250505060405180910390a46131388c338361522a565b6131438c33846150c3565b61314e8a33896147a0565b8b6001600160a01b0316600c60009054906101000a90046001600160a01b03166001600160a01b0316336001600160a01b0316600080516020615894833981519152846040518082815260200191505060405180910390a450505050506005805461ff001916905590969095509350505050565b6000806131cf8786614f67565b905060006131e5670de0b6b3a764000083614727565b905060006131f382866144d6565b9050600061320d876123e7670de0b6b3a764000085614727565b9050600061321b8c83614727565b90506000613229828e614f67565b90506000613237828861511c565b90506000613245828e6144d6565b905060006132538e83614727565b99505050505050505050509695505050505050565b6000806132758786614f67565b9050600061329461328e670de0b6b3a764000084614727565b856144d6565b905060006132b3866132ae670de0b6b3a764000085614727565b6144d6565b905060006132c18b8361506f565b905060006132cf828d614f67565b905060006132dd828761511c565b905060006132eb828d6144d6565b90506132f7818d614727565b9e9d5050505050505050505050505050565b64e8d4a51000670de0b6b3a76400006114d7565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2613386614318565b6005805461ff00191661010017905561339d6148bb565b60128290556013819055604080518381526020810183905281517fad659e822a6c18906bbabc64f81c2a16ce19173f83c8d0bacf028b507c9ee937929181900390910190a150506005805461ff0019169055565b6000806133fe8786614f67565b9050600061340c8786614727565b9050600061341a8289614f67565b9050600061343982613434670de0b6b3a764000087614f67565b61511c565b90506000613447828d6144d6565b905060006134558d83614727565b9050600061347461346e670de0b6b3a764000089614727565b8a6144d6565b90506132f7826132ae670de0b6b3a764000084614727565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a26134f5614318565b6005805461ff00191661010017905561350d8161447a565b604080516370a0823160e01b815230600482015290516001600160a01b038316916370a08231916024808301926020929190829003018186803b15801561355357600080fd5b505afa158015613567573d6000803e3d6000fd5b505050506040513d602081101561357d57600080fd5b50516001600160a01b039091166000908152600e60205260409020600301556005805461ff0019169055565b600c54600160a01b900460ff1690565b60006135c3614318565b506006546001600160a01b031690565b6000806000806135e1614318565b5050600954600a54600b54600c54929591945092506001600160a01b0390911690565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a261366d614318565b6005805461ff0019166101001790556136846148bb565b6005805461ff00196001600160a01b03909316620100000262010000600160b01b031990911617919091169055565b60006136bd614318565b6136c5614690565b905090565b68056bc75e2d6310000081565b60006136e1614318565b6136ea8261447a565b61129b8261459f565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156112365780601f1061120b57610100808354040283529160200191611236565b6704a03ce68d21555681565b600990565b6000806137728787614f67565b905060006137808686614f67565b9050600061378e8383614f67565b905060006137b0670de0b6b3a76400006123e7670de0b6b3a764000089614727565b90506137bc82826144d6565b9a9950505050505050505050565b60006137d733848461496c565b50600192915050565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2613849614318565b6005805461ff001916610100179055613860614361565b613868614417565b6138706143c9565b60008061388085600b54336114e3565b91509150600061388e6114c1565b9050600061389c8483614f67565b90506138a7816146e7565b6138b13388614789565b600c546138c7906001600160a01b031684614daa565b6138d084614797565b60005b600d54811015613a01576000600d82815481106138ec57fe5b60009182526020808320909101546001600160a01b0316808352600e90915260408220600301549092509061392185836144d6565b905061392c816146e7565b89898581811061393857fe5b9050602002013581101561397f576040805162461bcd60e51b8152602060048201526009602482015268131253525517d3d55560ba1b604482015290519081900360640190fd5b6001600160a01b0383166000908152600e60205260409020600301546139a59082614727565b6001600160a01b0384166000818152600e60209081526040918290206003019390935580518481529051919233926000805160206158748339815191529281900390910190a36139f68333836147a0565b5050506001016138d3565b50600c5460408051858152905130926001600160a01b03169133916000805160206158948339815191529181900360200190a450506005805461ff00191690555050505050565b600981565b600281565b600181565b600080613a648786614f67565b90506000613a7a670de0b6b3a764000085614727565b9050613a8685826144d6565b90506000613a988a6123e78c8561506f565b90506000613aa6828561511c565b90506000613abc670de0b6b3a764000083614727565b9050613ac88a826144d6565b9c9b505050505050505050505050565b600a670de0b6b3a76400006114d7565b671bc16d674ec7ffff81565b6060613afe614318565b613b066143c9565b600d80548060200260200160405190810160405280929190818152602001828054801561123657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613b3e575050505050905090565b670de0b6b3a764000081565b6000613b7b614318565b506007546001600160a01b031690565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2613bf4614318565b6005805461ff001916610100179055613c0b6148bb565b600780546001600160a01b0319166001600160a01b03929092169190911790556005805461ff0019169055565b6060613b06614318565b600d5490565b613c5181615288565b60408051606081018252600080825260208083018281528385018381526001600160a01b039096168352601190915292902090518155905160018201559051600290910155565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2613d01614318565b6005805461ff001916610100179055613d186148bb565b613d218461447a565b428211613d6f576040805162461bcd60e51b8152602060048201526017602482015276043414e545f5345545f504153545f54494d455354414d5604c1b604482015290519081900360640190fd5b818111613dbf576040805162461bcd60e51b815260206004820152601960248201527854494d455354414d505f494e434f52524543545f44454c544160381b604482015290519081900360640190fd5b633b9aca008310158015613ddc57506802b5e3af16b18800008311155b613e24576040805162461bcd60e51b81526020600482015260146024820152735441524745545f5745494748545f424f554e445360601b604482015290519081900360640190fd5b6000613e2f8561459f565b90506000613e3f828686866154a0565b9050601354811115613e90576040805162461bcd60e51b815260206004820152601560248201527413505617d5d15251d21517d4115497d4d150d3d391605a1b604482015290519081900360640190fd5b601254811015613edf576040805162461bcd60e51b815260206004820152601560248201527413525397d5d15251d21517d4115497d4d150d3d391605a1b604482015290519081900360640190fd5b6001600160a01b0386166000818152600e60209081526040808320600290810187905581516060810183528981528084018981528184018c8152968652601190945291842091518255915160018201559251920191909155600d54815b81811015613f9057613f868360116000600d8581548110613f5957fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190206002015461506f565b9250600101613f3c565b506802b5e3af16b1880000821115613fe9576040805162461bcd60e51b815260206004820152601760248201527613505617d5105491d15517d513d5105317d5d15251d215604a1b604482015290519081900360640190fd5b60408051858152602081018990528082018890526060810187905290516001600160a01b038a16917f0667af890d2d91f5a21a17df455617ff8f0fcc445cc6286d717c1144a1bcd001919081900360800190a250506005805461ff0019169055505050505050565b600061405b614318565b5060085490565b600061406d8361486d565b3360009081526001602090815260408083206001600160a01b038716845290915290205461409b908361506f565b3360008181526001602090815260408083206001600160a01b0389168085529083529281902085905580519485525191936000805160206158b4833981519152929081900390910190a350600192915050565b6012546013549091565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a261418c614318565b6005805461ff0019166101001790556141a36148bb565b600680546001600160a01b0319166001600160a01b03939093169290921760ff60a01b1916600160a01b911515919091021790556005805461ff0019169055565b6040805162461bcd60e51b8152602060048201526008602482015267111254d05093115160c21b604482015290519081900360640190fd5b6002670de0b6b3a76400006114d7565b6000614236614318565b61423f8261447a565b61129b61424b8361459f565b6123e7614690565b600061425d614318565b6142668261447a565b506001600160a01b03166000908152600e602052604090206003015490565b6000806142928588614f67565b905060006142a08786614727565b905060006142ae8883614f67565b905060006142bc828561511c565b90506142d081670de0b6b3a7640000614727565b90506142e4670de0b6b3a764000087614727565b94506142f96142f38c836144d6565b86614f67565b9b9a5050505050505050505050565b600554600160b01b900460ff1690565b600554610100900460ff161561435f576040805162461bcd60e51b81526020600482015260076024820152665245454e54525960c81b604482015290519081900360640190fd5b565b3260009081526010602052604090205443116143b5576040805162461bcd60e51b815260206004820152600e60248201526d29a0a6a2afaa2c2fa7a924a3a4a760911b604482015290519081900360640190fd5b326000908152601060205260409020439055565b600c54600160a01b900460ff1661435f576040805162461bcd60e51b815260206004820152600d60248201526c1393d517d19253905312569151609a1b604482015290519081900360640190fd5b600654600160a01b900460ff16158061443a57506006546001600160a01b031633145b61435f576040805162461bcd60e51b815260206004820152600c60248201526b27a7262cafaba920a82822a960a11b604482015290519081900360640190fd5b6001600160a01b0381166000908152600e602052604090205460ff166144d3576040805162461bcd60e51b81526020600482015260096024820152681393d517d093d5539160ba1b604482015290519081900360640190fd5b50565b60008282028315806144f05750828482816144ed57fe5b04145b614534576040805162461bcd60e51b815260206004820152601060248201526f4552525f4d554c5f4f564552464c4f5760801b604482015290519081900360640190fd5b6706f05b59d3b20000810181811015614587576040805162461bcd60e51b815260206004820152601060248201526f4552525f4d554c5f4f564552464c4f5760801b604482015290519081900360640190fd5b6000670de0b6b3a7640000825b049695505050505050565b60006145a96157f2565b506001600160a01b038216600081815260116020908152604080832081516060810183528154815260018201548185015260029182015481840152948452600e9092529091200154815115806146025750808260400151145b8061460e575081514211155b1561461c5791506117329050565b816020015142106146335750604001519050611732565b600061464d828460400151856000015186602001516154a0565b9050600061465f428560000151614727565b90508284604001511115614684576146798383830261506f565b945050505050611732565b61467983838302614727565b600d546000908190815b818110156146df576146d5836146d0600d84815481106146b657fe5b6000918252602090912001546001600160a01b031661459f565b61506f565b925060010161469a565b509091505090565b806144d3576040805162461bcd60e51b815260206004820152600b60248201526a09a82a890be82a0a0a49eb60ab1b604482015290519081900360640190fd5b600080600061473685856154e2565b915091508015614781576040805162461bcd60e51b81526020600482015260116024820152704552525f5355425f554e444552464c4f5760781b604482015290519081900360640190fd5b509392505050565b6147938282615507565b5050565b6144d381615512565b6000836001600160a01b031663a9059cbb84846040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156147f957600080fd5b505af115801561480d573d6000803e3d6000fd5b505050506040513d602081101561482357600080fd5b5051905080614867576040805162461bcd60e51b815260206004820152600b60248201526a45524332305f46414c534560a81b604482015290519081900360640190fd5b50505050565b6001600160a01b0381166144d3576040805162461bcd60e51b815260206004820152601060248201526f4552525f4e554c4c5f4144445245535360801b604482015290519081900360640190fd5b6005546201000090046001600160a01b0316331461435f576040805162461bcd60e51b815260206004820152600e60248201526d2727aa2fa1a7a72a2927a62622a960911b604482015290519081900360640190fd5b64e8d4a51000811080159061492e575067016345785d8a00008111155b6144d3576040805162461bcd60e51b815260206004820152600a6024820152694645455f424f554e445360b01b604482015290519081900360640190fd5b6001600160a01b0383166000908152602081905260409020548111156149d0576040805162461bcd60e51b815260206004820152601460248201527311549497d25394d551919250d251539517d0905360621b604482015290519081900360640190fd5b6149d98361486d565b6149e28261486d565b6001600160a01b038316600090815260208190526040902054614a059082614727565b6001600160a01b038085166000908152602081905260408082209390935590841681522054614a34908261506f565b6001600160a01b0380841660008181526020818152604091829020949094558051858152905191939287169260008051602061585483398151915292918290030190a3505050565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2614ae5614318565b6005805461ff001916610100179055614afc6148bb565b614b058361447a565b633b9aca008110158015614b2257506802b5e3af16b18800008111155b614b63576040805162461bcd60e51b815260206004820152600d60248201526c5745494748545f424f554e445360981b604482015290519081900360640190fd5b620f4240821015614ba9576040805162461bcd60e51b815260206004820152600b60248201526a4d494e5f42414c414e434560a81b604482015290519081900360640190fd5b6001600160a01b0383166000908152600e602052604090206002015480821115614be457614bdf614bda8383614727565b6144d3565b614bf9565b80821015614bf957614bf9614bda8284614727565b6001600160a01b0384166000908152600e602052604090206002810183905560030180549084905580841115614c4257614c3d8533614c388785614727565b6150c3565b614c65565b80841015614c65576000614c568286614727565b9050614c638633836147a0565b505b50506005805461ff0019169055505050565b600c54600160a01b900460ff161561435f576040805162461bcd60e51b815260206004820152600c60248201526b1254d7d1925390531256915160a21b604482015290519081900360640190fd5b6007546001600160a01b031615614da1576007546040805163afff324960e01b815230600482015290516000926001600160a01b03169163afff3249916024808301926020929190829003018186803b158015614d2157600080fd5b505afa158015614d35573d6000803e3d6000fd5b505050506040513d6020811015614d4b57600080fd5b50516002549091508190614d5f908461506f565b1115614d9f576040805162461bcd60e51b815260206004820152600a6024820152694d41585f535550504c5960b01b604482015290519081900360640190fd5b505b6144d3816155d0565b6147938282615633565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2614e1d6148bb565b6001600160a01b0383166000908152600e602052604090205460ff1615614e76576040805162461bcd60e51b81526020600482015260086024820152671254d7d093d5539160c21b604482015290519081900360640190fd5b600d54600911614eba576040805162461bcd60e51b815260206004820152600a6024820152694d41585f544f4b454e5360b01b604482015290519081900360640190fd5b604080516080810182526001808252600d805460208085019182526000858701818152606087018281526001600160a01b038c16808452600e9094529782209651875460ff1916901515178755925186860155915160028601559451600390940193909355805491820181559091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b03191690911790556118788383836117f9565b600081614faa576040805162461bcd60e51b815260206004820152600c60248201526b4552525f4449565f5a45524f60a01b604482015290519081900360640190fd5b670de0b6b3a76400008302831580614fd25750670de0b6b3a7640000848281614fcf57fe5b04145b615016576040805162461bcd60e51b815260206004820152601060248201526f11549497d1125597d25395115493905360821b604482015290519081900360640190fd5b60028304810181811015615064576040805162461bcd60e51b815260206004820152601060248201526f11549497d1125597d25395115493905360821b604482015290519081900360640190fd5b600084828161459457fe5b6000828201838110156150bc576040805162461bcd60e51b815260206004820152601060248201526f4552525f4144445f4f564552464c4f5760801b604482015290519081900360640190fd5b9392505050565b604080516323b872dd60e01b81526001600160a01b0384811660048301523060248301526044820184905291516000928616916323b872dd91606480830192602092919082900301818787803b1580156147f957600080fd5b6000600183101561516c576040805162461bcd60e51b81526020600482015260156024820152744552525f42504f575f424153455f544f4f5f4c4f5760581b604482015290519081900360640190fd5b671bc16d674ec7ffff8311156151c2576040805162461bcd60e51b815260206004820152601660248201527508aa4a4be84a09eaebe8482a68abea89e9ebe90928e960531b604482015290519081900360640190fd5b60006151cd8361563e565b905060006151db8483614727565b905060006151f1866151ec85615659565b615667565b90508161520257925061129b915050565b600061521387846305f5e1006156be565b905061521f82826144d6565b979650505050505050565b600c54604080516323b872dd60e01b81526001600160a01b03858116600483015292831660248201526044810184905290516000928616916323b872dd91606480830192602092919082900301818787803b1580156147f957600080fd5b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a26152f1614318565b6005805461ff0019166101001790556153086148bb565b6153118161447a565b6001600160a01b0381166000908152600e60205260409020600381015460029091015461533d906144d3565b6001600160a01b0382166000908152600e6020526040902060010154600d8054600019810191908290811061536e57fe5b600091825260209091200154600d80546001600160a01b03909216918490811061539457fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555081600e6000600d85815481106153d457fe5b60009182526020808320909101546001600160a01b03168352820192909252604001902060010155600d80548061540757fe5b60008281526020808220600019908401810180546001600160a01b031916905590920190925560408051608081018252838152808301848152818301858152606083018681526001600160a01b038b168752600e909552929094209051815460ff1916901515178155925160018401555160028301555160039091015561548f8433856147a0565b50506005805461ff00191690555050565b6000808585116154b9576154b48686614727565b6154c3565b6154c38587614727565b90506154d8816154d38587614727565b61579c565b9695505050505050565b6000808284106154f85750508082036000615500565b505081810360015b9250929050565b61479382308361496c565b3060009081526020819052604090205481111561556d576040805162461bcd60e51b815260206004820152601460248201527311549497d25394d551919250d251539517d0905360621b604482015290519081900360640190fd5b306000908152602081905260409020546155879082614727565b306000908152602081905260409020556002546155a49082614727565b60025560408051828152905160009130916000805160206158548339815191529181900360200190a350565b306000908152602081905260409020546155ea908261506f565b30600090815260208190526040902055600254615607908261506f565b60025560408051828152905130916000916000805160206158548339815191529181900360200190a350565b61479330838361496c565b6000670de0b6b3a764000061565283615659565b0292915050565b670de0b6b3a7640000900490565b6000806002830661568057670de0b6b3a7640000615682565b835b90506002830492505b82156150bc5761569b84856144d6565b935060028306156156b3576156b081856144d6565b90505b60028304925061568b565b60008281806156d587670de0b6b3a76400006154e2565b9092509050670de0b6b3a764000080600060015b88841061578d576000670de0b6b3a76400008202905060008061571d8a61571885670de0b6b3a7640000614727565b6154e2565b9150915061572f876132ae848c6144d6565b965061573b8784614f67565b96508661574a5750505061578d565b8715615754579315935b801561575e579315935b84156157755761576e8688614727565b9550615782565b61577f868861506f565b95505b5050506001016156e9565b50909998505050505050505050565b60008082116157e1576040805162461bcd60e51b815260206004820152600c60248201526b4552525f4449565f5a45524f60a01b604482015290519081900360640190fd5b8183816157ea57fe5b049392505050565b6040518060600160405280600081526020016000815260200160008152509056fe63982df10efd8dfaaaa0fcc7f50b2d93b7cba26ccc48adee2873220d485dc39a908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efe74c91552b64c2e2e7bd255639e004e693bd3e1d01cc33e65610b86afcc1ffed5b5ddc912843b56bbfa1620dc5a27cc3b1b82c88ab626118af8dc1319b4a86568c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a264697066735822122062589b3b35fe5b3ab79b385208b3967cb5281ecde120ea0669764a48e9b0608264736f6c634300060c0033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000004b3090ab80100000000000000000000000000000000000000000000000000000d287fb79cd10000000000000000000000000000000000000000000000000000000000000016506f77657220496e64657820506f6f6c20546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000045049505400000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103855760003560e01c806302c967481461038a57806306fdde03146103ce578063095ea7b31461044b57806309a3bbe41461048b5780630f7b1e3e146104935780631446a7ff146104cd57806315e84af9146104fb57806318160ddd14610529578063189d00ca14610531578063218b5382146105395780632245a08e1461054157806323b872dd1461058c5780632f37b624146105c25780633018205f146105e8578063313ce5671461060c57806334e199071461062a5780633fdddaa21461064757806341e5a5d414610679578063442e2152146106c557806346ab38f11461075257806349b59552146107845780634bb278f3146107a35780634d752ec3146107ab5780634f69c0d4146107e95780635c1bbaf71461085e5780635db342771461089957806366188463146108cb57806367cc71f0146108f75780636d06dfa0146108ff57806370a082311461093157806370eb8e7f1461095757806376c7a3c71461095f5780637c5e9ea4146109675780638201aa3f146109a757806382f652ad146109e75780638656b65314610a22578063867378c514610a5d5780638733ad7114610a655780638929801214610a885780638c28cbe814610ac35780638d4e408314610ae95780638f6b707014610af157806390ad688b14610af957806392eefe9b14610b30578063936c347714610b565780639381cd2b14610b5e578063948d8ce614610b6657806395d89b4114610b8c578063992e2a9214610b945780639a737aa214610b9c578063a221ee4914610ba4578063a9059cbb14610bd9578063b02f0b7314610c05578063b0e0d13614610c7a578063b7b800a414610c82578063ba019dab14610c8a578063ba9530a614610c92578063bc063e1a14610ccd578063bc694ea214610cd5578063be3bbd2e14610cdd578063c36596a614610d35578063c4195cb814610d3d578063c61641cd14610d45578063cc77828d14610d6b578063cd2ed8fb14610d73578063cf5e7bd314610d7b578063cfb2794514610da1578063d4cadf6814610dd9578063d73dd62314610de1578063d80817fb14610e0d578063dd62ed3e14610e15578063e0e5228d14610e43578063e4a28a521461048b578063e4e1e53814610e71578063ec09302114610ea3578063f1b8a9b714610eab578063f8b2cb4f14610ed1578063f8d6aed414610ef7578063fde924f714610f32575b600080fd5b6103bc600480360360608110156103a057600080fd5b506001600160a01b038135169060208101359060400135610f3a565b60408051918252519081900360200190f35b6103d66111aa565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104105781810151838201526020016103f8565b50505050905090810190601f16801561043d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6104776004803603604081101561046157600080fd5b506001600160a01b038135169060200135611240565b604080519115158252519081900360200190f35b6103bc6112a1565b6104cb600480360360808110156104a957600080fd5b50803590602081013590604081013590606001356001600160a01b03166112ae565b005b6103bc600480360360408110156104e357600080fd5b506001600160a01b0381358116916020013516611384565b6103bc6004803603604081101561051157600080fd5b506001600160a01b03813581169160200135166113f1565b6103bc6114c1565b6103bc6114c7565b6103bc6114db565b6105736004803603606081101561055757600080fd5b50803590602081013590604001356001600160a01b03166114e3565b6040805192835260208301919091528051918290030190f35b610477600480360360608110156105a257600080fd5b506001600160a01b038135811691602081013590911690604001356115bf565b610477600480360360208110156105d857600080fd5b50356001600160a01b0316611715565b6105f0611737565b604080516001600160a01b039092168252519081900360200190f35b610614611757565b6040805160ff9092168252519081900360200190f35b6104cb6004803603602081101561064057600080fd5b5035611760565b6104cb6004803603606081101561065d57600080fd5b506001600160a01b0381351690602081013590604001356117f9565b61069f6004803603602081101561068f57600080fd5b50356001600160a01b031661187d565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6104cb600480360360808110156106db57600080fd5b6001600160a01b03823516916001600160e01b031960208201351691810190606081016040820135600160201b81111561071457600080fd5b82018360208201111561072657600080fd5b803590602001918460018302840111600160201b8311171561074757600080fd5b9193509150356118b7565b6103bc6004803603606081101561076857600080fd5b506001600160a01b038135169060208101359060400135611c1f565b6104cb6004803603602081101561079a57600080fd5b50351515611e8d565b6104cb611f38565b6104cb600480360360a08110156107c157600080fd5b506001600160a01b03813516906020810135906040810135906060810135906080013561205d565b6104cb600480360360408110156107ff57600080fd5b81359190810190604081016020820135600160201b81111561082057600080fd5b82018360208201111561083257600080fd5b803590602001918460208302840111600160201b8311171561085357600080fd5b5090925090506120e0565b6103bc600480360360c081101561087457600080fd5b5080359060208101359060408101359060608101359060808101359060a00135612347565b6103bc600480360360608110156108af57600080fd5b506001600160a01b0381351690602081013590604001356123ff565b610477600480360360408110156108e157600080fd5b506001600160a01b03813516906020013561265a565b61047761273d565b6103bc6004803603606081101561091557600080fd5b506001600160a01b038135169060208101359060400135612758565b6103bc6004803603602081101561094757600080fd5b50356001600160a01b03166129c2565b6103bc6129dd565b6103bc6129e5565b610573600480360360a081101561097d57600080fd5b506001600160a01b03813581169160208101359160408201351690606081013590608001356129f7565b610573600480360360a08110156109bd57600080fd5b506001600160a01b0381358116916020810135916040820135169060608101359060800135612ddb565b6103bc600480360360c08110156109fd57600080fd5b5080359060208101359060408101359060608101359060808101359060a001356131c2565b6103bc600480360360c0811015610a3857600080fd5b5080359060208101359060408101359060608101359060808101359060a00135613268565b6103bc613309565b6104cb60048036036040811015610a7b57600080fd5b508035906020013561331d565b6103bc600480360360c0811015610a9e57600080fd5b5080359060208101359060408101359060608101359060808101359060a001356133f1565b6104cb60048036036020811015610ad957600080fd5b50356001600160a01b031661348c565b6104776135a9565b6105f06135b9565b610b016135d3565b604080519485526020850193909352838301919091526001600160a01b03166060830152519081900360800190f35b6104cb60048036036020811015610b4657600080fd5b50356001600160a01b0316613604565b6103bc6136b3565b6103bc6136ca565b6103bc60048036036020811015610b7c57600080fd5b50356001600160a01b03166136d7565b6103d66136f3565b6103bc613754565b6103bc613760565b6103bc600480360360a0811015610bba57600080fd5b5080359060208101359060408101359060608101359060800135613765565b61047760048036036040811015610bef57600080fd5b506001600160a01b0381351690602001356137ca565b6104cb60048036036040811015610c1b57600080fd5b81359190810190604081016020820135600160201b811115610c3c57600080fd5b820183602082011115610c4e57600080fd5b803590602001918460208302840111600160201b83111715610c6f57600080fd5b5090925090506137e0565b6103bc613a48565b6103bc613a4d565b6103bc613a52565b6103bc600480360360c0811015610ca857600080fd5b5080359060208101359060408101359060608101359060808101359060a00135613a57565b6103bc613ad8565b6103bc613ae8565b610ce5613af4565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610d21578181015183820152602001610d09565b505050509050019250505060405180910390f35b6103bc613b65565b6105f0613b71565b6104cb60048036036020811015610d5b57600080fd5b50356001600160a01b0316613b8b565b610ce5613c38565b6103bc613c42565b6104cb60048036036020811015610d9157600080fd5b50356001600160a01b0316613c48565b6104cb60048036036080811015610db757600080fd5b506001600160a01b038135169060208101359060408101359060600135613c98565b6103bc614051565b61047760048036036040811015610df757600080fd5b506001600160a01b038135169060200135614062565b6105736140ee565b6103bc60048036036040811015610e2b57600080fd5b506001600160a01b03813581169160200135166140f8565b6104cb60048036036040811015610e5957600080fd5b506001600160a01b0381351690602001351515614123565b6104cb60048036036060811015610e8757600080fd5b506001600160a01b0381351690602081013590604001356141e4565b6103bc61421c565b6103bc60048036036020811015610ec157600080fd5b50356001600160a01b031661422c565b6103bc60048036036020811015610ee757600080fd5b50356001600160a01b0316614253565b6103bc600480360360c0811015610f0d57600080fd5b5080359060208101359060408101359060608101359060808101359060a00135614285565b610477614308565b6000336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2610fa5614318565b6005805461ff001916610100179055610fbc614361565b610fc46143c9565b610fcc614417565b610fd58461447a565b6001600160a01b0384166000908152600e6020526040902060039081015461100a91670de0b6b3a76400005b046001016144d6565b83111561104a576040805162461bcd60e51b81526020600482015260096024820152684f55545f524154494f60b81b604482015290519081900360640190fd5b6001600160a01b0384166000908152600e60205260408120600b549091908190611076908790336114e3565b9150915061109f836003015461108b8961459f565b600254611096614690565b8a6008546131c2565b93506110aa846146e7565b848411156110ea576040805162461bcd60e51b81526020600482015260086024820152672624a6a4aa2fa4a760c11b604482015290519081900360640190fd5b6110f8836003015487614727565b60038401556040805183815290516001600160a01b0389169133916000805160206158748339815191529181900360200190a36111353385614789565b61113e84614797565b6111498733846147a0565b600c546111619088906001600160a01b0316836147a0565b600c546040805183815290516001600160a01b03808b1693169133916000805160206158948339815191529181900360200190a45050506005805461ff00191690559392505050565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156112365780601f1061120b57610100808354040283529160200191611236565b820191906000526020600020905b81548152906001019060200180831161121957829003601f168201915b5050505050905090565b600061124b8361486d565b3360008181526001602090815260408083206001600160a01b03881680855290835292819020869055805186815290519293926000805160206158b4833981519152929181900390910190a35060015b92915050565b6802b5e3af16b188000081565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2611317614318565b6005805461ff00191661010017905561132e6148bb565b61133784614911565b61134083614911565b61134982614911565b600993909355600a91909155600b55600c80546001600160a01b0319166001600160a01b039092169190911790556005805461ff0019169055565b600061138e614318565b6113978361447a565b6113a08261447a565b6001600160a01b038084166000908152600e60205260408082209285168252902060038201546113e8906113d38761459f565b83600301546113e18861459f565b6000613765565b95945050505050565b60006113fb614318565b6001600160a01b0383166000908152600e602052604090205460ff16801561143b57506001600160a01b0382166000908152600e602052604090205460ff165b611478576040805162461bcd60e51b81526020600482015260096024820152681393d517d093d5539160ba1b604482015290519081900360640190fd5b6001600160a01b038084166000908152600e60205260408082209285168252902060038201546113e8906114ab8761459f565b83600301546114b98861459f565b600854613765565b60025490565b6402540be400670de0b6b3a76400005b0481565b633b9aca0081565b60075460009081906001600160a01b031615801590611577575060075460408051630a499ad360e01b81526001600160a01b03868116600483015291519190921691630a499ad3916024808301926020929190829003018186803b15801561154a57600080fd5b505afa15801561155e573d6000803e3d6000fd5b505050506040513d602081101561157457600080fd5b50515b15611587575083905060006115b7565b600061159b670de0b6b3a764000086614727565b90506115a786826144d6565b92506115b38684614727565b9150505b935093915050565b6000336001600160a01b03851614806115fb57506001600160a01b03841660009081526001602090815260408083203384529091529020548211155b611644576040805162461bcd60e51b815260206004820152601560248201527422a9292fa12a27a5a2a72fa120a22fa1a0a62622a960591b604482015290519081900360640190fd5b61164f84848461496c565b336001600160a01b0385161480159061168d57506001600160a01b038416600090815260016020908152604080832033845290915290205460001914155b1561170b576001600160a01b03841660009081526001602090815260408083203384529091529020546116c09083614727565b6001600160a01b0385166000818152600160209081526040808320338085529083529281902085905580519485525191936000805160206158b4833981519152929081900390910190a35b5060019392505050565b6001600160a01b0381166000908152600e602052604090205460ff165b919050565b6000611741614318565b506005546201000090046001600160a01b031690565b60055460ff1690565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a26117c9614318565b6005805461ff0019166101001790556117e06148bb565b6117e981614911565b6008556005805461ff0019169055565b633b9aca008114801561182257506001600160a01b038316600090815260116020526040902054155b61186d576040805162461bcd60e51b815260206004820152601760248201527613d3931657d39155d7d513d2d15394d7d0531313d5d151604a1b604482015290519081900360640190fd5b611878838383614a7c565b505050565b6001600160a01b0316600090815260116020908152604080832080546001820154600e909452919093206002908101549301549093919291565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2611920614318565b6005805461ff0019166101001790556007546040805163ea3457b760e01b81526001600160a01b0388811660048301526001600160e01b0319881660248301529151919092169163ea3457b7916044808301926020929190829003018186803b15801561198c57600080fd5b505afa1580156119a0573d6000803e3d6000fd5b505050506040513d60208110156119b657600080fd5b50516119fb576040805162461bcd60e51b815260206004820152600f60248201526e4e4f545f414c4c4f5745445f53494760881b604482015290519081900360640190fd5b611a036148bb565b60006060866001600160a01b03168387878760405160200180846001600160e01b03191681526004018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310611a7c5780518252601f199092019160209182019101611a5d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611ade576040519150601f19603f3d011682016040523d82523d6000602084013e611ae3565b606091505b509150915081611b28576040805162461bcd60e51b815260206004820152600b60248201526a4e4f545f5355434345535360a81b604482015290519081900360640190fd5b856001600160e01b031916821515886001600160a01b03167f32258dd51d74a04508615e0840c1fc905dff28c96b7335e69d9a41023ecd286e88888660405180806020018060200183810383528686828181526020019250808284376000838201819052601f909101601f191690920185810384528651815286516020918201939188019250908190849084905b83811015611bce578181015183820152602001611bb6565b50505050905090810190601f168015611bfb5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a450506005805461ff00191690555050505050565b6000336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2611c8a614318565b6005805461ff001916610100179055611ca1614361565b611ca96143c9565b611cb1614417565b611cba8461447a565b6001600160a01b0384166000908152600e602052604090206003810154611cf890611ce48761459f565b600254611cef614690565b886008546133f1565b915082821015611d3b576040805162461bcd60e51b8152602060048201526009602482015268131253525517d3d55560ba1b604482015290519081900360640190fd5b6001600160a01b0385166000908152600e60205260409020600390810154611d6b91670de0b6b3a7640000611001565b821115611dab576040805162461bcd60e51b81526020600482015260096024820152684f55545f524154494f60b81b604482015290519081900360640190fd5b611db9816003015483614727565b8160030181905550600080611dd184600b54336114e3565b91509150866001600160a01b0316336001600160a01b0316600080516020615874833981519152846040518082815260200191505060405180910390a3611e183387614789565b611e2186614797565b611e2c8733846147a0565b600c54611e449088906001600160a01b0316836147a0565b600c546040805183815290516001600160a01b03808b1693169133916000805160206158948339815191529181900360200190a4506005805461ff001916905595945050505050565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2611ef6614318565b6005805461ff001916610100179055611f0d614c77565b611f156148bb565b6005805461ff0019921515600160b01b0260ff60b01b1990911617919091169055565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2611fa1614318565b6005805461ff001916610100179055611fb86148bb565b611fc0614c77565b600d5460021115612005576040805162461bcd60e51b815260206004820152600a6024820152694d494e5f544f4b454e5360b01b604482015290519081900360640190fd5b600c805460ff60a01b1916600160a01b1790556005805460ff60b01b1916600160b01b17905561203d68056bc75e2d63100000614cc5565b6120503368056bc75e2d63100000614daa565b6005805461ff0019169055565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a26120cd8585633b9aca00614db4565b6120d985848484613c98565b5050505050565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2612149614318565b6005805461ff001916610100179055612160614361565b612168614417565b6121706143c9565b600061217a6114c1565b905060006121888583614f67565b9050612193816146e7565b60005b600d548110156122c3576000600d82815481106121af57fe5b60009182526020808320909101546001600160a01b0316808352600e9091526040822060030154909250906121e485836144d6565b90506121ef816146e7565b8787858181106121fb57fe5b90506020020135811115612241576040805162461bcd60e51b81526020600482015260086024820152672624a6a4aa2fa4a760c11b604482015290519081900360640190fd5b6001600160a01b0383166000908152600e6020526040902060030154612267908261506f565b6001600160a01b0384166000818152600e60209081526040918290206003019390935580518481529051919233926000805160206158148339815191529281900390910190a36122b88333836150c3565b505050600101612196565b506000806122d487600a54336114e3565b915091506122e187614cc5565b6122eb3383614daa565b600c54612301906001600160a01b031682614daa565b600c5460408051838152905130926001600160a01b03169133916000805160206158948339815191529181900360200190a450506005805461ff00191690555050505050565b6000806123548786614f67565b90506000612362878661506f565b905060006123708289614f67565b90506000612386670de0b6b3a764000085614f67565b90506000612394838361511c565b905060006123a2828e6144d6565b905060006123b0828f614727565b905060006123cf6123c9670de0b6b3a76400008a614727565b8b6144d6565b90506123ec826123e7670de0b6b3a764000084614727565b614f67565b9f9e505050505050505050505050505050565b6000336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a261246a614318565b6005805461ff001916610100179055612481614361565b6124896143c9565b612491614417565b61249a8461447a565b6001600160a01b0384166000908152600e60205260409020600301546124cc906002670de0b6b3a76400005b046144d6565b83111561250f576040805162461bcd60e51b815260206004820152600c60248201526b4d41585f494e5f524154494f60a01b604482015290519081900360640190fd5b60008061251f85600a54336114e3565b6001600160a01b0388166000908152600e60205260409020600381015492945090925090612564906125508961459f565b60025461255b614690565b87600854613268565b9350848410156125a7576040805162461bcd60e51b8152602060048201526009602482015268131253525517d3d55560ba1b604482015290519081900360640190fd5b6125b581600301548461506f565b60038201556040805184815290516001600160a01b0389169133916000805160206158148339815191529181900360200190a36125f184614cc5565b6125fb3385614daa565b61260687338461522a565b6126118733856150c3565b600c546040805184815290516001600160a01b03808b1693169133916000805160206158948339815191529181900360200190a45050506005805461ff00191690559392505050565b60006126658361486d565b3360009081526001602090815260408083206001600160a01b0387168452909152902054808311156126ba573360009081526001602090815260408083206001600160a01b03881684529091528120556126e9565b6126c48184614727565b3360009081526001602090815260408083206001600160a01b03891684529091529020555b3360008181526001602090815260408083206001600160a01b0389168085529083529281902054815190815290519293926000805160206158b4833981519152929181900390910190a35060019392505050565b6000612747614318565b50600654600160a01b900460ff1690565b6000336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a26127c3614318565b6005805461ff0019166101001790556127da614361565b6127e26143c9565b6127ea614417565b6127f38461447a565b6001600160a01b0384166000908152600e60205260408120600a54909190819061281f908790336114e3565b9150915061284883600301546128348961459f565b60025461283f614690565b8a600854612347565b9350612853846146e7565b84841115612893576040805162461bcd60e51b81526020600482015260086024820152672624a6a4aa2fa4a760c11b604482015290519081900360640190fd5b6001600160a01b0387166000908152600e60205260409020600301546128c3906002670de0b6b3a76400006124c6565b841115612906576040805162461bcd60e51b815260206004820152600c60248201526b4d41585f494e5f524154494f60a01b604482015290519081900360640190fd5b61291483600301548561506f565b60038401556040805185815290516001600160a01b0389169133916000805160206158148339815191529181900360200190a361295086614cc5565b61295a3383614daa565b600c54612970906001600160a01b031682614daa565b61297b8733866150c3565b600c5460408051838152905130926001600160a01b03169133916000805160206158948339815191529181900360200190a45050506005805461ff00191690559392505050565b6001600160a01b031660009081526020819052604090205490565b633b9aca0090565b620f4240670de0b6b3a76400006114d7565b60408051602080825236908201819052600092839233926001600160e01b03198535169285929081908101848480828437600083820152604051601f909101601f19169092018290039550909350505050a2612a51614318565b6005805461ff001916610100179055612a68614361565b612a70614417565b612a798761447a565b612a828561447a565b600554600160b01b900460ff16612acd576040805162461bcd60e51b815260206004820152600a6024820152694e4f545f5055424c494360b01b604482015290519081900360640190fd5b6001600160a01b038088166000908152600e602052604080822092881682529020600380820154612b0691670de0b6b3a7640000611001565b861115612b46576040805162461bcd60e51b81526020600482015260096024820152684f55545f524154494f60b81b604482015290519081900360640190fd5b6000612b678360030154612b598c61459f565b84600301546114b98c61459f565b905085811115612bac576040805162461bcd60e51b815260206004820152600b60248201526a4c494d49545f505249434560a81b604482015290519081900360640190fd5b600080612bbc89600954336114e3565b91509150612be88560030154612bd18e61459f565b8660030154612bdf8e61459f565b8d600854614285565b96508a871115612c2a576040805162461bcd60e51b81526020600482015260086024820152672624a6a4aa2fa4a760c11b604482015290519081900360640190fd5b612c3885600301548861506f565b8560030181905550612c4e84600301548a614727565b8460030181905550612c758560030154612c678e61459f565b86600301546114b98e61459f565b9550828610158015612c905750612c8c8783614f67565b8311155b612ccf576040805162461bcd60e51b815260206004820152600b60248201526a09a82a890be82a0a0a49eb60ab1b604482015290519081900360640190fd5b87861115612d12576040805162461bcd60e51b815260206004820152600b60248201526a4c494d49545f505249434560a81b604482015290519081900360640190fd5b896001600160a01b03168c6001600160a01b0316336001600160a01b03166000805160206158348339815191528a86604051808381526020018281526020019250505060405180910390a4612d688c33896150c3565b612d738a33846147a0565b600c54612d8b908b906001600160a01b0316836147a0565b600c546040805183815290516001600160a01b03808e1693169133916000805160206158948339815191529181900360200190a450505050506005805461ff001916905590969095509350505050565b60408051602080825236908201819052600092839233926001600160e01b03198535169285929081908101848480828437600083820152604051601f909101601f19169092018290039550909350505050a2612e35614318565b6005805461ff001916610100179055612e4c614361565b612e54614417565b612e5d8761447a565b612e668561447a565b600554600160b01b900460ff16612eb1576040805162461bcd60e51b815260206004820152600a6024820152694e4f545f5055424c494360b01b604482015290519081900360640190fd5b6001600160a01b038088166000908152600e6020526040808220928816825281206003830154909190612ee790612b598c61459f565b905085811115612f2c576040805162461bcd60e51b815260206004820152600b60248201526a4c494d49545f505249434560a81b604482015290519081900360640190fd5b600080612f3c8b600954336114e3565b91509150612f5a85600301546002670de0b6b3a7640000816124c657fe5b821115612f9d576040805162461bcd60e51b815260206004820152600c60248201526b4d41585f494e5f524154494f60a01b604482015290519081900360640190fd5b612fc58560030154612fae8e61459f565b8660030154612fbc8e61459f565b86600854613a57565b965088871015613008576040805162461bcd60e51b8152602060048201526009602482015268131253525517d3d55560ba1b604482015290519081900360640190fd5b61301685600301548361506f565b856003018190555061302c846003015488614727565b84600301819055506130458560030154612c678e61459f565b9550828610158015613060575061305c8288614f67565b8311155b61309f576040805162461bcd60e51b815260206004820152600b60248201526a09a82a890be82a0a0a49eb60ab1b604482015290519081900360640190fd5b878611156130e2576040805162461bcd60e51b815260206004820152600b60248201526a4c494d49545f505249434560a81b604482015290519081900360640190fd5b896001600160a01b03168c6001600160a01b0316336001600160a01b0316600080516020615834833981519152858b604051808381526020018281526020019250505060405180910390a46131388c338361522a565b6131438c33846150c3565b61314e8a33896147a0565b8b6001600160a01b0316600c60009054906101000a90046001600160a01b03166001600160a01b0316336001600160a01b0316600080516020615894833981519152846040518082815260200191505060405180910390a450505050506005805461ff001916905590969095509350505050565b6000806131cf8786614f67565b905060006131e5670de0b6b3a764000083614727565b905060006131f382866144d6565b9050600061320d876123e7670de0b6b3a764000085614727565b9050600061321b8c83614727565b90506000613229828e614f67565b90506000613237828861511c565b90506000613245828e6144d6565b905060006132538e83614727565b99505050505050505050509695505050505050565b6000806132758786614f67565b9050600061329461328e670de0b6b3a764000084614727565b856144d6565b905060006132b3866132ae670de0b6b3a764000085614727565b6144d6565b905060006132c18b8361506f565b905060006132cf828d614f67565b905060006132dd828761511c565b905060006132eb828d6144d6565b90506132f7818d614727565b9e9d5050505050505050505050505050565b64e8d4a51000670de0b6b3a76400006114d7565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2613386614318565b6005805461ff00191661010017905561339d6148bb565b60128290556013819055604080518381526020810183905281517fad659e822a6c18906bbabc64f81c2a16ce19173f83c8d0bacf028b507c9ee937929181900390910190a150506005805461ff0019169055565b6000806133fe8786614f67565b9050600061340c8786614727565b9050600061341a8289614f67565b9050600061343982613434670de0b6b3a764000087614f67565b61511c565b90506000613447828d6144d6565b905060006134558d83614727565b9050600061347461346e670de0b6b3a764000089614727565b8a6144d6565b90506132f7826132ae670de0b6b3a764000084614727565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a26134f5614318565b6005805461ff00191661010017905561350d8161447a565b604080516370a0823160e01b815230600482015290516001600160a01b038316916370a08231916024808301926020929190829003018186803b15801561355357600080fd5b505afa158015613567573d6000803e3d6000fd5b505050506040513d602081101561357d57600080fd5b50516001600160a01b039091166000908152600e60205260409020600301556005805461ff0019169055565b600c54600160a01b900460ff1690565b60006135c3614318565b506006546001600160a01b031690565b6000806000806135e1614318565b5050600954600a54600b54600c54929591945092506001600160a01b0390911690565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a261366d614318565b6005805461ff0019166101001790556136846148bb565b6005805461ff00196001600160a01b03909316620100000262010000600160b01b031990911617919091169055565b60006136bd614318565b6136c5614690565b905090565b68056bc75e2d6310000081565b60006136e1614318565b6136ea8261447a565b61129b8261459f565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156112365780601f1061120b57610100808354040283529160200191611236565b6704a03ce68d21555681565b600990565b6000806137728787614f67565b905060006137808686614f67565b9050600061378e8383614f67565b905060006137b0670de0b6b3a76400006123e7670de0b6b3a764000089614727565b90506137bc82826144d6565b9a9950505050505050505050565b60006137d733848461496c565b50600192915050565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2613849614318565b6005805461ff001916610100179055613860614361565b613868614417565b6138706143c9565b60008061388085600b54336114e3565b91509150600061388e6114c1565b9050600061389c8483614f67565b90506138a7816146e7565b6138b13388614789565b600c546138c7906001600160a01b031684614daa565b6138d084614797565b60005b600d54811015613a01576000600d82815481106138ec57fe5b60009182526020808320909101546001600160a01b0316808352600e90915260408220600301549092509061392185836144d6565b905061392c816146e7565b89898581811061393857fe5b9050602002013581101561397f576040805162461bcd60e51b8152602060048201526009602482015268131253525517d3d55560ba1b604482015290519081900360640190fd5b6001600160a01b0383166000908152600e60205260409020600301546139a59082614727565b6001600160a01b0384166000818152600e60209081526040918290206003019390935580518481529051919233926000805160206158748339815191529281900390910190a36139f68333836147a0565b5050506001016138d3565b50600c5460408051858152905130926001600160a01b03169133916000805160206158948339815191529181900360200190a450506005805461ff00191690555050505050565b600981565b600281565b600181565b600080613a648786614f67565b90506000613a7a670de0b6b3a764000085614727565b9050613a8685826144d6565b90506000613a988a6123e78c8561506f565b90506000613aa6828561511c565b90506000613abc670de0b6b3a764000083614727565b9050613ac88a826144d6565b9c9b505050505050505050505050565b600a670de0b6b3a76400006114d7565b671bc16d674ec7ffff81565b6060613afe614318565b613b066143c9565b600d80548060200260200160405190810160405280929190818152602001828054801561123657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613b3e575050505050905090565b670de0b6b3a764000081565b6000613b7b614318565b506007546001600160a01b031690565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2613bf4614318565b6005805461ff001916610100179055613c0b6148bb565b600780546001600160a01b0319166001600160a01b03929092169190911790556005805461ff0019169055565b6060613b06614318565b600d5490565b613c5181615288565b60408051606081018252600080825260208083018281528385018381526001600160a01b039096168352601190915292902090518155905160018201559051600290910155565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2613d01614318565b6005805461ff001916610100179055613d186148bb565b613d218461447a565b428211613d6f576040805162461bcd60e51b8152602060048201526017602482015276043414e545f5345545f504153545f54494d455354414d5604c1b604482015290519081900360640190fd5b818111613dbf576040805162461bcd60e51b815260206004820152601960248201527854494d455354414d505f494e434f52524543545f44454c544160381b604482015290519081900360640190fd5b633b9aca008310158015613ddc57506802b5e3af16b18800008311155b613e24576040805162461bcd60e51b81526020600482015260146024820152735441524745545f5745494748545f424f554e445360601b604482015290519081900360640190fd5b6000613e2f8561459f565b90506000613e3f828686866154a0565b9050601354811115613e90576040805162461bcd60e51b815260206004820152601560248201527413505617d5d15251d21517d4115497d4d150d3d391605a1b604482015290519081900360640190fd5b601254811015613edf576040805162461bcd60e51b815260206004820152601560248201527413525397d5d15251d21517d4115497d4d150d3d391605a1b604482015290519081900360640190fd5b6001600160a01b0386166000818152600e60209081526040808320600290810187905581516060810183528981528084018981528184018c8152968652601190945291842091518255915160018201559251920191909155600d54815b81811015613f9057613f868360116000600d8581548110613f5957fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190206002015461506f565b9250600101613f3c565b506802b5e3af16b1880000821115613fe9576040805162461bcd60e51b815260206004820152601760248201527613505617d5105491d15517d513d5105317d5d15251d215604a1b604482015290519081900360640190fd5b60408051858152602081018990528082018890526060810187905290516001600160a01b038a16917f0667af890d2d91f5a21a17df455617ff8f0fcc445cc6286d717c1144a1bcd001919081900360800190a250506005805461ff0019169055505050505050565b600061405b614318565b5060085490565b600061406d8361486d565b3360009081526001602090815260408083206001600160a01b038716845290915290205461409b908361506f565b3360008181526001602090815260408083206001600160a01b0389168085529083529281902085905580519485525191936000805160206158b4833981519152929081900390910190a350600192915050565b6012546013549091565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a261418c614318565b6005805461ff0019166101001790556141a36148bb565b600680546001600160a01b0319166001600160a01b03939093169290921760ff60a01b1916600160a01b911515919091021790556005805461ff0019169055565b6040805162461bcd60e51b8152602060048201526008602482015267111254d05093115160c21b604482015290519081900360640190fd5b6002670de0b6b3a76400006114d7565b6000614236614318565b61423f8261447a565b61129b61424b8361459f565b6123e7614690565b600061425d614318565b6142668261447a565b506001600160a01b03166000908152600e602052604090206003015490565b6000806142928588614f67565b905060006142a08786614727565b905060006142ae8883614f67565b905060006142bc828561511c565b90506142d081670de0b6b3a7640000614727565b90506142e4670de0b6b3a764000087614727565b94506142f96142f38c836144d6565b86614f67565b9b9a5050505050505050505050565b600554600160b01b900460ff1690565b600554610100900460ff161561435f576040805162461bcd60e51b81526020600482015260076024820152665245454e54525960c81b604482015290519081900360640190fd5b565b3260009081526010602052604090205443116143b5576040805162461bcd60e51b815260206004820152600e60248201526d29a0a6a2afaa2c2fa7a924a3a4a760911b604482015290519081900360640190fd5b326000908152601060205260409020439055565b600c54600160a01b900460ff1661435f576040805162461bcd60e51b815260206004820152600d60248201526c1393d517d19253905312569151609a1b604482015290519081900360640190fd5b600654600160a01b900460ff16158061443a57506006546001600160a01b031633145b61435f576040805162461bcd60e51b815260206004820152600c60248201526b27a7262cafaba920a82822a960a11b604482015290519081900360640190fd5b6001600160a01b0381166000908152600e602052604090205460ff166144d3576040805162461bcd60e51b81526020600482015260096024820152681393d517d093d5539160ba1b604482015290519081900360640190fd5b50565b60008282028315806144f05750828482816144ed57fe5b04145b614534576040805162461bcd60e51b815260206004820152601060248201526f4552525f4d554c5f4f564552464c4f5760801b604482015290519081900360640190fd5b6706f05b59d3b20000810181811015614587576040805162461bcd60e51b815260206004820152601060248201526f4552525f4d554c5f4f564552464c4f5760801b604482015290519081900360640190fd5b6000670de0b6b3a7640000825b049695505050505050565b60006145a96157f2565b506001600160a01b038216600081815260116020908152604080832081516060810183528154815260018201548185015260029182015481840152948452600e9092529091200154815115806146025750808260400151145b8061460e575081514211155b1561461c5791506117329050565b816020015142106146335750604001519050611732565b600061464d828460400151856000015186602001516154a0565b9050600061465f428560000151614727565b90508284604001511115614684576146798383830261506f565b945050505050611732565b61467983838302614727565b600d546000908190815b818110156146df576146d5836146d0600d84815481106146b657fe5b6000918252602090912001546001600160a01b031661459f565b61506f565b925060010161469a565b509091505090565b806144d3576040805162461bcd60e51b815260206004820152600b60248201526a09a82a890be82a0a0a49eb60ab1b604482015290519081900360640190fd5b600080600061473685856154e2565b915091508015614781576040805162461bcd60e51b81526020600482015260116024820152704552525f5355425f554e444552464c4f5760781b604482015290519081900360640190fd5b509392505050565b6147938282615507565b5050565b6144d381615512565b6000836001600160a01b031663a9059cbb84846040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156147f957600080fd5b505af115801561480d573d6000803e3d6000fd5b505050506040513d602081101561482357600080fd5b5051905080614867576040805162461bcd60e51b815260206004820152600b60248201526a45524332305f46414c534560a81b604482015290519081900360640190fd5b50505050565b6001600160a01b0381166144d3576040805162461bcd60e51b815260206004820152601060248201526f4552525f4e554c4c5f4144445245535360801b604482015290519081900360640190fd5b6005546201000090046001600160a01b0316331461435f576040805162461bcd60e51b815260206004820152600e60248201526d2727aa2fa1a7a72a2927a62622a960911b604482015290519081900360640190fd5b64e8d4a51000811080159061492e575067016345785d8a00008111155b6144d3576040805162461bcd60e51b815260206004820152600a6024820152694645455f424f554e445360b01b604482015290519081900360640190fd5b6001600160a01b0383166000908152602081905260409020548111156149d0576040805162461bcd60e51b815260206004820152601460248201527311549497d25394d551919250d251539517d0905360621b604482015290519081900360640190fd5b6149d98361486d565b6149e28261486d565b6001600160a01b038316600090815260208190526040902054614a059082614727565b6001600160a01b038085166000908152602081905260408082209390935590841681522054614a34908261506f565b6001600160a01b0380841660008181526020818152604091829020949094558051858152905191939287169260008051602061585483398151915292918290030190a3505050565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2614ae5614318565b6005805461ff001916610100179055614afc6148bb565b614b058361447a565b633b9aca008110158015614b2257506802b5e3af16b18800008111155b614b63576040805162461bcd60e51b815260206004820152600d60248201526c5745494748545f424f554e445360981b604482015290519081900360640190fd5b620f4240821015614ba9576040805162461bcd60e51b815260206004820152600b60248201526a4d494e5f42414c414e434560a81b604482015290519081900360640190fd5b6001600160a01b0383166000908152600e602052604090206002015480821115614be457614bdf614bda8383614727565b6144d3565b614bf9565b80821015614bf957614bf9614bda8284614727565b6001600160a01b0384166000908152600e602052604090206002810183905560030180549084905580841115614c4257614c3d8533614c388785614727565b6150c3565b614c65565b80841015614c65576000614c568286614727565b9050614c638633836147a0565b505b50506005805461ff0019169055505050565b600c54600160a01b900460ff161561435f576040805162461bcd60e51b815260206004820152600c60248201526b1254d7d1925390531256915160a21b604482015290519081900360640190fd5b6007546001600160a01b031615614da1576007546040805163afff324960e01b815230600482015290516000926001600160a01b03169163afff3249916024808301926020929190829003018186803b158015614d2157600080fd5b505afa158015614d35573d6000803e3d6000fd5b505050506040513d6020811015614d4b57600080fd5b50516002549091508190614d5f908461506f565b1115614d9f576040805162461bcd60e51b815260206004820152600a6024820152694d41585f535550504c5960b01b604482015290519081900360640190fd5b505b6144d3816155d0565b6147938282615633565b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2614e1d6148bb565b6001600160a01b0383166000908152600e602052604090205460ff1615614e76576040805162461bcd60e51b81526020600482015260086024820152671254d7d093d5539160c21b604482015290519081900360640190fd5b600d54600911614eba576040805162461bcd60e51b815260206004820152600a6024820152694d41585f544f4b454e5360b01b604482015290519081900360640190fd5b604080516080810182526001808252600d805460208085019182526000858701818152606087018281526001600160a01b038c16808452600e9094529782209651875460ff1916901515178755925186860155915160028601559451600390940193909355805491820181559091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b03191690911790556118788383836117f9565b600081614faa576040805162461bcd60e51b815260206004820152600c60248201526b4552525f4449565f5a45524f60a01b604482015290519081900360640190fd5b670de0b6b3a76400008302831580614fd25750670de0b6b3a7640000848281614fcf57fe5b04145b615016576040805162461bcd60e51b815260206004820152601060248201526f11549497d1125597d25395115493905360821b604482015290519081900360640190fd5b60028304810181811015615064576040805162461bcd60e51b815260206004820152601060248201526f11549497d1125597d25395115493905360821b604482015290519081900360640190fd5b600084828161459457fe5b6000828201838110156150bc576040805162461bcd60e51b815260206004820152601060248201526f4552525f4144445f4f564552464c4f5760801b604482015290519081900360640190fd5b9392505050565b604080516323b872dd60e01b81526001600160a01b0384811660048301523060248301526044820184905291516000928616916323b872dd91606480830192602092919082900301818787803b1580156147f957600080fd5b6000600183101561516c576040805162461bcd60e51b81526020600482015260156024820152744552525f42504f575f424153455f544f4f5f4c4f5760581b604482015290519081900360640190fd5b671bc16d674ec7ffff8311156151c2576040805162461bcd60e51b815260206004820152601660248201527508aa4a4be84a09eaebe8482a68abea89e9ebe90928e960531b604482015290519081900360640190fd5b60006151cd8361563e565b905060006151db8483614727565b905060006151f1866151ec85615659565b615667565b90508161520257925061129b915050565b600061521387846305f5e1006156be565b905061521f82826144d6565b979650505050505050565b600c54604080516323b872dd60e01b81526001600160a01b03858116600483015292831660248201526044810184905290516000928616916323b872dd91606480830192602092919082900301818787803b1580156147f957600080fd5b336001600160a01b03166000356001600160e01b0319166001600160e01b03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a26152f1614318565b6005805461ff0019166101001790556153086148bb565b6153118161447a565b6001600160a01b0381166000908152600e60205260409020600381015460029091015461533d906144d3565b6001600160a01b0382166000908152600e6020526040902060010154600d8054600019810191908290811061536e57fe5b600091825260209091200154600d80546001600160a01b03909216918490811061539457fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555081600e6000600d85815481106153d457fe5b60009182526020808320909101546001600160a01b03168352820192909252604001902060010155600d80548061540757fe5b60008281526020808220600019908401810180546001600160a01b031916905590920190925560408051608081018252838152808301848152818301858152606083018681526001600160a01b038b168752600e909552929094209051815460ff1916901515178155925160018401555160028301555160039091015561548f8433856147a0565b50506005805461ff00191690555050565b6000808585116154b9576154b48686614727565b6154c3565b6154c38587614727565b90506154d8816154d38587614727565b61579c565b9695505050505050565b6000808284106154f85750508082036000615500565b505081810360015b9250929050565b61479382308361496c565b3060009081526020819052604090205481111561556d576040805162461bcd60e51b815260206004820152601460248201527311549497d25394d551919250d251539517d0905360621b604482015290519081900360640190fd5b306000908152602081905260409020546155879082614727565b306000908152602081905260409020556002546155a49082614727565b60025560408051828152905160009130916000805160206158548339815191529181900360200190a350565b306000908152602081905260409020546155ea908261506f565b30600090815260208190526040902055600254615607908261506f565b60025560408051828152905130916000916000805160206158548339815191529181900360200190a350565b61479330838361496c565b6000670de0b6b3a764000061565283615659565b0292915050565b670de0b6b3a7640000900490565b6000806002830661568057670de0b6b3a7640000615682565b835b90506002830492505b82156150bc5761569b84856144d6565b935060028306156156b3576156b081856144d6565b90505b60028304925061568b565b60008281806156d587670de0b6b3a76400006154e2565b9092509050670de0b6b3a764000080600060015b88841061578d576000670de0b6b3a76400008202905060008061571d8a61571885670de0b6b3a7640000614727565b6154e2565b9150915061572f876132ae848c6144d6565b965061573b8784614f67565b96508661574a5750505061578d565b8715615754579315935b801561575e579315935b84156157755761576e8688614727565b9550615782565b61577f868861506f565b95505b5050506001016156e9565b50909998505050505050505050565b60008082116157e1576040805162461bcd60e51b815260206004820152600c60248201526b4552525f4449565f5a45524f60a01b604482015290519081900360640190fd5b8183816157ea57fe5b049392505050565b6040518060600160405280600081526020016000815260200160008152509056fe63982df10efd8dfaaaa0fcc7f50b2d93b7cba26ccc48adee2873220d485dc39a908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efe74c91552b64c2e2e7bd255639e004e693bd3e1d01cc33e65610b86afcc1ffed5b5ddc912843b56bbfa1620dc5a27cc3b1b82c88ab626118af8dc1319b4a86568c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a264697066735822122062589b3b35fe5b3ab79b385208b3967cb5281ecde120ea0669764a48e9b0608264736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000004b3090ab80100000000000000000000000000000000000000000000000000000d287fb79cd10000000000000000000000000000000000000000000000000000000000000016506f77657220496e64657820506f6f6c20546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000045049505400000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : name (string): Power Index Pool Token
Arg [1] : symbol (string): PIPT
Arg [2] : minWeightPerSecond (uint256): 5166997354497
Arg [3] : maxWeightPerSecond (uint256): 14467592592593
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 000000000000000000000000000000000000000000000000000004b3090ab801
Arg [3] : 00000000000000000000000000000000000000000000000000000d287fb79cd1
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000016
Arg [5] : 506f77657220496e64657820506f6f6c20546f6b656e00000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [7] : 5049505400000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.