Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- FuseStakingV3
- Optimization enabled
- true
- Compiler version
- v0.6.12+commit.27d51765
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2021-03-03T08:19:16.780306Z
Contract source code
// SPDX-License-Identifier: MIT // File: @openzeppelin/contracts-upgradeable/proxy/Initializable.sol // solhint-disable-next-line compiler-version pragma solidity >=0.4.24 <0.8.0; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function _isConstructor() private view returns (bool) { // extcodesize checks the size of the code stored in an address, and // address returns the current address. Since the code is still not // deployed when running a constructor, any checks on its code size will // yield zero, making it an effective way to detect if a contract is // under construction or not. address self = address(this); uint256 cs; // solhint-disable-next-line no-inline-assembly assembly { cs := extcodesize(self) } return cs == 0; } } // File: @openzeppelin/contracts-upgradeable/GSN/ContextUpgradeable.sol /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } uint256[50] private __gap; } // File: @openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal initializer { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal initializer { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(_owner == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } uint256[49] private __gap; } // File: @openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMathUpgradeable { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File: contracts/utils/DSMath.sol /// math.sol -- mixin for inline numerical wizardry // 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/>. contract DSMath { function WAD() internal pure returns (uint256) { return 10**18; } function RAY() internal pure returns (uint256) { return 10**27; } function add(uint256 x, uint256 y) public pure returns (uint256 z) { require((z = x + y) >= x, "ds-math-add-overflow"); } function sub(uint256 x, uint256 y) public pure returns (uint256 z) { require((z = x - y) <= x, "ds-math-sub-underflow"); } function mul(uint256 x, uint256 y) public pure returns (uint256 z) { require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow"); } function min(uint256 x, uint256 y) public pure returns (uint256 z) { return x <= y ? x : y; } function max(uint256 x, uint256 y) public pure returns (uint256 z) { return x >= y ? x : y; } function imin(int256 x, int256 y) public pure returns (int256 z) { return x <= y ? x : y; } function imax(int256 x, int256 y) public pure returns (int256 z) { return x >= y ? x : y; } function wmul(uint256 x, uint256 y) public pure returns (uint256 z) { z = add(mul(x, y), WAD() / 2) / WAD(); } function rmul(uint256 x, uint256 y) public pure returns (uint256 z) { z = add(mul(x, y), RAY() / 2) / RAY(); } function wdiv(uint256 x, uint256 y) public pure returns (uint256 z) { z = add(mul(x, WAD()), y / 2) / y; } function rdiv(uint256 x, uint256 y) public pure returns (uint256 z) { z = add(mul(x, RAY()), y / 2) / y; } // This famous algorithm is called "exponentiation by squaring" // and calculates x^n with x as fixed-point and n as regular unsigned. // // It's O(log n), instead of O(n) for naive repeated multiplication. // // These facts are why it works: // // If n is even, then x^n = (x^2)^(n/2). // If n is odd, then x^n = x * x^(n-1), // and applying the equation for even x gives // x^n = x * (x^2)^((n-1) / 2). // // Also, EVM division is flooring and // floor[(n-1) / 2] = floor[n / 2]. // function rpow(uint256 x, uint256 n) public pure returns (uint256 z) { z = n % 2 != 0 ? x : RAY(); for (n /= 2; n != 0; n /= 2) { x = rmul(x, x); if (n % 2 != 0) { z = rmul(z, x); } } } } // File: contracts/Interfaces.sol pragma experimental ABIEncoderV2; interface cERC20 { function mint(uint256 mintAmount) external returns (uint256); function redeemUnderlying(uint256 mintAmount) external returns (uint256); function exchangeRateCurrent() external returns (uint256); function exchangeRateStored() external view returns (uint256); function balanceOf(address addr) external view returns (uint256); function transfer(address to, uint256 amount) external returns (bool); function approve(address spender, uint256 amount) external returns (bool); } interface GoodDollar is cERC20 { function getFees(uint256 value) external view returns (uint256, bool); function mint(address to, uint256 mintAmount) external returns (uint256); } interface Staking { struct Staker { // The staked DAI amount uint256 stakedDAI; // The latest block number which the // staker has staked tokens uint256 lastStake; } function stakeDAI(uint256 amount) external; function withdrawStake() external; function stakers(address staker) external view returns (Staker memory); } interface Uniswap { function swapExactETHForTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function swapExactTokensForETH( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function WETH() external pure returns (address); function factory() external pure returns (address); function quote( uint256 amountA, uint256 reserveA, uint256 reserveB ) external pure returns (uint256 amountB); function getAmountIn( uint256 amountOut, uint256 reserveIn, uint256 reserveOut ) external pure returns (uint256 amountIn); function getAmountOut( uint256 amountI, uint256 reserveIn, uint256 reserveOut ) external pure returns (uint256 amountOut); } interface UniswapFactory { function getPair(address tokenA, address tokenB) external view returns (address); } interface UniswapPair { function getReserves() external view returns ( uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast ); function kLast() external view returns (uint256); } interface Reserve { function buy( address _buyWith, uint256 _tokenAmount, uint256 _minReturn ) external returns (uint256); } interface IIdentity { function isWhitelisted(address user) external view returns (bool); function addWhitelistedWithDID(address account, string memory did) external; function removeWhitelisted(address account) external; function addIdentityAdmin(address account) external returns (bool); function setAvatar(address _avatar) external; } interface UBIScheme { function currentDay() external view returns (uint256); } interface ProxyAdmin { function getProxyImplementation(address proxy) external view returns (address); function getProxyAdmin(address proxy) external view returns (address); function upgrade(address proxy, address implementation) external; function owner() external view returns (address); function transferOwnership(address newOwner) external; } // File: contracts/staking/FuseStakingV3.sol interface IConsensus { /** * @dev delegate to a validator * @param _validator the address of the validator msg.sender is delegating to */ function delegate(address _validator) external payable; /** * @dev Function to be called when a delegator whishes to withdraw some of his staked funds for a validator * @param _validator the address of the validator msg.sender has delegating to * @param _amount the amount msg.sender wishes to withdraw from the contract */ function withdraw(address _validator, uint256 _amount) external; function delegatedAmount(address _address, address _validator) external view returns (uint256); function stakeAmount(address _address) external view returns (uint256); function delegators(address _validator) external view returns (address[] memory); } contract FuseStakingV3 is Initializable, OwnableUpgradeable, DSMath { using SafeMathUpgradeable for uint256; mapping(address => uint256) public stakers; address[] public validators; IConsensus public consensus; Uniswap public uniswap; GoodDollar public GD; UBIScheme public ubischeme; UniswapFactory public uniswapFactory; UniswapPair public uniswapPair; uint256 public lastDayCollected; //ubi day from ubischeme uint256 public stakeBackRatio; uint256 public maxSlippageRatio; uint256 public keeperFeeRatio; uint256 public RATIO_BASE; uint256 public communityPoolRatio; //out of G$ bought how much should goto pool uint256 communityPoolBalance; uint256 pendingFuseEarnings; //earnings not used because of slippage event UBICollected( uint256 indexed currentDay, uint256 ubi, //G$ sent to ubischeme uint256 communityPool, //G$ added to pool uint256 gdBought, //actual G$ we got out of swapping stakingRewards + pendingFuseEarnings uint256 stakingRewards, //rewards earned since previous collection, uint256 pendingFuseEarnings, //new balance of fuse pending to be swapped for G$ address keeper, uint256 keeperGDFee ); /** * @dev initialize */ function initialize() public initializer { __Ownable_init_unchained(); consensus = IConsensus( address(0x3014ca10b91cb3D0AD85fEf7A3Cb95BCAc9c0f79) ); validators.push(address(0xcb876A393F05a6677a8a029f1C6D7603B416C0A6)); } function upgrade0() public { if (RATIO_BASE == 0) { stakeBackRatio = 33333; //%33 communityPoolRatio = 33333; //%33 maxSlippageRatio = 3000; //3% keeperFeeRatio = 30; //0.03% RATIO_BASE = 100000; //100% } } function upgrade1( address _gd, address _ubischeme, address _uniswap ) public { if (address(uniswapPair) == address(0)) { uniswap = Uniswap( _uniswap == address(0) ? 0xFB76e9E7d88E308aB530330eD90e84a952570319 : _uniswap ); GD = GoodDollar(_gd); ubischeme = UBIScheme(_ubischeme); uniswapFactory = UniswapFactory(uniswap.factory()); uniswapPair = UniswapPair( uniswapFactory.getPair(uniswap.WETH(), _gd) ); upgrade0(); } } function setContracts(address _gd, address _ubischeme) public onlyOwner { if (_gd != address(0)) { GD = GoodDollar(_gd); } if (_ubischeme != address(0)) { ubischeme = UBIScheme(_ubischeme); } } function stake() public payable returns (bool) { return stake(address(0)); } function stake(address _validator) public payable returns (bool) { require(msg.value > 0, "stake must be > 0"); require(validators.length > 0, "no approved validators"); bool found; for ( uint256 i = 0; _validator != address(0) && i < validators.length; i++ ) { if (validators[i] != _validator) { found = true; break; } } require( _validator == address(0) || found, "validator not in approved list" ); bool staked = stakeNextValidator(msg.value, _validator); stakers[msg.sender] = stakers[msg.sender].add(msg.value); return staked; } function balanceOf(address _owner) public view returns (uint256) { return stakers[_owner]; } function withdraw(uint256 _value) public returns (uint256) { uint256 effectiveBalance = balance(); //use only undelegated funds uint256 toWithdraw = _value == 0 ? stakers[msg.sender] : _value; uint256 toCollect = toWithdraw; require( toWithdraw > 0 && toWithdraw <= stakers[msg.sender], "invalid withdraw amount" ); uint256 perValidator = _value.div(validators.length); for (uint256 i = 0; i < validators.length; i++) { uint256 cur = consensus.delegatedAmount(address(this), validators[i]); if (cur == 0) continue; if (cur <= perValidator) { undelegateWithCatch(validators[i], cur); toCollect = toCollect.sub(cur); } else { undelegateWithCatch(validators[i], perValidator); toCollect = toCollect.sub(perValidator); } if (toCollect == 0) break; } effectiveBalance = balance().sub(effectiveBalance); //use only undelegated funds // in case some funds where not withdrawn if (toWithdraw > effectiveBalance) { toWithdraw = effectiveBalance; } stakers[msg.sender] = stakers[msg.sender].sub(toWithdraw); if (toWithdraw > 0) payable(msg.sender).transfer(toWithdraw); return toWithdraw; } function stakeNextValidator(uint256 _value, address _validator) internal returns (bool) { if (validators.length == 0) return false; if (_validator != address(0)) { consensus.delegate{ value: _value }(_validator); return true; } uint256 perValidator = totalDelegated().add(_value).div(validators.length); uint256 left = _value; for (uint256 i = 0; i < validators.length && left > 0; i++) { uint256 cur = consensus.delegatedAmount(address(this), validators[i]); if (cur < perValidator) { uint256 toDelegate = perValidator.sub(cur); toDelegate = toDelegate < left ? toDelegate : left; consensus.delegate{ value: toDelegate }(validators[i]); left = left.sub(toDelegate); } } return true; } function addValidator(address _v) public onlyOwner { validators.push(_v); } function totalDelegated() public view returns (uint256) { uint256 total = 0; for (uint256 i = 0; i < validators.length; i++) { uint256 cur = consensus.delegatedAmount(address(this), validators[i]); total = total.add(cur); } return total; } function removeValidator(address _validator) public onlyOwner { uint256 delegated = consensus.delegatedAmount(address(this), _validator); if (delegated > 0) { uint256 prevBalance = balance(); undelegateWithCatch(_validator, delegated); // wasnt withdrawn because validator needs to be taken of active validators if (balance() == prevBalance) { // pendingValidators.push(_validator); return; } } for (uint256 i = 0; i < validators.length; i++) { if (validators[i] == _validator) { if (i < validators.length - 1) validators[i] = validators[validators.length - 1]; validators.pop(); break; } } } function collectUBIInterest() public { uint256 curDay = ubischeme.currentDay(); require( curDay != lastDayCollected, "can collect only once in a ubi cycle" ); uint256 earnings = balance() - pendingFuseEarnings; require(pendingFuseEarnings + earnings > 0, "no earnings to collect"); lastDayCollected = curDay; uint256 fuseUBI = earnings.mul(RATIO_BASE - stakeBackRatio).div(RATIO_BASE); uint256 stakeBack = earnings - fuseUBI; uint256[] memory fuseswapResult = _buyGD(fuseUBI.add(pendingFuseEarnings)); //buy GD with X% of earnings pendingFuseEarnings = fuseUBI.add(pendingFuseEarnings).sub( fuseswapResult[0] ); stakeNextValidator(stakeBack, address(0)); //stake back the rest of the earnings uint256 gdBought = fuseswapResult[1]; uint256 keeperFee = gdBought.mul(keeperFeeRatio).div(RATIO_BASE); if (keeperFee > 0) GD.transfer(msg.sender, keeperFee); uint256 communityPoolContribution = gdBought .sub(keeperFee) //subtract fee .mul(communityPoolRatio) // * ommunityPoolRatio .div(RATIO_BASE); // = G$ after fee * communityPoolRatio% uint256 ubiAfterFeeAndPool = gdBought.sub(communityPoolContribution); GD.transfer(address(ubischeme), ubiAfterFeeAndPool); //transfer to ubischeme communityPoolBalance = communityPoolBalance.add( communityPoolContribution ); emit UBICollected( curDay, ubiAfterFeeAndPool, communityPoolContribution, gdBought, earnings, pendingFuseEarnings, msg.sender, keeperFee ); } /** * @dev internal method to buy GD from fuseswap * @param _value fuse to be sold * @return uniswap coversion results uint256[2] */ function _buyGD(uint256 _value) internal returns (uint256[] memory) { //buy from uniwasp require(_value > 0, "buy value should be > 0"); uint256 maxFuse = calcMaxFuseWithSlippage(_value); address[] memory path = new address[](2); path[1] = address(GD); path[0] = uniswap.WETH(); return uniswap.swapExactETHForTokens{ value: maxFuse }( 0, path, address(this), now ); } function calcMaxFuseWithSlippage(uint256 _value) public view returns (uint256) { (uint256 r_fuse, uint256 r_gd, ) = uniswapPair.getReserves(); return calcMaxFuseWithSlippage(r_fuse, r_gd, _value); } /** * uniswap amountOut helper */ function getAmountOut( uint256 _amountIn, uint256 _reserveIn, uint256 _reserveOut ) internal pure returns (uint256 amountOut) { uint256 amountInWithFee = _amountIn.mul(997); uint256 numerator = amountInWithFee.mul(_reserveOut); uint256 denominator = _reserveIn.mul(1000).add(amountInWithFee); amountOut = numerator / denominator; } /** * @dev use binary search to find quantity that will result with slippage < maxSlippageRatio */ function calcMaxFuseWithSlippage( uint256 r_fuse, uint256 r_gd, uint256 _value ) public view returns (uint256) { uint256 start = 0; uint256 end = _value.div(1e18); //save iterations by moving precision to whole Fuse quantity uint256 curPriceWei = uint256(100).mul(r_fuse) / r_gd; //uniswap quote formula UniswapV2Library.sol uint256 maxPriceWei = curPriceWei.mul(RATIO_BASE.add(maxSlippageRatio)).div(RATIO_BASE); uint256 fuseAmount = _value; //Iterate while start not meets end while (start <= end) { // Find the mid index uint256 midQuantityWei = start.add(end).mul(1e18).div(2); //restore quantity precision if (midQuantityWei == 0) break; uint256 gdForQuantity = getAmountOut(midQuantityWei, r_fuse, r_gd); uint256 priceForQuantityWei = rdiv(midQuantityWei, gdForQuantity.mul(1e16)).div(1e9); if (priceForQuantityWei <= maxPriceWei) { start = midQuantityWei.div(1e18) + 1; //reduce precision to whole quantity div 1e18 fuseAmount = midQuantityWei; } else end = midQuantityWei.div(1e18) - 1; //reduce precision to whole quantity div 1e18 } return fuseAmount; } function undelegateWithCatch(address _validator, uint256 _amount) internal returns (bool) { try consensus.withdraw(_validator, _amount) { return true; } catch Error( string memory /*reason*/ ) { // This is executed in case // revert was called inside getData // and a reason string was provided. return false; } catch ( bytes memory /*lowLevelData*/ ) { // This is executed in case revert() was used // or there was a failing assertion, division // by zero, etc. inside getData. return false; } } function balance() internal view returns (uint256) { return payable(address(this)).balance; } receive() external payable {} }
Contract ABI
[{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"UBICollected","inputs":[{"type":"uint256","name":"currentDay","internalType":"uint256","indexed":true},{"type":"uint256","name":"ubi","internalType":"uint256","indexed":false},{"type":"uint256","name":"communityPool","internalType":"uint256","indexed":false},{"type":"uint256","name":"gdBought","internalType":"uint256","indexed":false},{"type":"uint256","name":"stakingRewards","internalType":"uint256","indexed":false},{"type":"uint256","name":"pendingFuseEarnings","internalType":"uint256","indexed":false},{"type":"address","name":"keeper","internalType":"address","indexed":false},{"type":"uint256","name":"keeperGDFee","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract GoodDollar"}],"name":"GD","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"RATIO_BASE","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"z","internalType":"uint256"}],"name":"add","inputs":[{"type":"uint256","name":"x","internalType":"uint256"},{"type":"uint256","name":"y","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addValidator","inputs":[{"type":"address","name":"_v","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"_owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"calcMaxFuseWithSlippage","inputs":[{"type":"uint256","name":"r_fuse","internalType":"uint256"},{"type":"uint256","name":"r_gd","internalType":"uint256"},{"type":"uint256","name":"_value","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"calcMaxFuseWithSlippage","inputs":[{"type":"uint256","name":"_value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"collectUBIInterest","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"communityPoolRatio","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IConsensus"}],"name":"consensus","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"int256","name":"z","internalType":"int256"}],"name":"imax","inputs":[{"type":"int256","name":"x","internalType":"int256"},{"type":"int256","name":"y","internalType":"int256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"int256","name":"z","internalType":"int256"}],"name":"imin","inputs":[{"type":"int256","name":"x","internalType":"int256"},{"type":"int256","name":"y","internalType":"int256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"keeperFeeRatio","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastDayCollected","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"z","internalType":"uint256"}],"name":"max","inputs":[{"type":"uint256","name":"x","internalType":"uint256"},{"type":"uint256","name":"y","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxSlippageRatio","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"z","internalType":"uint256"}],"name":"min","inputs":[{"type":"uint256","name":"x","internalType":"uint256"},{"type":"uint256","name":"y","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"z","internalType":"uint256"}],"name":"mul","inputs":[{"type":"uint256","name":"x","internalType":"uint256"},{"type":"uint256","name":"y","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"z","internalType":"uint256"}],"name":"rdiv","inputs":[{"type":"uint256","name":"x","internalType":"uint256"},{"type":"uint256","name":"y","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeValidator","inputs":[{"type":"address","name":"_validator","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"z","internalType":"uint256"}],"name":"rmul","inputs":[{"type":"uint256","name":"x","internalType":"uint256"},{"type":"uint256","name":"y","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"z","internalType":"uint256"}],"name":"rpow","inputs":[{"type":"uint256","name":"x","internalType":"uint256"},{"type":"uint256","name":"n","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setContracts","inputs":[{"type":"address","name":"_gd","internalType":"address"},{"type":"address","name":"_ubischeme","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"stake","inputs":[{"type":"address","name":"_validator","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"stake","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"stakeBackRatio","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"stakers","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"z","internalType":"uint256"}],"name":"sub","inputs":[{"type":"uint256","name":"x","internalType":"uint256"},{"type":"uint256","name":"y","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalDelegated","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract UBIScheme"}],"name":"ubischeme","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract Uniswap"}],"name":"uniswap","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract UniswapFactory"}],"name":"uniswapFactory","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract UniswapPair"}],"name":"uniswapPair","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"upgrade0","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"upgrade1","inputs":[{"type":"address","name":"_gd","internalType":"address"},{"type":"address","name":"_ubischeme","internalType":"address"},{"type":"address","name":"_uniswap","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"validators","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"z","internalType":"uint256"}],"name":"wdiv","inputs":[{"type":"uint256","name":"x","internalType":"uint256"},{"type":"uint256","name":"y","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"withdraw","inputs":[{"type":"uint256","name":"_value","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"z","internalType":"uint256"}],"name":"wmul","inputs":[{"type":"uint256","name":"x","internalType":"uint256"},{"type":"uint256","name":"y","internalType":"uint256"}]},{"type":"receive","stateMutability":"payable"}]
Contract Creation Code
0x608060405234801561001057600080fd5b506129df806100206000396000f3fe6080604052600436106102605760003560e01c8063771602f7116101445780639168ae72116100b6578063c816841b1161007a578063c816841b14610669578063c8a4ac9c1461067e578063c8e6c7d91461069e578063d22e9b06146106be578063d8952a49146106d3578063f2fde38b146106f357610267565b80639168ae72146105df578063a5a90636146105ff578063ae94e44814610614578063b67d77c514610634578063c11a56301461065457610267565b80638918c4a2116101085780638918c4a21461054b5780638b9af5c1146105605780638bdb2afa146105805780638da5cb5b146105955780638ef3f761146105aa5780638f907195146105bf57610267565b8063771602f7146104cc5780637ae2b5c7146104ec57806380d04de81461050c57806381028f67146105215780638129fc1c1461053657610267565b80633fb1ccf1116101dd5780636021a9d5116101a15780636021a9d51461042d5780636711281c1461044257806367457022146104575780636d5433e61461047757806370a0823114610497578063715018a6146104b757610267565b80633fb1ccf11461039657806340a141ff146103ab57806347a1671a146103cd5780634d238c8e146103ed5780635fde731c1461040d57610267565b80632681f7e4116102245780632681f7e41461030c5780632cda89431461032e5780632e1a7d4d1461034e57806335aa2e441461036e5780633a4b66f11461038e57610267565b806304d26ebf1461026c57806309b6afb2146102975780630e2286d3146102b7578063150d7e47146102d757806326476204146102ec57610267565b3661026757005b600080fd5b34801561027857600080fd5b50610281610713565b60405161028e919061244f565b60405180910390f35b3480156102a357600080fd5b506102816102b23660046123d2565b610719565b3480156102c357600080fd5b506102816102d2366004612338565b610835565b3480156102e357600080fd5b50610281610860565b6102ff6102fa3660046121c9565b610866565b60405161028e9190612444565b34801561031857600080fd5b50610321610983565b60405161028e91906123fd565b34801561033a57600080fd5b506102816103493660046123a2565b610992565b34801561035a57600080fd5b506102816103693660046123a2565b610a47565b34801561037a57600080fd5b506103216103893660046123a2565b610ca7565b6102ff610cce565b3480156103a257600080fd5b50610321610ce0565b3480156103b757600080fd5b506103cb6103c63660046121c9565b610cef565b005b3480156103d957600080fd5b506103cb6103e8366004612239565b610ed2565b3480156103f957600080fd5b506103cb6104083660046121c9565b6110ea565b34801561041957600080fd5b50610281610428366004612338565b611171565b34801561043957600080fd5b50610281611183565b34801561044e57600080fd5b506103cb611189565b34801561046357600080fd5b50610281610472366004612338565b6111b0565b34801561048357600080fd5b50610281610492366004612338565b6111d8565b3480156104a357600080fd5b506102816104b23660046121c9565b6111f3565b3480156104c357600080fd5b506103cb61120e565b3480156104d857600080fd5b506102816104e7366004612338565b61128d565b3480156104f857600080fd5b50610281610507366004612338565b6112b0565b34801561051857600080fd5b506102816112c0565b34801561052d57600080fd5b5061032161139a565b34801561054257600080fd5b506103cb6113a9565b34801561055757600080fd5b506102816114ab565b34801561056c57600080fd5b5061028161057b366004612338565b6114b1565b34801561058c57600080fd5b506103216114d2565b3480156105a157600080fd5b506103216114e1565b3480156105b657600080fd5b506103216114f0565b3480156105cb57600080fd5b506102816105da366004612338565b6114ff565b3480156105eb57600080fd5b506102816105fa3660046121c9565b611554565b34801561060b57600080fd5b506103cb611566565b34801561062057600080fd5b5061028161062f366004612338565b6118a1565b34801561064057600080fd5b5061028161064f366004612338565b6118b1565b34801561066057600080fd5b506102816118d4565b34801561067557600080fd5b506103216118da565b34801561068a57600080fd5b50610281610699366004612338565b6118e9565b3480156106aa57600080fd5b506102816106b9366004612338565b611920565b3480156106ca57600080fd5b50610281611930565b3480156106df57600080fd5b506103cb6106ee366004612201565b611936565b3480156106ff57600080fd5b506103cb61070e3660046121c9565b6119c5565b606f5481565b6000808061072f84670de0b6b3a7640000611a7c565b905060008561073f606489611abe565b8161074657fe5b049050600061077860715461077261076b606f54607154611af890919063ffffffff16565b8590611abe565b90611a7c565b9050855b8385116108295760006107a66002610772670de0b6b3a76400006107a08a8a611af8565b90611abe565b9050806107b35750610829565b60006107c0828c8c611b1d565b905060006107e1633b9aca00610772856102d286662386f26fc10000611abe565b9050848111610809576107fc83670de0b6b3a7640000611a7c565b6001019750829350610821565b600161081d84670de0b6b3a7640000611a7c565b0396505b50505061077c565b98975050505050505050565b60008161085161084785610699611b6b565b6002855b0461128d565b8161085857fe5b049392505050565b60705481565b60008034116108905760405162461bcd60e51b8152600401610887906127c2565b60405180910390fd5b6066546108af5760405162461bcd60e51b8152600401610887906127ed565b6000805b6001600160a01b038416158015906108cc575060665481105b1561091357836001600160a01b0316606682815481106108e857fe5b6000918252602090912001546001600160a01b03161461090b5760019150610913565b6001016108b3565b506001600160a01b03831615806109275750805b6109435760405162461bcd60e51b81526004016108879061281d565b600061094f3485611b7b565b3360009081526065602052604090205490915061096c9034611af8565b336000908152606560205260409020559392505050565b6068546001600160a01b031681565b6000806000606c60009054906101000a90046001600160a01b03166001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156109e557600080fd5b505afa1580156109f9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1d9190612359565b506001600160701b031691506001600160701b03169150610a3f828286610719565b949350505050565b600080610a52611dcc565b905060008315610a625783610a73565b336000908152606560205260409020545b9050808015801590610a945750336000908152606560205260409020548211155b610ab05760405162461bcd60e51b815260040161088790612756565b606654600090610ac1908790611a7c565b905060005b606654811015610c1d57606754606680546000926001600160a01b0316916321429e609130919086908110610af757fe5b6000918252602090912001546040516001600160e01b031960e085901b168152610b2e92916001600160a01b031690600401612411565b60206040518083038186803b158015610b4657600080fd5b505afa158015610b5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7e91906123ba565b905080610b8b5750610c15565b828111610bcf57610bbd60668381548110610ba257fe5b6000918252602090912001546001600160a01b031682611dd1565b50610bc88482611e92565b9350610c08565b610bfa60668381548110610bdf57fe5b6000918252602090912001546001600160a01b031684611dd1565b50610c058484611e92565b93505b83610c135750610c1d565b505b600101610ac6565b50610c3084610c2a611dcc565b90611e92565b935083831115610c3e578392505b33600090815260656020526040902054610c589084611e92565b336000908152606560205260409020558215610c9d57604051339084156108fc029085906000818181858888f19350505050158015610c9b573d6000803e3d6000fd5b505b5090949350505050565b60668181548110610cb457fe5b6000918252602090912001546001600160a01b0316905081565b6000610cda6000610866565b90505b90565b6069546001600160a01b031681565b610cf7611ed4565b6033546001600160a01b03908116911614610d245760405162461bcd60e51b81526004016108879061278d565b60675460405163010a14f360e51b81526000916001600160a01b0316906321429e6090610d579030908690600401612411565b60206040518083038186803b158015610d6f57600080fd5b505afa158015610d83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da791906123ba565b90508015610dde576000610db9611dcc565b9050610dc58383611dd1565b5080610dcf611dcc565b1415610ddc575050610ecf565b505b60005b606654811015610ecc57826001600160a01b031660668281548110610e0257fe5b6000918252602090912001546001600160a01b03161415610ec45760665460001901811015610e9257606680546000198101908110610e3d57fe5b600091825260209091200154606680546001600160a01b039092169183908110610e6357fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b6066805480610e9d57fe5b600082815260209020810160001990810180546001600160a01b0319169055019055610ecc565b600101610de1565b50505b50565b606c546001600160a01b0316610ecc576001600160a01b03811615610ef75780610f0d565b73fb76e9e7d88e308ab530330ed90e84a9525703195b606880546001600160a01b03199081166001600160a01b039384161791829055606980548216878516179055606a80549091168584161790556040805163c45a015560e01b81529051919092169163c45a0155916004808301926020929190829003018186803b158015610f8057600080fd5b505afa158015610f94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb891906121e5565b606b80546001600160a01b0319166001600160a01b039283161790819055606854604080516315ab88c960e31b815290519284169363e6a439059392169163ad5c464891600480820192602092909190829003018186803b15801561101c57600080fd5b505afa158015611030573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105491906121e5565b856040518363ffffffff1660e01b8152600401611072929190612411565b60206040518083038186803b15801561108a57600080fd5b505afa15801561109e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c291906121e5565b606c80546001600160a01b0319166001600160a01b0392909216919091179055610ecc611189565b6110f2611ed4565b6033546001600160a01b0390811691161461111f5760405162461bcd60e51b81526004016108879061278d565b606680546001810182556000919091527f46501879b8ca8525e8c2fd519e2fbfcfa2ebea26501294aa02cbfcfb12e943540180546001600160a01b0319166001600160a01b0392909216919091179055565b60008161085161084785610699611ed8565b606e5481565b6071546111ae57618235606e819055607255610bb8606f55601e607055620186a06071555b565b60006111ba611b6b565b6108516111c785856118e9565b60026111d1611b6b565b8161084b57fe5b6000818310156111e857816111ea565b825b90505b92915050565b6001600160a01b031660009081526065602052604090205490565b611216611ed4565b6033546001600160a01b039081169116146112435760405162461bcd60e51b81526004016108879061278d565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b808201828110156111ed5760405162461bcd60e51b815260040161088790612625565b6000818311156111e857816111ea565b600080805b60665481101561139457606754606680546000926001600160a01b0316916321429e6091309190869081106112f657fe5b6000918252602090912001546040516001600160e01b031960e085901b16815261132d92916001600160a01b031690600401612411565b60206040518083038186803b15801561134557600080fd5b505afa158015611359573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137d91906123ba565b90506113898382611af8565b9250506001016112c5565b50905090565b606a546001600160a01b031681565b600054610100900460ff16806113c257506113c2611ee4565b806113d0575060005460ff16155b6113ec5760405162461bcd60e51b815260040161088790612683565b600054610100900460ff16158015611417576000805460ff1961ff0019909116610100171660011790555b61141f611eea565b606780546001600160a01b0319908116733014ca10b91cb3d0ad85fef7a3cb95bcac9c0f7917909155606680546001810182556000919091527f46501879b8ca8525e8c2fd519e2fbfcfa2ebea26501294aa02cbfcfb12e9435401805490911673cb876a393f05a6677a8a029f1c6d7603b416c0a61790558015610ecf576000805461ff001916905550565b606d5481565b60006114bb611ed8565b6108516114c885856118e9565b60026111d1611ed8565b606b546001600160a01b031681565b6033546001600160a01b031690565b6067546001600160a01b031681565b60006002820661151657611511611b6b565b611518565b825b90506002820491505b81156111ed5761153183846111b0565b925060028206156115495761154681846111b0565b90505b600282049150611521565b60656020526000908152604090205481565b606a5460408051635c9302c960e01b815290516000926001600160a01b031691635c9302c9916004808301926020929190829003018186803b1580156115ab57600080fd5b505afa1580156115bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e391906123ba565b9050606d548114156116075760405162461bcd60e51b8152600401610887906126d1565b6000607454611614611dcc565b039050600081607454011161163b5760405162461bcd60e51b815260040161088790612653565b606d829055607154606e5460009161165a916107729085908303611abe565b905060008183039050606061168261167d60745485611af890919063ffffffff16565b611fc4565b90506116b18160008151811061169457fe5b6020026020010151610c2a60745486611af890919063ffffffff16565b6074556116bf826000611b7b565b506000816001815181106116cf57fe5b6020026020010151905060006116f660715461077260705485611abe90919063ffffffff16565b905080156117845760695460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611730903390859060040161242b565b602060405180830381600087803b15801561174a57600080fd5b505af115801561175e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117829190612318565b505b60006117a56071546107726072546107a08688611e9290919063ffffffff16565b905060006117b38483611e92565b606954606a5460405163a9059cbb60e01b81529293506001600160a01b039182169263a9059cbb926117eb921690859060040161242b565b602060405180830381600087803b15801561180557600080fd5b505af1158015611819573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061183d9190612318565b5060735461184b9083611af8565b6073556074546040518a917f49a079c90e07ed02ae8283e86eaeb643c637381d30aa7ba06d155e5b744a85439161188e91859187918a918f919033908c90612854565b60405180910390a2505050505050505050565b6000818312156111e857816111ea565b808203828111156111ed5760405162461bcd60e51b815260040161088790612514565b60715481565b606c546001600160a01b031681565b60008115806119045750508082028282828161190157fe5b04145b6111ed5760405162461bcd60e51b8152600401610887906125c0565b6000818313156111e857816111ea565b60725481565b61193e611ed4565b6033546001600160a01b0390811691161461196b5760405162461bcd60e51b81526004016108879061278d565b6001600160a01b0382161561199657606980546001600160a01b0319166001600160a01b0384161790555b6001600160a01b038116156119c157606a80546001600160a01b0319166001600160a01b0383161790555b5050565b6119cd611ed4565b6033546001600160a01b039081169116146119fa5760405162461bcd60e51b81526004016108879061278d565b6001600160a01b038116611a205760405162461bcd60e51b81526004016108879061257a565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b60006111ea83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612166565b600082611acd575060006111ed565b82820282848281611ada57fe5b04146111ea5760405162461bcd60e51b815260040161088790612715565b6000828201838110156111ea5760405162461bcd60e51b8152600401610887906125ee565b600080611b2c856103e5611abe565b90506000611b3a8285611abe565b90506000611b5483611b4e886103e8611abe565b90611af8565b9050808281611b5f57fe5b04979650505050505050565b6b033b2e3c9fd0803ce800000090565b606654600090611b8d575060006111ed565b6001600160a01b03821615611c09576067546040516317066a5760e21b81526001600160a01b0390911690635c19a95c908590611bce9086906004016123fd565b6000604051808303818588803b158015611be757600080fd5b505af1158015611bfb573d6000803e3d6000fd5b5050505050600190506111ed565b606654600090611c1f9061077286611b4e6112c0565b90508360005b60665481108015611c365750600082115b15611dc057606754606680546000926001600160a01b0316916321429e609130919086908110611c6257fe5b6000918252602090912001546040516001600160e01b031960e085901b168152611c9992916001600160a01b031690600401612411565b60206040518083038186803b158015611cb157600080fd5b505afa158015611cc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ce991906123ba565b905083811015611db7576000611cff8583611e92565b9050838110611d0e5783611d10565b805b606754606680549293506001600160a01b0390911691635c19a95c91849187908110611d3857fe5b6000918252602090912001546040516001600160e01b031960e085901b168152611d6e916001600160a01b0316906004016123fd565b6000604051808303818588803b158015611d8757600080fd5b505af1158015611d9b573d6000803e3d6000fd5b5050505050611db38185611e9290919063ffffffff16565b9350505b50600101611c25565b50600195945050505050565b303190565b60675460405163f3fef3a360e01b81526000916001600160a01b03169063f3fef3a390611e04908690869060040161242b565b600060405180830381600087803b158015611e1e57600080fd5b505af1925050508015611e2f575060015b611e8a57611e3b6128da565b80611e465750611e50565b60009150506111ed565b3d808015611e7a576040519150601f19603f3d011682016040523d82523d6000602084013e611e7f565b606091505b5060009150506111ed565b5060016111ed565b60006111ea83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061219d565b3390565b670de0b6b3a764000090565b303b1590565b600054610100900460ff1680611f035750611f03611ee4565b80611f11575060005460ff16155b611f2d5760405162461bcd60e51b815260040161088790612683565b600054610100900460ff16158015611f58576000805460ff1961ff0019909116610100171660011790555b6000611f62611ed4565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015610ecf576000805461ff001916905550565b606060008211611fe65760405162461bcd60e51b815260040161088790612543565b6000611ff183610992565b604080516002808252606080830184529394509091602083019080368337505060695482519293506001600160a01b031691839150600190811061203157fe5b6001600160a01b03928316602091820292909201810191909152606854604080516315ab88c960e31b81529051919093169263ad5c4648926004808301939192829003018186803b15801561208557600080fd5b505afa158015612099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120bd91906121e5565b816000815181106120ca57fe5b6001600160a01b039283166020918202929092010152606854604051637ff36ab560e01b8152911690637ff36ab590849061211090600090869030904290600401612458565b6000604051808303818588803b15801561212957600080fd5b505af115801561213d573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f19168201604052610a3f9190810190612283565b600081836121875760405162461bcd60e51b815260040161088791906124c1565b50600083858161219357fe5b0495945050505050565b600081848411156121c15760405162461bcd60e51b815260040161088791906124c1565b505050900390565b6000602082840312156121da578081fd5b81356111ea8161297f565b6000602082840312156121f6578081fd5b81516111ea8161297f565b60008060408385031215612213578081fd5b823561221e8161297f565b9150602083013561222e8161297f565b809150509250929050565b60008060006060848603121561224d578081fd5b83356122588161297f565b925060208401356122688161297f565b915060408401356122788161297f565b809150509250925092565b60006020808385031215612295578182fd5b825167ffffffffffffffff8111156122ab578283fd5b8301601f810185136122bb578283fd5b80516122ce6122c9826128b4565b61288d565b81815283810190838501858402850186018910156122ea578687fd5b8694505b8385101561230c5780518352600194909401939185019185016122ee565b50979650505050505050565b600060208284031215612329578081fd5b815180151581146111ea578182fd5b6000806040838503121561234a578182fd5b50508035926020909101359150565b60008060006060848603121561236d578283fd5b835161237881612994565b602085015190935061238981612994565b604085015190925063ffffffff81168114612278578182fd5b6000602082840312156123b3578081fd5b5035919050565b6000602082840312156123cb578081fd5b5051919050565b6000806000606084860312156123e6578283fd5b505081359360208301359350604090920135919050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b90815260200190565b600060808201868352602060808185015281875180845260a0860191508289019350845b818110156124a15784516001600160a01b03168352938301939183019160010161247c565b50506001600160a01b039690961660408501525050506060015292915050565b6000602080835283518082850152825b818110156124ed578581018301518582016040015282016124d1565b818111156124fe5783604083870101525b50601f01601f1916929092016040019392505050565b60208082526015908201527464732d6d6174682d7375622d756e646572666c6f7760581b604082015260600190565b60208082526017908201527f6275792076616c75652073686f756c64206265203e2030000000000000000000604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526014908201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526014908201527364732d6d6174682d6164642d6f766572666c6f7760601b604082015260600190565b6020808252601690820152751b9bc819585c9b9a5b99dcc81d1bc818dbdb1b1958dd60521b604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526024908201527f63616e20636f6c6c656374206f6e6c79206f6e636520696e206120756269206360408201526379636c6560e01b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b60208082526017908201527f696e76616c696420776974686472617720616d6f756e74000000000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526011908201527007374616b65206d757374206265203e203607c1b604082015260600190565b6020808252601690820152756e6f20617070726f7665642076616c696461746f727360501b604082015260600190565b6020808252601e908201527f76616c696461746f72206e6f7420696e20617070726f766564206c6973740000604082015260600190565b96875260208701959095526040860193909352606085019190915260808401526001600160a01b031660a083015260c082015260e00190565b60405181810167ffffffffffffffff811182821017156128ac57600080fd5b604052919050565b600067ffffffffffffffff8211156128ca578081fd5b5060209081020190565b60e01c90565b600060443d10156128ea57610cdd565b600481823e6308c379a06128fe82516128d4565b1461290857610cdd565b6040513d600319016004823e80513d67ffffffffffffffff81602484011181841117156129385750505050610cdd565b828401925082519150808211156129525750505050610cdd565b503d8301602082840101111561296a57505050610cdd565b601f01601f1916810160200160405291505090565b6001600160a01b0381168114610ecf57600080fd5b6001600160701b0381168114610ecf57600080fdfea2646970667358221220c81644fb5118b2211dedf7e78b5379ae287bb2d47b14cc2f7cefe056fc6ac46564736f6c634300060c0033
Deployed ByteCode
0x6080604052600436106102605760003560e01c8063771602f7116101445780639168ae72116100b6578063c816841b1161007a578063c816841b14610669578063c8a4ac9c1461067e578063c8e6c7d91461069e578063d22e9b06146106be578063d8952a49146106d3578063f2fde38b146106f357610267565b80639168ae72146105df578063a5a90636146105ff578063ae94e44814610614578063b67d77c514610634578063c11a56301461065457610267565b80638918c4a2116101085780638918c4a21461054b5780638b9af5c1146105605780638bdb2afa146105805780638da5cb5b146105955780638ef3f761146105aa5780638f907195146105bf57610267565b8063771602f7146104cc5780637ae2b5c7146104ec57806380d04de81461050c57806381028f67146105215780638129fc1c1461053657610267565b80633fb1ccf1116101dd5780636021a9d5116101a15780636021a9d51461042d5780636711281c1461044257806367457022146104575780636d5433e61461047757806370a0823114610497578063715018a6146104b757610267565b80633fb1ccf11461039657806340a141ff146103ab57806347a1671a146103cd5780634d238c8e146103ed5780635fde731c1461040d57610267565b80632681f7e4116102245780632681f7e41461030c5780632cda89431461032e5780632e1a7d4d1461034e57806335aa2e441461036e5780633a4b66f11461038e57610267565b806304d26ebf1461026c57806309b6afb2146102975780630e2286d3146102b7578063150d7e47146102d757806326476204146102ec57610267565b3661026757005b600080fd5b34801561027857600080fd5b50610281610713565b60405161028e919061244f565b60405180910390f35b3480156102a357600080fd5b506102816102b23660046123d2565b610719565b3480156102c357600080fd5b506102816102d2366004612338565b610835565b3480156102e357600080fd5b50610281610860565b6102ff6102fa3660046121c9565b610866565b60405161028e9190612444565b34801561031857600080fd5b50610321610983565b60405161028e91906123fd565b34801561033a57600080fd5b506102816103493660046123a2565b610992565b34801561035a57600080fd5b506102816103693660046123a2565b610a47565b34801561037a57600080fd5b506103216103893660046123a2565b610ca7565b6102ff610cce565b3480156103a257600080fd5b50610321610ce0565b3480156103b757600080fd5b506103cb6103c63660046121c9565b610cef565b005b3480156103d957600080fd5b506103cb6103e8366004612239565b610ed2565b3480156103f957600080fd5b506103cb6104083660046121c9565b6110ea565b34801561041957600080fd5b50610281610428366004612338565b611171565b34801561043957600080fd5b50610281611183565b34801561044e57600080fd5b506103cb611189565b34801561046357600080fd5b50610281610472366004612338565b6111b0565b34801561048357600080fd5b50610281610492366004612338565b6111d8565b3480156104a357600080fd5b506102816104b23660046121c9565b6111f3565b3480156104c357600080fd5b506103cb61120e565b3480156104d857600080fd5b506102816104e7366004612338565b61128d565b3480156104f857600080fd5b50610281610507366004612338565b6112b0565b34801561051857600080fd5b506102816112c0565b34801561052d57600080fd5b5061032161139a565b34801561054257600080fd5b506103cb6113a9565b34801561055757600080fd5b506102816114ab565b34801561056c57600080fd5b5061028161057b366004612338565b6114b1565b34801561058c57600080fd5b506103216114d2565b3480156105a157600080fd5b506103216114e1565b3480156105b657600080fd5b506103216114f0565b3480156105cb57600080fd5b506102816105da366004612338565b6114ff565b3480156105eb57600080fd5b506102816105fa3660046121c9565b611554565b34801561060b57600080fd5b506103cb611566565b34801561062057600080fd5b5061028161062f366004612338565b6118a1565b34801561064057600080fd5b5061028161064f366004612338565b6118b1565b34801561066057600080fd5b506102816118d4565b34801561067557600080fd5b506103216118da565b34801561068a57600080fd5b50610281610699366004612338565b6118e9565b3480156106aa57600080fd5b506102816106b9366004612338565b611920565b3480156106ca57600080fd5b50610281611930565b3480156106df57600080fd5b506103cb6106ee366004612201565b611936565b3480156106ff57600080fd5b506103cb61070e3660046121c9565b6119c5565b606f5481565b6000808061072f84670de0b6b3a7640000611a7c565b905060008561073f606489611abe565b8161074657fe5b049050600061077860715461077261076b606f54607154611af890919063ffffffff16565b8590611abe565b90611a7c565b9050855b8385116108295760006107a66002610772670de0b6b3a76400006107a08a8a611af8565b90611abe565b9050806107b35750610829565b60006107c0828c8c611b1d565b905060006107e1633b9aca00610772856102d286662386f26fc10000611abe565b9050848111610809576107fc83670de0b6b3a7640000611a7c565b6001019750829350610821565b600161081d84670de0b6b3a7640000611a7c565b0396505b50505061077c565b98975050505050505050565b60008161085161084785610699611b6b565b6002855b0461128d565b8161085857fe5b049392505050565b60705481565b60008034116108905760405162461bcd60e51b8152600401610887906127c2565b60405180910390fd5b6066546108af5760405162461bcd60e51b8152600401610887906127ed565b6000805b6001600160a01b038416158015906108cc575060665481105b1561091357836001600160a01b0316606682815481106108e857fe5b6000918252602090912001546001600160a01b03161461090b5760019150610913565b6001016108b3565b506001600160a01b03831615806109275750805b6109435760405162461bcd60e51b81526004016108879061281d565b600061094f3485611b7b565b3360009081526065602052604090205490915061096c9034611af8565b336000908152606560205260409020559392505050565b6068546001600160a01b031681565b6000806000606c60009054906101000a90046001600160a01b03166001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156109e557600080fd5b505afa1580156109f9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1d9190612359565b506001600160701b031691506001600160701b03169150610a3f828286610719565b949350505050565b600080610a52611dcc565b905060008315610a625783610a73565b336000908152606560205260409020545b9050808015801590610a945750336000908152606560205260409020548211155b610ab05760405162461bcd60e51b815260040161088790612756565b606654600090610ac1908790611a7c565b905060005b606654811015610c1d57606754606680546000926001600160a01b0316916321429e609130919086908110610af757fe5b6000918252602090912001546040516001600160e01b031960e085901b168152610b2e92916001600160a01b031690600401612411565b60206040518083038186803b158015610b4657600080fd5b505afa158015610b5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7e91906123ba565b905080610b8b5750610c15565b828111610bcf57610bbd60668381548110610ba257fe5b6000918252602090912001546001600160a01b031682611dd1565b50610bc88482611e92565b9350610c08565b610bfa60668381548110610bdf57fe5b6000918252602090912001546001600160a01b031684611dd1565b50610c058484611e92565b93505b83610c135750610c1d565b505b600101610ac6565b50610c3084610c2a611dcc565b90611e92565b935083831115610c3e578392505b33600090815260656020526040902054610c589084611e92565b336000908152606560205260409020558215610c9d57604051339084156108fc029085906000818181858888f19350505050158015610c9b573d6000803e3d6000fd5b505b5090949350505050565b60668181548110610cb457fe5b6000918252602090912001546001600160a01b0316905081565b6000610cda6000610866565b90505b90565b6069546001600160a01b031681565b610cf7611ed4565b6033546001600160a01b03908116911614610d245760405162461bcd60e51b81526004016108879061278d565b60675460405163010a14f360e51b81526000916001600160a01b0316906321429e6090610d579030908690600401612411565b60206040518083038186803b158015610d6f57600080fd5b505afa158015610d83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da791906123ba565b90508015610dde576000610db9611dcc565b9050610dc58383611dd1565b5080610dcf611dcc565b1415610ddc575050610ecf565b505b60005b606654811015610ecc57826001600160a01b031660668281548110610e0257fe5b6000918252602090912001546001600160a01b03161415610ec45760665460001901811015610e9257606680546000198101908110610e3d57fe5b600091825260209091200154606680546001600160a01b039092169183908110610e6357fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b6066805480610e9d57fe5b600082815260209020810160001990810180546001600160a01b0319169055019055610ecc565b600101610de1565b50505b50565b606c546001600160a01b0316610ecc576001600160a01b03811615610ef75780610f0d565b73fb76e9e7d88e308ab530330ed90e84a9525703195b606880546001600160a01b03199081166001600160a01b039384161791829055606980548216878516179055606a80549091168584161790556040805163c45a015560e01b81529051919092169163c45a0155916004808301926020929190829003018186803b158015610f8057600080fd5b505afa158015610f94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb891906121e5565b606b80546001600160a01b0319166001600160a01b039283161790819055606854604080516315ab88c960e31b815290519284169363e6a439059392169163ad5c464891600480820192602092909190829003018186803b15801561101c57600080fd5b505afa158015611030573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105491906121e5565b856040518363ffffffff1660e01b8152600401611072929190612411565b60206040518083038186803b15801561108a57600080fd5b505afa15801561109e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c291906121e5565b606c80546001600160a01b0319166001600160a01b0392909216919091179055610ecc611189565b6110f2611ed4565b6033546001600160a01b0390811691161461111f5760405162461bcd60e51b81526004016108879061278d565b606680546001810182556000919091527f46501879b8ca8525e8c2fd519e2fbfcfa2ebea26501294aa02cbfcfb12e943540180546001600160a01b0319166001600160a01b0392909216919091179055565b60008161085161084785610699611ed8565b606e5481565b6071546111ae57618235606e819055607255610bb8606f55601e607055620186a06071555b565b60006111ba611b6b565b6108516111c785856118e9565b60026111d1611b6b565b8161084b57fe5b6000818310156111e857816111ea565b825b90505b92915050565b6001600160a01b031660009081526065602052604090205490565b611216611ed4565b6033546001600160a01b039081169116146112435760405162461bcd60e51b81526004016108879061278d565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b808201828110156111ed5760405162461bcd60e51b815260040161088790612625565b6000818311156111e857816111ea565b600080805b60665481101561139457606754606680546000926001600160a01b0316916321429e6091309190869081106112f657fe5b6000918252602090912001546040516001600160e01b031960e085901b16815261132d92916001600160a01b031690600401612411565b60206040518083038186803b15801561134557600080fd5b505afa158015611359573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137d91906123ba565b90506113898382611af8565b9250506001016112c5565b50905090565b606a546001600160a01b031681565b600054610100900460ff16806113c257506113c2611ee4565b806113d0575060005460ff16155b6113ec5760405162461bcd60e51b815260040161088790612683565b600054610100900460ff16158015611417576000805460ff1961ff0019909116610100171660011790555b61141f611eea565b606780546001600160a01b0319908116733014ca10b91cb3d0ad85fef7a3cb95bcac9c0f7917909155606680546001810182556000919091527f46501879b8ca8525e8c2fd519e2fbfcfa2ebea26501294aa02cbfcfb12e9435401805490911673cb876a393f05a6677a8a029f1c6d7603b416c0a61790558015610ecf576000805461ff001916905550565b606d5481565b60006114bb611ed8565b6108516114c885856118e9565b60026111d1611ed8565b606b546001600160a01b031681565b6033546001600160a01b031690565b6067546001600160a01b031681565b60006002820661151657611511611b6b565b611518565b825b90506002820491505b81156111ed5761153183846111b0565b925060028206156115495761154681846111b0565b90505b600282049150611521565b60656020526000908152604090205481565b606a5460408051635c9302c960e01b815290516000926001600160a01b031691635c9302c9916004808301926020929190829003018186803b1580156115ab57600080fd5b505afa1580156115bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e391906123ba565b9050606d548114156116075760405162461bcd60e51b8152600401610887906126d1565b6000607454611614611dcc565b039050600081607454011161163b5760405162461bcd60e51b815260040161088790612653565b606d829055607154606e5460009161165a916107729085908303611abe565b905060008183039050606061168261167d60745485611af890919063ffffffff16565b611fc4565b90506116b18160008151811061169457fe5b6020026020010151610c2a60745486611af890919063ffffffff16565b6074556116bf826000611b7b565b506000816001815181106116cf57fe5b6020026020010151905060006116f660715461077260705485611abe90919063ffffffff16565b905080156117845760695460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611730903390859060040161242b565b602060405180830381600087803b15801561174a57600080fd5b505af115801561175e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117829190612318565b505b60006117a56071546107726072546107a08688611e9290919063ffffffff16565b905060006117b38483611e92565b606954606a5460405163a9059cbb60e01b81529293506001600160a01b039182169263a9059cbb926117eb921690859060040161242b565b602060405180830381600087803b15801561180557600080fd5b505af1158015611819573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061183d9190612318565b5060735461184b9083611af8565b6073556074546040518a917f49a079c90e07ed02ae8283e86eaeb643c637381d30aa7ba06d155e5b744a85439161188e91859187918a918f919033908c90612854565b60405180910390a2505050505050505050565b6000818312156111e857816111ea565b808203828111156111ed5760405162461bcd60e51b815260040161088790612514565b60715481565b606c546001600160a01b031681565b60008115806119045750508082028282828161190157fe5b04145b6111ed5760405162461bcd60e51b8152600401610887906125c0565b6000818313156111e857816111ea565b60725481565b61193e611ed4565b6033546001600160a01b0390811691161461196b5760405162461bcd60e51b81526004016108879061278d565b6001600160a01b0382161561199657606980546001600160a01b0319166001600160a01b0384161790555b6001600160a01b038116156119c157606a80546001600160a01b0319166001600160a01b0383161790555b5050565b6119cd611ed4565b6033546001600160a01b039081169116146119fa5760405162461bcd60e51b81526004016108879061278d565b6001600160a01b038116611a205760405162461bcd60e51b81526004016108879061257a565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b60006111ea83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612166565b600082611acd575060006111ed565b82820282848281611ada57fe5b04146111ea5760405162461bcd60e51b815260040161088790612715565b6000828201838110156111ea5760405162461bcd60e51b8152600401610887906125ee565b600080611b2c856103e5611abe565b90506000611b3a8285611abe565b90506000611b5483611b4e886103e8611abe565b90611af8565b9050808281611b5f57fe5b04979650505050505050565b6b033b2e3c9fd0803ce800000090565b606654600090611b8d575060006111ed565b6001600160a01b03821615611c09576067546040516317066a5760e21b81526001600160a01b0390911690635c19a95c908590611bce9086906004016123fd565b6000604051808303818588803b158015611be757600080fd5b505af1158015611bfb573d6000803e3d6000fd5b5050505050600190506111ed565b606654600090611c1f9061077286611b4e6112c0565b90508360005b60665481108015611c365750600082115b15611dc057606754606680546000926001600160a01b0316916321429e609130919086908110611c6257fe5b6000918252602090912001546040516001600160e01b031960e085901b168152611c9992916001600160a01b031690600401612411565b60206040518083038186803b158015611cb157600080fd5b505afa158015611cc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ce991906123ba565b905083811015611db7576000611cff8583611e92565b9050838110611d0e5783611d10565b805b606754606680549293506001600160a01b0390911691635c19a95c91849187908110611d3857fe5b6000918252602090912001546040516001600160e01b031960e085901b168152611d6e916001600160a01b0316906004016123fd565b6000604051808303818588803b158015611d8757600080fd5b505af1158015611d9b573d6000803e3d6000fd5b5050505050611db38185611e9290919063ffffffff16565b9350505b50600101611c25565b50600195945050505050565b303190565b60675460405163f3fef3a360e01b81526000916001600160a01b03169063f3fef3a390611e04908690869060040161242b565b600060405180830381600087803b158015611e1e57600080fd5b505af1925050508015611e2f575060015b611e8a57611e3b6128da565b80611e465750611e50565b60009150506111ed565b3d808015611e7a576040519150601f19603f3d011682016040523d82523d6000602084013e611e7f565b606091505b5060009150506111ed565b5060016111ed565b60006111ea83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061219d565b3390565b670de0b6b3a764000090565b303b1590565b600054610100900460ff1680611f035750611f03611ee4565b80611f11575060005460ff16155b611f2d5760405162461bcd60e51b815260040161088790612683565b600054610100900460ff16158015611f58576000805460ff1961ff0019909116610100171660011790555b6000611f62611ed4565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015610ecf576000805461ff001916905550565b606060008211611fe65760405162461bcd60e51b815260040161088790612543565b6000611ff183610992565b604080516002808252606080830184529394509091602083019080368337505060695482519293506001600160a01b031691839150600190811061203157fe5b6001600160a01b03928316602091820292909201810191909152606854604080516315ab88c960e31b81529051919093169263ad5c4648926004808301939192829003018186803b15801561208557600080fd5b505afa158015612099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120bd91906121e5565b816000815181106120ca57fe5b6001600160a01b039283166020918202929092010152606854604051637ff36ab560e01b8152911690637ff36ab590849061211090600090869030904290600401612458565b6000604051808303818588803b15801561212957600080fd5b505af115801561213d573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f19168201604052610a3f9190810190612283565b600081836121875760405162461bcd60e51b815260040161088791906124c1565b50600083858161219357fe5b0495945050505050565b600081848411156121c15760405162461bcd60e51b815260040161088791906124c1565b505050900390565b6000602082840312156121da578081fd5b81356111ea8161297f565b6000602082840312156121f6578081fd5b81516111ea8161297f565b60008060408385031215612213578081fd5b823561221e8161297f565b9150602083013561222e8161297f565b809150509250929050565b60008060006060848603121561224d578081fd5b83356122588161297f565b925060208401356122688161297f565b915060408401356122788161297f565b809150509250925092565b60006020808385031215612295578182fd5b825167ffffffffffffffff8111156122ab578283fd5b8301601f810185136122bb578283fd5b80516122ce6122c9826128b4565b61288d565b81815283810190838501858402850186018910156122ea578687fd5b8694505b8385101561230c5780518352600194909401939185019185016122ee565b50979650505050505050565b600060208284031215612329578081fd5b815180151581146111ea578182fd5b6000806040838503121561234a578182fd5b50508035926020909101359150565b60008060006060848603121561236d578283fd5b835161237881612994565b602085015190935061238981612994565b604085015190925063ffffffff81168114612278578182fd5b6000602082840312156123b3578081fd5b5035919050565b6000602082840312156123cb578081fd5b5051919050565b6000806000606084860312156123e6578283fd5b505081359360208301359350604090920135919050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b90815260200190565b600060808201868352602060808185015281875180845260a0860191508289019350845b818110156124a15784516001600160a01b03168352938301939183019160010161247c565b50506001600160a01b039690961660408501525050506060015292915050565b6000602080835283518082850152825b818110156124ed578581018301518582016040015282016124d1565b818111156124fe5783604083870101525b50601f01601f1916929092016040019392505050565b60208082526015908201527464732d6d6174682d7375622d756e646572666c6f7760581b604082015260600190565b60208082526017908201527f6275792076616c75652073686f756c64206265203e2030000000000000000000604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526014908201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526014908201527364732d6d6174682d6164642d6f766572666c6f7760601b604082015260600190565b6020808252601690820152751b9bc819585c9b9a5b99dcc81d1bc818dbdb1b1958dd60521b604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526024908201527f63616e20636f6c6c656374206f6e6c79206f6e636520696e206120756269206360408201526379636c6560e01b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b60208082526017908201527f696e76616c696420776974686472617720616d6f756e74000000000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526011908201527007374616b65206d757374206265203e203607c1b604082015260600190565b6020808252601690820152756e6f20617070726f7665642076616c696461746f727360501b604082015260600190565b6020808252601e908201527f76616c696461746f72206e6f7420696e20617070726f766564206c6973740000604082015260600190565b96875260208701959095526040860193909352606085019190915260808401526001600160a01b031660a083015260c082015260e00190565b60405181810167ffffffffffffffff811182821017156128ac57600080fd5b604052919050565b600067ffffffffffffffff8211156128ca578081fd5b5060209081020190565b60e01c90565b600060443d10156128ea57610cdd565b600481823e6308c379a06128fe82516128d4565b1461290857610cdd565b6040513d600319016004823e80513d67ffffffffffffffff81602484011181841117156129385750505050610cdd565b828401925082519150808211156129525750505050610cdd565b503d8301602082840101111561296a57505050610cdd565b601f01601f1916810160200160405291505090565b6001600160a01b0381168114610ecf57600080fd5b6001600160701b0381168114610ecf57600080fdfea2646970667358221220c81644fb5118b2211dedf7e78b5379ae287bb2d47b14cc2f7cefe056fc6ac46564736f6c634300060c0033