More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 101,939 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Handle Rewards | 329355208 | 1 min ago | IN | 0 ETH | 0.00000719 | ||||
Handle Rewards | 329355009 | 2 mins ago | IN | 0 ETH | 0.00000761 | ||||
Handle Rewards | 329354797 | 3 mins ago | IN | 0 ETH | 0.00000462 | ||||
Handle Rewards | 329354658 | 3 mins ago | IN | 0 ETH | 0.00000548 | ||||
Unstake Gmx | 329353273 | 9 mins ago | IN | 0 ETH | 0.00000697 | ||||
Stake Gmx | 329352472 | 12 mins ago | IN | 0 ETH | 0.00000685 | ||||
Handle Rewards | 329352390 | 13 mins ago | IN | 0 ETH | 0.00000856 | ||||
Handle Rewards | 329352384 | 13 mins ago | IN | 0 ETH | 0.00000901 | ||||
Handle Rewards | 329352353 | 13 mins ago | IN | 0 ETH | 0.00000944 | ||||
Handle Rewards | 329352166 | 14 mins ago | IN | 0 ETH | 0.00000923 | ||||
Handle Rewards | 329352082 | 14 mins ago | IN | 0 ETH | 0.00000866 | ||||
Handle Rewards | 329351777 | 15 mins ago | IN | 0 ETH | 0.00001005 | ||||
Handle Rewards | 329351384 | 17 mins ago | IN | 0 ETH | 0.00001043 | ||||
Handle Rewards | 329350788 | 19 mins ago | IN | 0 ETH | 0.00001068 | ||||
Handle Rewards | 329350637 | 20 mins ago | IN | 0 ETH | 0.00000913 | ||||
Handle Rewards | 329350437 | 21 mins ago | IN | 0 ETH | 0.0000098 | ||||
Handle Rewards | 329347710 | 32 mins ago | IN | 0 ETH | 0.00000995 | ||||
Handle Rewards | 329346993 | 35 mins ago | IN | 0 ETH | 0.0000101 | ||||
Stake Gmx | 329346868 | 36 mins ago | IN | 0 ETH | 0.00000738 | ||||
Handle Rewards | 329346097 | 39 mins ago | IN | 0 ETH | 0.00001186 | ||||
Handle Rewards | 329345880 | 40 mins ago | IN | 0 ETH | 0.00001099 | ||||
Stake Es Gmx | 329345849 | 40 mins ago | IN | 0 ETH | 0.00000812 | ||||
Handle Rewards | 329345805 | 40 mins ago | IN | 0 ETH | 0.0000099 | ||||
Stake Gmx | 329345605 | 41 mins ago | IN | 0 ETH | 0.00001025 | ||||
Handle Rewards | 329345598 | 41 mins ago | IN | 0 ETH | 0.00001367 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
329351777 | 15 mins ago | 0.00016638 ETH | ||||
329351777 | 15 mins ago | 0.00016638 ETH | ||||
329351384 | 17 mins ago | 0.17463014 ETH | ||||
329351384 | 17 mins ago | 0.17463014 ETH | ||||
329350788 | 19 mins ago | 0.00001911 ETH | ||||
329350788 | 19 mins ago | 0.00001911 ETH | ||||
329346097 | 39 mins ago | 0.00115908 ETH | ||||
329346097 | 39 mins ago | 0.00115908 ETH | ||||
329345805 | 40 mins ago | 0.00092515 ETH | ||||
329345805 | 40 mins ago | 0.00092515 ETH | ||||
329345598 | 41 mins ago | 0.00121943 ETH | ||||
329345598 | 41 mins ago | 0.00121943 ETH | ||||
329345385 | 42 mins ago | 0.00968942 ETH | ||||
329345385 | 42 mins ago | 0.00968942 ETH | ||||
329345187 | 43 mins ago | 0.01081203 ETH | ||||
329345187 | 43 mins ago | 0.01081203 ETH | ||||
329342409 | 54 mins ago | 0.00046052 ETH | ||||
329342409 | 54 mins ago | 0.00046052 ETH | ||||
329337827 | 1 hr ago | 0.00224201 ETH | ||||
329337827 | 1 hr ago | 0.00224201 ETH | ||||
329333826 | 1 hr ago | 0.00028606 ETH | ||||
329333826 | 1 hr ago | 0.00028606 ETH | ||||
329332139 | 1 hr ago | 0.00007395 ETH | ||||
329332139 | 1 hr ago | 0.00007395 ETH | ||||
329329080 | 1 hr ago | 0.00133179 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
RewardRouterV2
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 10 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; pragma experimental ABIEncoderV2; import "../libraries/math/SafeMath.sol"; import "../libraries/token/IERC20.sol"; import "../libraries/token/SafeERC20.sol"; import "../libraries/utils/ReentrancyGuard.sol"; import "../libraries/utils/Address.sol"; import "./interfaces/IExternalHandler.sol"; import "./interfaces/IRewardTracker.sol"; import "./interfaces/IRewardRouterV2.sol"; import "./interfaces/IVester.sol"; import "../tokens/interfaces/IMintable.sol"; import "../tokens/interfaces/IWETH.sol"; import "../core/interfaces/IGlpManager.sol"; import "../access/Governable.sol"; contract RewardRouterV2 is IRewardRouterV2, ReentrancyGuard, Governable { using SafeMath for uint256; using SafeERC20 for IERC20; using Address for address payable; enum VotingPowerType { None, BaseStakedAmount, BaseAndBonusStakedAmount } struct InitializeParams { address weth; address gmx; address esGmx; address bnGmx; address glp; address stakedGmxTracker; address bonusGmxTracker; address extendedGmxTracker; address feeGmxTracker; address feeGlpTracker; address stakedGlpTracker; address glpManager; address gmxVester; address glpVester; address externalHandler; address govToken; } uint256 public constant BASIS_POINTS_DIVISOR = 10000; bool public isInitialized; address public weth; address public gmx; address public esGmx; address public bnGmx; address public glp; // GMX Liquidity Provider token address public stakedGmxTracker; address public bonusGmxTracker; address public extendedGmxTracker; address public feeGmxTracker; address public override stakedGlpTracker; address public override feeGlpTracker; address public glpManager; address public gmxVester; address public glpVester; address public externalHandler; uint256 public maxBoostBasisPoints; bool public inStrictTransferMode; address public govToken; VotingPowerType public votingPowerType; bool public inRestakingMode; mapping (address => address) public pendingReceivers; event StakeGmx(address account, address token, uint256 amount); event UnstakeGmx(address account, address token, uint256 amount); event StakeGlp(address account, uint256 amount); event UnstakeGlp(address account, uint256 amount); receive() external payable { require(msg.sender == weth, "Router: invalid sender"); } function initialize(InitializeParams memory _initializeParams) external onlyGov { require(!isInitialized, "already initialized"); isInitialized = true; weth = _initializeParams.weth; gmx = _initializeParams.gmx; esGmx = _initializeParams.esGmx; bnGmx = _initializeParams.bnGmx; glp = _initializeParams.glp; stakedGmxTracker = _initializeParams.stakedGmxTracker; bonusGmxTracker = _initializeParams.bonusGmxTracker; extendedGmxTracker = _initializeParams.extendedGmxTracker; feeGmxTracker = _initializeParams.feeGmxTracker; feeGlpTracker = _initializeParams.feeGlpTracker; stakedGlpTracker = _initializeParams.stakedGlpTracker; glpManager = _initializeParams.glpManager; gmxVester = _initializeParams.gmxVester; glpVester = _initializeParams.glpVester; externalHandler = _initializeParams.externalHandler; govToken = _initializeParams.govToken; } function setGovToken(address _govToken) external onlyGov { govToken = _govToken; } function setInStrictTransferMode(bool _inStrictTransferMode) external onlyGov { inStrictTransferMode = _inStrictTransferMode; } function setMaxBoostBasisPoints(uint256 _maxBoostBasisPoints) external onlyGov { maxBoostBasisPoints = _maxBoostBasisPoints; } function setVotingPowerType(VotingPowerType _votingPowerType) external onlyGov { votingPowerType = _votingPowerType; } function setInRestakingMode(bool _inRestakingMode) external onlyGov { inRestakingMode = _inRestakingMode; } // to help users who accidentally send their tokens to this contract function withdrawToken(address _token, address _account, uint256 _amount) external onlyGov { IERC20(_token).safeTransfer(_account, _amount); } function batchStakeGmxForAccounts(address[] memory _accounts, uint256[] memory _amounts) external nonReentrant onlyGov { address _gmx = gmx; for (uint256 i = 0; i < _accounts.length; i++) { _stakeGmx(msg.sender, _accounts[i], _gmx, _amounts[i]); } } function batchCompoundForAccounts(address[] memory _accounts) external nonReentrant onlyGov { for (uint256 i = 0; i < _accounts.length; i++) { _compound(_accounts[i]); } } function batchRestakeForAccounts(address[] memory _accounts) external nonReentrant onlyGov { for (uint256 i = 0; i < _accounts.length; i++) { _restakeForAccount(_accounts[i]); } } function multicall(bytes[] memory data) external returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i; i < data.length; i++) { (bool success, bytes memory result) = address(this).delegatecall(data[i]); require(success, "call failed"); results[i] = result; } return results; } function makeExternalCalls( address[] memory externalCallTargets, bytes[] memory externalCallDataList, address[] memory refundTokens, address[] memory refundReceivers ) external nonReentrant { IExternalHandler(externalHandler).makeExternalCalls( externalCallTargets, externalCallDataList, refundTokens, refundReceivers ); } function stakeGmx(uint256 _amount) external nonReentrant { _stakeGmx(msg.sender, msg.sender, gmx, _amount); } function stakeEsGmx(uint256 _amount) external nonReentrant { _stakeGmx(msg.sender, msg.sender, esGmx, _amount); } function unstakeGmx(uint256 _amount) external nonReentrant { _restakeForAccount(msg.sender); _unstakeGmx(msg.sender, gmx, _amount, true); } function unstakeEsGmx(uint256 _amount) external nonReentrant { _restakeForAccount(msg.sender); _unstakeGmx(msg.sender, esGmx, _amount, true); } function mintAndStakeGlp(address _token, uint256 _amount, uint256 _minUsdg, uint256 _minGlp) external nonReentrant returns (uint256) { _validateAmount(_amount); uint256 glpAmount = _mintAndStakeGlp(msg.sender, _token, _amount, _minUsdg, _minGlp); emit StakeGlp(msg.sender, glpAmount); return glpAmount; } function mintAndStakeGlpETH(uint256 _minUsdg, uint256 _minGlp) external payable nonReentrant returns (uint256) { require(msg.value > 0, "invalid msg.value"); IWETH(weth).deposit{value: msg.value}(); IERC20(weth).approve(glpManager, msg.value); uint256 glpAmount = _mintAndStakeGlp(address(this), weth, msg.value, _minUsdg, _minGlp); emit StakeGlp(msg.sender, glpAmount); return glpAmount; } function unstakeAndRedeemGlp(address _tokenOut, uint256 _glpAmount, uint256 _minOut, address _receiver) external nonReentrant returns (uint256) { uint256 amountOut = _unstakeAndRedeemGlp(_tokenOut, _glpAmount, _minOut, _receiver); emit UnstakeGlp(msg.sender, _glpAmount); return amountOut; } function unstakeAndRedeemGlpETH(uint256 _glpAmount, uint256 _minOut, address payable _receiver) external nonReentrant returns (uint256) { uint256 amountOut = _unstakeAndRedeemGlp(weth, _glpAmount, _minOut, address(this)); IWETH(weth).withdraw(amountOut); _receiver.sendValue(amountOut); emit UnstakeGlp(msg.sender, _glpAmount); return amountOut; } function claim() external nonReentrant { _claim(stakedGmxTracker, stakedGlpTracker, msg.sender, msg.sender); _claimGmxFees(msg.sender, msg.sender); _claim(feeGmxTracker, feeGlpTracker, msg.sender, msg.sender); } function claimEsGmx() external nonReentrant { _claim(stakedGmxTracker, stakedGlpTracker, msg.sender, msg.sender); } function claimFees() external nonReentrant { _claimGmxFees(msg.sender, msg.sender); _claim(feeGmxTracker, feeGlpTracker, msg.sender, msg.sender); } function compound() external nonReentrant { _compound(msg.sender); } function handleRewards( bool _shouldClaimGmx, bool _shouldStakeGmx, bool _shouldClaimEsGmx, bool _shouldStakeEsGmx, bool _shouldStakeMultiplierPoints, bool _shouldClaimWeth, bool _shouldConvertWethToEth ) external nonReentrant { address account = msg.sender; uint256 gmxAmount = 0; if (_shouldClaimGmx) { uint256 gmxAmount0 = _claimVestedGmx(account, account); uint256 gmxAmount1 = _claimGmxFees(account, account); gmxAmount = gmxAmount0.add(gmxAmount1); } if (_shouldStakeGmx && gmxAmount > 0) { _stakeGmx(account, account, gmx, gmxAmount); } uint256 esGmxAmount = 0; if (_shouldClaimEsGmx) { esGmxAmount = _claim(stakedGmxTracker, stakedGlpTracker, account, account); } if (_shouldStakeEsGmx && esGmxAmount > 0) { _stakeGmx(account, account, esGmx, esGmxAmount); } if (_shouldStakeMultiplierPoints) { _restakeForAccount(account); _stakeBnGmx(account); } if (_shouldClaimWeth) { if (_shouldConvertWethToEth) { uint256 wethAmount = _claim(feeGmxTracker, feeGlpTracker, account, address(this)); _convertWethToEth(wethAmount); } else { _claim(feeGmxTracker, feeGlpTracker, account, account); } } _syncVotingPower(account); } function handleRewardsV2( address _gmxReceiver, bool _shouldClaimGmx, bool _shouldStakeGmx, bool _shouldClaimEsGmx, bool _shouldStakeEsGmx, bool _shouldStakeMultiplierPoints, bool _shouldClaimWeth, bool _shouldConvertWethToEth ) external nonReentrant { address account = msg.sender; uint256 gmxAmount = 0; if (_shouldClaimGmx) { uint256 gmxAmount0 = _claimVestedGmx(account, _gmxReceiver); uint256 gmxAmount1 = _claimGmxFees(account, _gmxReceiver); gmxAmount = gmxAmount0.add(gmxAmount1); } if (_shouldStakeGmx && gmxAmount > 0) { require(_gmxReceiver == account, "cannot stake GMX if _gmxReceiver != account"); _stakeGmx(account, account, gmx, gmxAmount); } uint256 esGmxAmount = 0; if (_shouldClaimEsGmx) { esGmxAmount = _claim(stakedGmxTracker, stakedGlpTracker, account, account); } if (_shouldStakeEsGmx && esGmxAmount > 0) { _stakeGmx(account, account, esGmx, esGmxAmount); } if (_shouldStakeMultiplierPoints) { _restakeForAccount(account); _stakeBnGmx(account); } if (_shouldClaimWeth) { if (_shouldConvertWethToEth) { uint256 wethAmount = _claim(feeGmxTracker, feeGlpTracker, account, address(this)); _convertWethToEth(wethAmount); } else { _claim(feeGmxTracker, feeGlpTracker, account, account); } } _syncVotingPower(account); } // the _validateReceiver function checks that the averageStakedAmounts and cumulativeRewards // values of an account are zero, this is to help ensure that vesting calculations can be // done correctly // averageStakedAmounts and cumulativeRewards are updated if the claimable reward for an account // is more than zero // it is possible for multiple transfers to be sent into a single account, using signalTransfer and // acceptTransfer, if those values have not been updated yet // for GLP transfers it is also possible to transfer GLP into an account using the StakedGlp contract function signalTransfer(address _receiver) external nonReentrant { _validateNotVesting(msg.sender); _validateReceiver(_receiver); if (inStrictTransferMode) { uint256 balance = IRewardTracker(feeGmxTracker).stakedAmounts(msg.sender); uint256 allowance = IERC20(feeGmxTracker).allowance(msg.sender, _receiver); require(allowance >= balance, "insufficient allowance"); } pendingReceivers[msg.sender] = _receiver; } function acceptTransfer(address _sender) external nonReentrant { _validateNotVesting(_sender); address receiver = msg.sender; require(pendingReceivers[_sender] == receiver, "transfer not signalled"); delete pendingReceivers[_sender]; _validateReceiver(receiver); _compound(_sender); uint256 stakedGmx = IRewardTracker(stakedGmxTracker).depositBalances(_sender, gmx); if (stakedGmx > 0) { _unstakeGmx(_sender, gmx, stakedGmx, false); _stakeGmx(_sender, receiver, gmx, stakedGmx); } uint256 stakedEsGmx = IRewardTracker(stakedGmxTracker).depositBalances(_sender, esGmx); if (stakedEsGmx > 0) { _unstakeGmx(_sender, esGmx, stakedEsGmx, false); _stakeGmx(_sender, receiver, esGmx, stakedEsGmx); } uint256 stakedBnGmx = IRewardTracker(extendedGmxTracker).depositBalances(_sender, bnGmx); _acceptTransferRestake(feeGmxTracker, extendedGmxTracker, _sender, receiver, bnGmx, stakedBnGmx); uint256 esGmxBalance = IERC20(esGmx).balanceOf(_sender); if (esGmxBalance > 0) { IERC20(esGmx).transferFrom(_sender, receiver, esGmxBalance); } uint256 bnGmxBalance = IERC20(bnGmx).balanceOf(_sender); if (bnGmxBalance > 0) { _burnToken(bnGmx, _sender, bnGmxBalance); _mintToken(bnGmx, receiver, bnGmxBalance); } uint256 glpAmount = IRewardTracker(feeGlpTracker).depositBalances(_sender, glp); _acceptTransferRestake(stakedGlpTracker, feeGlpTracker, _sender, receiver, glp, glpAmount); IVester(gmxVester).transferStakeValues(_sender, receiver); IVester(glpVester).transferStakeValues(_sender, receiver); _syncVotingPower(_sender); _syncVotingPower(receiver); } function _claim(address _rewardTracker0, address _rewardTracker1, address _account, address _receiver) private returns (uint256) { uint256 amount0 = IRewardTracker(_rewardTracker0).claimForAccount(_account, _receiver); uint256 amount1 = IRewardTracker(_rewardTracker1).claimForAccount(_account, _receiver); uint256 amount = amount0.add(amount1); return(amount); } function _claimGmxFees(address _account, address _receiver) private returns (uint256) { uint256 gmxAmount = IRewardTracker(extendedGmxTracker).claimForAccount(_account, _receiver); return(gmxAmount); } function _claimVestedGmx(address _account, address _receiver) private returns (uint256) { uint256 gmxAmount0 = IVester(gmxVester).claimForAccount(_account, _receiver); uint256 gmxAmount1 = IVester(glpVester).claimForAccount(_account, _receiver); uint256 gmxAmount = gmxAmount0.add(gmxAmount1); return (gmxAmount); } function _convertWethToEth(uint256 _amount) private { IWETH(weth).withdraw(_amount); payable(msg.sender).sendValue(_amount); } function _compound(address _account) private { uint256 gmxAmount = _claimGmxFees(_account, _account); if (gmxAmount > 0) { _stakeGmx(_account, _account, gmx, gmxAmount); } uint256 esGmxAmount = _claim(stakedGmxTracker, stakedGlpTracker, _account, _account); if (esGmxAmount > 0) { _stakeGmx(_account, _account, esGmx, esGmxAmount); } _restakeForAccount(_account); _stakeBnGmx(_account); _syncVotingPower(_account); } function _stakeGmx(address _fundingAccount, address _account, address _token, uint256 _amount) private { _validateAmount(_amount); IRewardTracker(stakedGmxTracker).stakeForAccount(_fundingAccount, _account, _token, _amount); IRewardTracker(bonusGmxTracker).stakeForAccount(_account, _account, stakedGmxTracker, _amount); IRewardTracker(extendedGmxTracker).stakeForAccount(_account, _account, bonusGmxTracker, _amount); IRewardTracker(feeGmxTracker).stakeForAccount(_account, _account, extendedGmxTracker, _amount); _syncVotingPower(_account); emit StakeGmx(_account, _token, _amount); } // note that _syncVotingPower is not called here, in functions which // call _stakeBnGmx it should be ensured that _syncVotingPower is called // after function _stakeBnGmx(address _account) private { IRewardTracker(bonusGmxTracker).claimForAccount(_account, _account); // get the bnGmx balance of the user, this would be the amount of // bnGmx that has not been staked uint256 bnGmxAmount = IERC20(bnGmx).balanceOf(_account); if (bnGmxAmount == 0) { return; } // get the baseStakedAmount which would be the sum of staked gmx and staked esGmx tokens uint256 baseStakedAmount = IRewardTracker(stakedGmxTracker).stakedAmounts(_account); uint256 maxAllowedBnGmxAmount = baseStakedAmount.mul(maxBoostBasisPoints).div(BASIS_POINTS_DIVISOR); uint256 currentBnGmxAmount = IRewardTracker(extendedGmxTracker).depositBalances(_account, bnGmx); if (currentBnGmxAmount == maxAllowedBnGmxAmount) { return; } // if the currentBnGmxAmount is more than the maxAllowedBnGmxAmount // unstake the excess tokens if (currentBnGmxAmount > maxAllowedBnGmxAmount) { uint256 amountToUnstake = currentBnGmxAmount.sub(maxAllowedBnGmxAmount); IRewardTracker(feeGmxTracker).unstakeForAccount(_account, extendedGmxTracker, amountToUnstake, _account); IRewardTracker(extendedGmxTracker).unstakeForAccount(_account, bnGmx, amountToUnstake, _account); return; } uint256 maxStakeableBnGmxAmount = maxAllowedBnGmxAmount.sub(currentBnGmxAmount); if (bnGmxAmount > maxStakeableBnGmxAmount) { bnGmxAmount = maxStakeableBnGmxAmount; } IRewardTracker(extendedGmxTracker).stakeForAccount(_account, _account, bnGmx, bnGmxAmount); IRewardTracker(feeGmxTracker).stakeForAccount(_account, _account, extendedGmxTracker, bnGmxAmount); } function _unstakeGmx(address _account, address _token, uint256 _amount, bool _shouldReduceBnGmx) private { _validateAmount(_amount); uint256 balance = IRewardTracker(stakedGmxTracker).stakedAmounts(_account); IRewardTracker(feeGmxTracker).unstakeForAccount(_account, extendedGmxTracker, _amount, _account); IRewardTracker(extendedGmxTracker).unstakeForAccount(_account, bonusGmxTracker, _amount, _account); IRewardTracker(bonusGmxTracker).unstakeForAccount(_account, stakedGmxTracker, _amount, _account); IRewardTracker(stakedGmxTracker).unstakeForAccount(_account, _token, _amount, _account); if (_shouldReduceBnGmx) { IRewardTracker(bonusGmxTracker).claimForAccount(_account, _account); // unstake and burn staked bnGmx tokens uint256 stakedBnGmx = IRewardTracker(extendedGmxTracker).depositBalances(_account, bnGmx); if (stakedBnGmx > 0) { uint256 reductionAmount = stakedBnGmx.mul(_amount).div(balance); IRewardTracker(feeGmxTracker).unstakeForAccount(_account, extendedGmxTracker, reductionAmount, _account); IRewardTracker(extendedGmxTracker).unstakeForAccount(_account, bnGmx, reductionAmount, _account); _burnToken(bnGmx, _account, reductionAmount); } // burn bnGmx tokens from user's balance uint256 bnGmxBalance = IERC20(bnGmx).balanceOf(_account); if (bnGmxBalance > 0) { uint256 amountToBurn = bnGmxBalance.mul(_amount).div(balance); _burnToken(bnGmx, _account, amountToBurn); } } _syncVotingPower(_account); emit UnstakeGmx(_account, _token, _amount); } function _syncVotingPower(address _account) private { if (votingPowerType == VotingPowerType.None) { return; } if (votingPowerType == VotingPowerType.BaseStakedAmount) { uint256 baseStakedAmount = IRewardTracker(stakedGmxTracker).stakedAmounts(_account); _syncVotingPower(_account, baseStakedAmount); return; } if (votingPowerType == VotingPowerType.BaseAndBonusStakedAmount) { uint256 stakedAmount = IRewardTracker(feeGmxTracker).stakedAmounts(_account); _syncVotingPower(_account, stakedAmount); return; } revert("unsupported votingPowerType"); } function _syncVotingPower(address _account, uint256 _amount) private { uint256 currentVotingPower = IERC20(govToken).balanceOf(_account); if (currentVotingPower == _amount) { return; } if (currentVotingPower > _amount) { uint256 amountToBurn = currentVotingPower.sub(_amount); _burnToken(govToken, _account, amountToBurn); return; } uint256 amountToMint = _amount.sub(currentVotingPower); _mintToken(govToken, _account, amountToMint); } function _mintAndStakeGlp(address _address, address _token, uint256 _amount, uint256 _minUsdg, uint256 _minGlp) private returns (uint256) { address account = msg.sender; uint256 glpAmount = IGlpManager(glpManager).addLiquidityForAccount(_address, account, _token, _amount, _minUsdg, _minGlp); IRewardTracker(feeGlpTracker).stakeForAccount(account, account, glp, glpAmount); IRewardTracker(stakedGlpTracker).stakeForAccount(account, account, feeGlpTracker, glpAmount); return glpAmount; } function _unstakeAndRedeemGlp(address _tokenOut, uint256 _glpAmount, uint256 _minOut, address _receiver) private returns (uint256) { require(_glpAmount > 0, "invalid _glpAmount"); address account = msg.sender; IRewardTracker(stakedGlpTracker).unstakeForAccount(account, feeGlpTracker, _glpAmount, account); IRewardTracker(feeGlpTracker).unstakeForAccount(account, glp, _glpAmount, account); uint256 amountOut = IGlpManager(glpManager).removeLiquidityForAccount(account, _tokenOut, _glpAmount, _minOut, _receiver); return amountOut; } function _restakeForAccount(address _account) private { if (!inRestakingMode) { return; } uint256 bonusGmxTrackerBalance = IRewardTracker(feeGmxTracker).depositBalances(_account, bonusGmxTracker); if (bonusGmxTrackerBalance > 0) { uint256 reservedForVesting = IVester(gmxVester).pairAmounts(_account); if (reservedForVesting > 0) { IERC20(feeGmxTracker).safeTransferFrom(gmxVester, _account, reservedForVesting); _restakeBonusGmxTracker(_account, bonusGmxTrackerBalance); _restakeBnGmx(_account); IERC20(feeGmxTracker).safeTransferFrom(_account, gmxVester, reservedForVesting); } else { _restakeBonusGmxTracker(_account, bonusGmxTrackerBalance); _restakeBnGmx(_account); } } } function _restakeBonusGmxTracker(address _account, uint256 _bonusGmxTrackerBalance) private { IRewardTracker(feeGmxTracker).unstakeForAccount(_account, bonusGmxTracker, _bonusGmxTrackerBalance, _account); IRewardTracker(extendedGmxTracker).stakeForAccount(_account, _account, bonusGmxTracker, _bonusGmxTrackerBalance); IRewardTracker(feeGmxTracker).stakeForAccount(_account, _account, extendedGmxTracker, _bonusGmxTrackerBalance); } function _restakeBnGmx(address _account) private { uint256 stakedBnGmx = IRewardTracker(feeGmxTracker).depositBalances(_account, bnGmx); if (stakedBnGmx > 0) { IRewardTracker(feeGmxTracker).unstakeForAccount(_account, bnGmx, stakedBnGmx, _account); _stakeBnGmx(_account); _syncVotingPower(_account); } } function _acceptTransferRestake(address _rewardTracker0, address _rewardTracker1, address _sender, address _receiver, address _token, uint256 _amount) private { if (_amount > 0) { IRewardTracker(_rewardTracker0).unstakeForAccount(_sender, _rewardTracker1, _amount, _sender); IRewardTracker(_rewardTracker1).unstakeForAccount(_sender, _token, _amount, _sender); IRewardTracker(_rewardTracker1).stakeForAccount(_sender, _receiver, _token, _amount); IRewardTracker(_rewardTracker0).stakeForAccount(_receiver, _receiver, _rewardTracker1, _amount); } } function _mintToken(address _token, address _account, uint256 _amountToMint) private { IMintable(_token).mint(_account, _amountToMint); } function _burnToken(address _token, address _account, uint256 _amountToBurn) private { IMintable(_token).burn(_account, _amountToBurn); } function _validateReceiver(address _receiver) private view { require(IRewardTracker(stakedGmxTracker).averageStakedAmounts(_receiver) == 0, "stakedGmxTracker.averageStakedAmounts > 0"); require(IRewardTracker(stakedGmxTracker).cumulativeRewards(_receiver) == 0, "stakedGmxTracker.cumulativeRewards > 0"); require(IRewardTracker(bonusGmxTracker).averageStakedAmounts(_receiver) == 0, "bonusGmxTracker.averageStakedAmounts > 0"); require(IRewardTracker(bonusGmxTracker).cumulativeRewards(_receiver) == 0, "bonusGmxTracker.cumulativeRewards > 0"); require(IRewardTracker(extendedGmxTracker).averageStakedAmounts(_receiver) == 0, "extendedGmxTracker.averageStakedAmounts > 0"); require(IRewardTracker(extendedGmxTracker).cumulativeRewards(_receiver) == 0, "extendedGmxTracker.cumulativeRewards > 0"); require(IRewardTracker(feeGmxTracker).averageStakedAmounts(_receiver) == 0, "feeGmxTracker.averageStakedAmounts > 0"); require(IRewardTracker(feeGmxTracker).cumulativeRewards(_receiver) == 0, "feeGmxTracker.cumulativeRewards > 0"); require(IVester(gmxVester).transferredAverageStakedAmounts(_receiver) == 0, "gmxVester.transferredAverageStakedAmounts > 0"); require(IVester(gmxVester).transferredCumulativeRewards(_receiver) == 0, "gmxVester.transferredCumulativeRewards > 0"); require(IRewardTracker(stakedGlpTracker).averageStakedAmounts(_receiver) == 0, "stakedGlpTracker.averageStakedAmounts > 0"); require(IRewardTracker(stakedGlpTracker).cumulativeRewards(_receiver) == 0, "stakedGlpTracker.cumulativeRewards > 0"); require(IRewardTracker(feeGlpTracker).averageStakedAmounts(_receiver) == 0, "feeGlpTracker.averageStakedAmounts > 0"); require(IRewardTracker(feeGlpTracker).cumulativeRewards(_receiver) == 0, "feeGlpTracker.cumulativeRewards > 0"); require(IVester(glpVester).transferredAverageStakedAmounts(_receiver) == 0, "gmxVester.transferredAverageStakedAmounts > 0"); require(IVester(glpVester).transferredCumulativeRewards(_receiver) == 0, "gmxVester.transferredCumulativeRewards > 0"); require(IERC20(gmxVester).balanceOf(_receiver) == 0, "gmxVester.balance > 0"); require(IERC20(glpVester).balanceOf(_receiver) == 0, "glpVester.balance > 0"); } function _validateNotVesting(address _sender) private view { require(IERC20(gmxVester).balanceOf(_sender) == 0 && IERC20(glpVester).balanceOf(_sender) == 0, "sender has vested tokens"); } function _validateAmount(uint256 _amount) private pure { require(_amount > 0, "invalid _amount"); } }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; contract Governable { address public gov; constructor() public { gov = msg.sender; } modifier onlyGov() { require(msg.sender == gov, "Governable: forbidden"); _; } function setGov(address _gov) external onlyGov { gov = _gov; } }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; /** * @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 "./IERC20.sol"; import "../math/SafeMath.sol"; import "../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.2; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.3._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.3._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; /** * @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 SafeMath { /** * @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; } }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; pragma experimental ABIEncoderV2; interface IExternalHandler { function makeExternalCalls( address[] memory targets, bytes[] memory dataList, address[] memory refundTokens, address[] memory refundReceivers ) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; interface IRewardTracker { function depositBalances(address _account, address _depositToken) external view returns (uint256); function stakedAmounts(address _account) external view returns (uint256); function updateRewards() external; function stake(address _depositToken, uint256 _amount) external; function stakeForAccount(address _fundingAccount, address _account, address _depositToken, uint256 _amount) external; function unstake(address _depositToken, uint256 _amount) external; function unstakeForAccount(address _account, address _depositToken, uint256 _amount, address _receiver) external; function tokensPerInterval() external view returns (uint256); function claim(address _receiver) external returns (uint256); function claimForAccount(address _account, address _receiver) external returns (uint256); function claimable(address _account) external view returns (uint256); function averageStakedAmounts(address _account) external view returns (uint256); function cumulativeRewards(address _account) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () internal { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; interface IVester { function rewardTracker() external view returns (address); function claimForAccount(address _account, address _receiver) external returns (uint256); function claimable(address _account) external view returns (uint256); function cumulativeClaimAmounts(address _account) external view returns (uint256); function claimedAmounts(address _account) external view returns (uint256); function pairAmounts(address _account) external view returns (uint256); function getVestedAmount(address _account) external view returns (uint256); function transferredAverageStakedAmounts(address _account) external view returns (uint256); function transferredCumulativeRewards(address _account) external view returns (uint256); function cumulativeRewardDeductions(address _account) external view returns (uint256); function bonusRewards(address _account) external view returns (uint256); function transferStakeValues(address _sender, address _receiver) external; function setTransferredAverageStakedAmounts(address _account, uint256 _amount) external; function setTransferredCumulativeRewards(address _account, uint256 _amount) external; function setCumulativeRewardDeductions(address _account, uint256 _amount) external; function setBonusRewards(address _account, uint256 _amount) external; function getMaxVestableAmount(address _account) external view returns (uint256); function getCombinedAverageStakedAmount(address _account) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; interface IRewardRouterV2 { function feeGlpTracker() external view returns (address); function stakedGlpTracker() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; interface IMintable { function isMinter(address _account) external returns (bool); function setMinter(address _minter, bool _isActive) external; function mint(address _account, uint256 _amount) external; function burn(address _account, uint256 _amount) external; }
//SPDX-License-Identifier: MIT pragma solidity 0.6.12; interface IWETH { function deposit() external payable; function transfer(address to, uint value) external returns (bool); function withdraw(uint) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; import "./IVault.sol"; interface IGlpManager { function glp() external view returns (address); function usdg() external view returns (address); function vault() external view returns (IVault); function cooldownDuration() external returns (uint256); function getAumInUsdg(bool maximise) external view returns (uint256); function lastAddedAt(address _account) external returns (uint256); function addLiquidity(address _token, uint256 _amount, uint256 _minUsdg, uint256 _minGlp) external returns (uint256); function addLiquidityForAccount(address _fundingAccount, address _account, address _token, uint256 _amount, uint256 _minUsdg, uint256 _minGlp) external returns (uint256); function removeLiquidity(address _tokenOut, uint256 _glpAmount, uint256 _minOut, address _receiver) external returns (uint256); function removeLiquidityForAccount(address _account, address _tokenOut, uint256 _glpAmount, uint256 _minOut, address _receiver) external returns (uint256); function setShortsTrackerAveragePriceWeight(uint256 _shortsTrackerAveragePriceWeight) external; function setCooldownDuration(uint256 _cooldownDuration) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; import "./IVaultUtils.sol"; interface IVault { function isInitialized() external view returns (bool); function isSwapEnabled() external view returns (bool); function isLeverageEnabled() external view returns (bool); function setVaultUtils(IVaultUtils _vaultUtils) external; function setError(uint256 _errorCode, string calldata _error) external; function router() external view returns (address); function usdg() external view returns (address); function gov() external view returns (address); function whitelistedTokenCount() external view returns (uint256); function maxLeverage() external view returns (uint256); function minProfitTime() external view returns (uint256); function hasDynamicFees() external view returns (bool); function fundingInterval() external view returns (uint256); function totalTokenWeights() external view returns (uint256); function getTargetUsdgAmount(address _token) external view returns (uint256); function inManagerMode() external view returns (bool); function inPrivateLiquidationMode() external view returns (bool); function maxGasPrice() external view returns (uint256); function approvedRouters(address _account, address _router) external view returns (bool); function isLiquidator(address _account) external view returns (bool); function isManager(address _account) external view returns (bool); function minProfitBasisPoints(address _token) external view returns (uint256); function tokenBalances(address _token) external view returns (uint256); function lastFundingTimes(address _token) external view returns (uint256); function setMaxLeverage(uint256 _maxLeverage) external; function setInManagerMode(bool _inManagerMode) external; function setManager(address _manager, bool _isManager) external; function setIsSwapEnabled(bool _isSwapEnabled) external; function setIsLeverageEnabled(bool _isLeverageEnabled) external; function setMaxGasPrice(uint256 _maxGasPrice) external; function setUsdgAmount(address _token, uint256 _amount) external; function setBufferAmount(address _token, uint256 _amount) external; function setMaxGlobalShortSize(address _token, uint256 _amount) external; function setInPrivateLiquidationMode(bool _inPrivateLiquidationMode) external; function setLiquidator(address _liquidator, bool _isActive) external; function setFundingRate(uint256 _fundingInterval, uint256 _fundingRateFactor, uint256 _stableFundingRateFactor) external; function setFees( uint256 _taxBasisPoints, uint256 _stableTaxBasisPoints, uint256 _mintBurnFeeBasisPoints, uint256 _swapFeeBasisPoints, uint256 _stableSwapFeeBasisPoints, uint256 _marginFeeBasisPoints, uint256 _liquidationFeeUsd, uint256 _minProfitTime, bool _hasDynamicFees ) external; function setTokenConfig( address _token, uint256 _tokenDecimals, uint256 _redemptionBps, uint256 _minProfitBps, uint256 _maxUsdgAmount, bool _isStable, bool _isShortable ) external; function setPriceFeed(address _priceFeed) external; function withdrawFees(address _token, address _receiver) external returns (uint256); function directPoolDeposit(address _token) external; function buyUSDG(address _token, address _receiver) external returns (uint256); function sellUSDG(address _token, address _receiver) external returns (uint256); function swap(address _tokenIn, address _tokenOut, address _receiver) external returns (uint256); function increasePosition(address _account, address _collateralToken, address _indexToken, uint256 _sizeDelta, bool _isLong) external; function decreasePosition(address _account, address _collateralToken, address _indexToken, uint256 _collateralDelta, uint256 _sizeDelta, bool _isLong, address _receiver) external returns (uint256); function validateLiquidation(address _account, address _collateralToken, address _indexToken, bool _isLong, bool _raise) external view returns (uint256, uint256); function liquidatePosition(address _account, address _collateralToken, address _indexToken, bool _isLong, address _feeReceiver) external; function tokenToUsdMin(address _token, uint256 _tokenAmount) external view returns (uint256); function priceFeed() external view returns (address); function fundingRateFactor() external view returns (uint256); function stableFundingRateFactor() external view returns (uint256); function cumulativeFundingRates(address _token) external view returns (uint256); function getNextFundingRate(address _token) external view returns (uint256); function getFeeBasisPoints(address _token, uint256 _usdgDelta, uint256 _feeBasisPoints, uint256 _taxBasisPoints, bool _increment) external view returns (uint256); function liquidationFeeUsd() external view returns (uint256); function taxBasisPoints() external view returns (uint256); function stableTaxBasisPoints() external view returns (uint256); function mintBurnFeeBasisPoints() external view returns (uint256); function swapFeeBasisPoints() external view returns (uint256); function stableSwapFeeBasisPoints() external view returns (uint256); function marginFeeBasisPoints() external view returns (uint256); function allWhitelistedTokensLength() external view returns (uint256); function allWhitelistedTokens(uint256) external view returns (address); function whitelistedTokens(address _token) external view returns (bool); function stableTokens(address _token) external view returns (bool); function shortableTokens(address _token) external view returns (bool); function feeReserves(address _token) external view returns (uint256); function globalShortSizes(address _token) external view returns (uint256); function globalShortAveragePrices(address _token) external view returns (uint256); function maxGlobalShortSizes(address _token) external view returns (uint256); function tokenDecimals(address _token) external view returns (uint256); function tokenWeights(address _token) external view returns (uint256); function guaranteedUsd(address _token) external view returns (uint256); function poolAmounts(address _token) external view returns (uint256); function bufferAmounts(address _token) external view returns (uint256); function reservedAmounts(address _token) external view returns (uint256); function usdgAmounts(address _token) external view returns (uint256); function maxUsdgAmounts(address _token) external view returns (uint256); function getRedemptionAmount(address _token, uint256 _usdgAmount) external view returns (uint256); function getMaxPrice(address _token) external view returns (uint256); function getMinPrice(address _token) external view returns (uint256); function getDelta(address _indexToken, uint256 _size, uint256 _averagePrice, bool _isLong, uint256 _lastIncreasedTime) external view returns (bool, uint256); function getPosition(address _account, address _collateralToken, address _indexToken, bool _isLong) external view returns (uint256, uint256, uint256, uint256, uint256, uint256, bool, uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; interface IVaultUtils { function updateCumulativeFundingRate(address _collateralToken, address _indexToken) external returns (bool); function validateIncreasePosition(address _account, address _collateralToken, address _indexToken, uint256 _sizeDelta, bool _isLong) external view; function validateDecreasePosition(address _account, address _collateralToken, address _indexToken, uint256 _collateralDelta, uint256 _sizeDelta, bool _isLong, address _receiver) external view; function validateLiquidation(address _account, address _collateralToken, address _indexToken, bool _isLong, bool _raise) external view returns (uint256, uint256); function getEntryFundingRate(address _collateralToken, address _indexToken, bool _isLong) external view returns (uint256); function getPositionFee(address _account, address _collateralToken, address _indexToken, bool _isLong, uint256 _sizeDelta) external view returns (uint256); function getFundingFee(address _account, address _collateralToken, address _indexToken, bool _isLong, uint256 _size, uint256 _entryFundingRate) external view returns (uint256); function getBuyUsdgFeeBasisPoints(address _token, uint256 _usdgAmount) external view returns (uint256); function getSellUsdgFeeBasisPoints(address _token, uint256 _usdgAmount) external view returns (uint256); function getSwapFeeBasisPoints(address _tokenIn, address _tokenOut, uint256 _usdgAmount) external view returns (uint256); function getFeeBasisPoints(address _token, uint256 _usdgDelta, uint256 _feeBasisPoints, uint256 _taxBasisPoints, bool _increment) external view returns (uint256); }
{ "optimizer": { "enabled": true, "runs": 10 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakeGlp","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakeGmx","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"UnstakeGlp","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"UnstakeGmx","type":"event"},{"inputs":[],"name":"BASIS_POINTS_DIVISOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"}],"name":"acceptTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_accounts","type":"address[]"}],"name":"batchCompoundForAccounts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_accounts","type":"address[]"}],"name":"batchRestakeForAccounts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_accounts","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"batchStakeGmxForAccounts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bnGmx","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bonusGmxTracker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimEsGmx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"compound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"esGmx","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"extendedGmxTracker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"externalHandler","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeGlpTracker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeGmxTracker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"glp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"glpManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"glpVester","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gmx","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gmxVester","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"govToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_shouldClaimGmx","type":"bool"},{"internalType":"bool","name":"_shouldStakeGmx","type":"bool"},{"internalType":"bool","name":"_shouldClaimEsGmx","type":"bool"},{"internalType":"bool","name":"_shouldStakeEsGmx","type":"bool"},{"internalType":"bool","name":"_shouldStakeMultiplierPoints","type":"bool"},{"internalType":"bool","name":"_shouldClaimWeth","type":"bool"},{"internalType":"bool","name":"_shouldConvertWethToEth","type":"bool"}],"name":"handleRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gmxReceiver","type":"address"},{"internalType":"bool","name":"_shouldClaimGmx","type":"bool"},{"internalType":"bool","name":"_shouldStakeGmx","type":"bool"},{"internalType":"bool","name":"_shouldClaimEsGmx","type":"bool"},{"internalType":"bool","name":"_shouldStakeEsGmx","type":"bool"},{"internalType":"bool","name":"_shouldStakeMultiplierPoints","type":"bool"},{"internalType":"bool","name":"_shouldClaimWeth","type":"bool"},{"internalType":"bool","name":"_shouldConvertWethToEth","type":"bool"}],"name":"handleRewardsV2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"inRestakingMode","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"inStrictTransferMode","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"weth","type":"address"},{"internalType":"address","name":"gmx","type":"address"},{"internalType":"address","name":"esGmx","type":"address"},{"internalType":"address","name":"bnGmx","type":"address"},{"internalType":"address","name":"glp","type":"address"},{"internalType":"address","name":"stakedGmxTracker","type":"address"},{"internalType":"address","name":"bonusGmxTracker","type":"address"},{"internalType":"address","name":"extendedGmxTracker","type":"address"},{"internalType":"address","name":"feeGmxTracker","type":"address"},{"internalType":"address","name":"feeGlpTracker","type":"address"},{"internalType":"address","name":"stakedGlpTracker","type":"address"},{"internalType":"address","name":"glpManager","type":"address"},{"internalType":"address","name":"gmxVester","type":"address"},{"internalType":"address","name":"glpVester","type":"address"},{"internalType":"address","name":"externalHandler","type":"address"},{"internalType":"address","name":"govToken","type":"address"}],"internalType":"struct RewardRouterV2.InitializeParams","name":"_initializeParams","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"externalCallTargets","type":"address[]"},{"internalType":"bytes[]","name":"externalCallDataList","type":"bytes[]"},{"internalType":"address[]","name":"refundTokens","type":"address[]"},{"internalType":"address[]","name":"refundReceivers","type":"address[]"}],"name":"makeExternalCalls","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxBoostBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_minUsdg","type":"uint256"},{"internalType":"uint256","name":"_minGlp","type":"uint256"}],"name":"mintAndStakeGlp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minUsdg","type":"uint256"},{"internalType":"uint256","name":"_minGlp","type":"uint256"}],"name":"mintAndStakeGlpETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pendingReceivers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gov","type":"address"}],"name":"setGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_govToken","type":"address"}],"name":"setGovToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_inRestakingMode","type":"bool"}],"name":"setInRestakingMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_inStrictTransferMode","type":"bool"}],"name":"setInStrictTransferMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxBoostBasisPoints","type":"uint256"}],"name":"setMaxBoostBasisPoints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum RewardRouterV2.VotingPowerType","name":"_votingPowerType","type":"uint8"}],"name":"setVotingPowerType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"}],"name":"signalTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stakeEsGmx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stakeGmx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakedGlpTracker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakedGmxTracker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"uint256","name":"_glpAmount","type":"uint256"},{"internalType":"uint256","name":"_minOut","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"unstakeAndRedeemGlp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_glpAmount","type":"uint256"},{"internalType":"uint256","name":"_minOut","type":"uint256"},{"internalType":"address payable","name":"_receiver","type":"address"}],"name":"unstakeAndRedeemGlpETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unstakeEsGmx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unstakeGmx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"votingPowerType","outputs":[{"internalType":"enum RewardRouterV2.VotingPowerType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b506001600081905580546001600160a01b03191633179055615fc080620000386000396000f3fe60806040526004361061025e5760003560e01c806301e336671461029d57806305268cff146102bd578063078580d2146102e857806308694e63146103085780630ce4018a1461032a5780630f3aa5541461033f578063126082cf1461036c57806312d43a51146103815780631af276a6146103965780631cf631bb146103b65780631fcd60e5146103d6578063204b4c6f146103eb5780632e944bd61461040057806330b70002146104155780633172fc231461043557806331e67c711461045557806335c1b1881461046a578063364e23111461048a5780633671df25146104aa578063392e53cd146104bf5780633fc8cef3146104e157806341d315b4146104f657806344d3a2011461050b5780634e71d92d1461052b57806351c3e3b4146105405780635261aef31461055557806353a8aa03146105755780635fe3945f1461058857806364f644671461059d578063655603a4146105bd57806365f8f4d0146105dd5780636a192a78146105fd5780636d6440f014610612578063743655ab1461063257806378a207ee1461064757806382b6aecc1461065c578063a86ea69514610671578063abb5e5e214610691578063ac9650d8146106b1578063af394d00146106de578063ba2db4f5146106f3578063cfad57a214610713578063d294f09314610733578063d59922b014610748578063dddfa31414610768578063e102f5641461077d578063e1b9db8914610792578063e1c363b7146107b2578063ef8c5994146107c7578063ef9aacfd146107e7578063f3daeacc14610807578063f69e204614610827578063fa6db1bc1461083c57610298565b36610298576002546001600160a01b031633146102965760405162461bcd60e51b815260040161028d906156ca565b60405180910390fd5b005b600080fd5b3480156102a957600080fd5b506102966102b8366004614d9a565b610851565b3480156102c957600080fd5b506102d2610894565b6040516102df9190615465565b60405180910390f35b3480156102f457600080fd5b506102966103033660046152fb565b6108a8565b34801561031457600080fd5b5061031d6108fb565b6040516102df91906155f9565b34801561033657600080fd5b506102d261090b565b34801561034b57600080fd5b5061035f61035a366004614e82565b61091a565b6040516102df9190615ead565b34801561037857600080fd5b5061035f610989565b34801561038d57600080fd5b506102d261098f565b3480156103a257600080fd5b506102966103b1366004614f05565b61099e565b3480156103c257600080fd5b506102966103d1366004614dda565b610a29565b3480156103e257600080fd5b506102d2610bc9565b3480156103f757600080fd5b506102d2610bd8565b34801561040c57600080fd5b506102d2610be7565b34801561042157600080fd5b50610296610430366004615100565b610bf6565b34801561044157600080fd5b50610296610450366004614fde565b610d64565b34801561046157600080fd5b506102d2610e13565b34801561047657600080fd5b506102966104853660046152fb565b610e22565b34801561049657600080fd5b5061035f6104a5366004614ecb565b610e51565b3480156104b657600080fd5b506102d2610eb4565b3480156104cb57600080fd5b506104d4610ec3565b6040516102df91906155ee565b3480156104ed57600080fd5b506102d2610ed3565b34801561050257600080fd5b506102d2610ee2565b34801561051757600080fd5b50610296610526366004614f05565b610ef1565b34801561053757600080fd5b50610296610f73565b34801561054c57600080fd5b506102d2610fe3565b34801561056157600080fd5b506102966105703660046151b4565b610ff2565b61035f61058336600461532b565b6111c0565b34801561059457600080fd5b5061029661134b565b3480156105a957600080fd5b506102966105b83660046152fb565b611391565b3480156105c957600080fd5b506102966105d8366004614d7e565b6113dc565b3480156105e957600080fd5b506102966105f83660046150c8565b611a20565b34801561060957600080fd5b506102d2611a5d565b34801561061e57600080fd5b5061029661062d3660046150c8565b611a6c565b34801561063e57600080fd5b506104d4611ab4565b34801561065357600080fd5b506102d2611abd565b34801561066857600080fd5b506104d4611acc565b34801561067d57600080fd5b5061029661068c366004614d7e565b611adc565b34801561069d57600080fd5b5061035f6106ac36600461534c565b611b2e565b3480156106bd57600080fd5b506106d16106cc366004615096565b611c1c565b6040516102df91906155db565b3480156106ea57600080fd5b506102d2611d31565b3480156106ff57600080fd5b5061029661070e366004615195565b611d40565b34801561071f57600080fd5b5061029661072e366004614d7e565b611d91565b34801561073f57600080fd5b50610296611ddd565b34801561075457600080fd5b50610296610763366004614f37565b611e0f565b34801561077457600080fd5b5061035f611e9b565b34801561078957600080fd5b506102d2611ea1565b34801561079e57600080fd5b506102d26107ad366004614d7e565b611eb0565b3480156107be57600080fd5b506102d2611ecb565b3480156107d357600080fd5b506102966107e23660046152fb565b611eda565b3480156107f357600080fd5b50610296610802366004614d7e565b611f1c565b34801561081357600080fd5b506102966108223660046152fb565b6120c3565b34801561083357600080fd5b50610296612105565b34801561084857600080fd5b506102d261213d565b6001546001600160a01b0316331461087b5760405162461bcd60e51b815260040161028d90615a73565b61088f6001600160a01b038416838361214c565b505050565b60125461010090046001600160a01b031681565b600260005414156108cb5760405162461bcd60e51b815260040161028d90615e31565b60026000556108d9336121a2565b6003546108f39033906001600160a01b031683600161233e565b506001600055565b601254600160a81b900460ff1681565b6007546001600160a01b031681565b60006002600054141561093f5760405162461bcd60e51b815260040161028d90615e31565b600260009081556109528686868661289d565b9050600080516020615f6b8339815191523386604051610973929190615493565b60405180910390a1600160005595945050505050565b61271081565b6001546001600160a01b031681565b600260005414156109c15760405162461bcd60e51b815260040161028d90615e31565b60026000556001546001600160a01b031633146109f05760405162461bcd60e51b815260040161028d90615a73565b60005b8151811015610a2057610a18828281518110610a0b57fe5b6020026020010151612a2e565b6001016109f3565b50506001600055565b60026000541415610a4c5760405162461bcd60e51b815260040161028d90615e31565b6002600090815533908815610a86576000610a67838c612aba565b90506000610a75848d612be7565b9050610a818282612c78565b925050505b878015610a935750600081115b15610ae357816001600160a01b03168a6001600160a01b031614610ac95760405162461bcd60e51b815260040161028d90615aa2565b600354610ae390839081906001600160a01b031684612ca4565b60008715610b0c57600754600b54610b09916001600160a01b0390811691168580612ea3565b90505b868015610b195750600081115b15610b3857600454610b3890849081906001600160a01b031684612ca4565b8515610b5057610b47836121a2565b610b5083612fc4565b8415610bae578315610b8e57600a54600c54600091610b7d916001600160a01b0391821691168630612ea3565b9050610b8881613408565b50610bae565b600a54600c54610bac916001600160a01b0390811691168580612ea3565b505b610bb783613477565b50506001600055505050505050505050565b6008546001600160a01b031681565b6009546001600160a01b031681565b6010546001600160a01b031681565b60026000541415610c195760405162461bcd60e51b815260040161028d90615e31565b6002600090815533908815610c53576000610c348384612aba565b90506000610c428485612be7565b9050610c4e8282612c78565b925050505b878015610c605750600081115b15610c7f57600354610c7f90839081906001600160a01b031684612ca4565b60008715610ca857600754600b54610ca5916001600160a01b0390811691168580612ea3565b90505b868015610cb55750600081115b15610cd457600454610cd490849081906001600160a01b031684612ca4565b8515610cec57610ce3836121a2565b610cec83612fc4565b8415610d4a578315610d2a57600a54600c54600091610d19916001600160a01b0391821691168630612ea3565b9050610d2481613408565b50610d4a565b600a54600c54610d48916001600160a01b0390811691168580612ea3565b505b610d5383613477565b505060016000555050505050505050565b60026000541415610d875760405162461bcd60e51b815260040161028d90615e31565b60026000556001546001600160a01b03163314610db65760405162461bcd60e51b815260040161028d90615a73565b6003546001600160a01b031660005b8351811015610e0857610e0033858381518110610dde57fe5b602002602001015184868581518110610df357fe5b6020026020010151612ca4565b600101610dc5565b505060016000555050565b6003546001600160a01b031681565b6001546001600160a01b03163314610e4c5760405162461bcd60e51b815260040161028d90615a73565b601155565b600060026000541415610e765760405162461bcd60e51b815260040161028d90615e31565b6002600055610e84846135b8565b6000610e9333878787876135d8565b9050600080516020615f4b8339815191523382604051610973929190615493565b600f546001600160a01b031681565b600154600160a01b900460ff1681565b6002546001600160a01b031681565b600e546001600160a01b031681565b60026000541415610f145760405162461bcd60e51b815260040161028d90615e31565b60026000556001546001600160a01b03163314610f435760405162461bcd60e51b815260040161028d90615a73565b60005b8151811015610a2057610f6b828281518110610f5e57fe5b60200260200101516121a2565b600101610f46565b60026000541415610f965760405162461bcd60e51b815260040161028d90615e31565b6002600055600754600b54610fb9916001600160a01b0390811691163380612ea3565b50610fc43333612be7565b50600a54600c546108f3916001600160a01b0390811691163380612ea3565b600a546001600160a01b031681565b6001546001600160a01b0316331461101c5760405162461bcd60e51b815260040161028d90615a73565b600154600160a01b900460ff16156110465760405162461bcd60e51b815260040161028d906159b3565b60018054600160a01b60ff60a01b199091161790558051600280546001600160a01b03199081166001600160a01b0393841617909155602083015160038054831691841691909117905560408301516004805483169184169190911790556060830151600580548316918416919091179055608083015160068054831691841691909117905560a083015160078054831691841691909117905560c083015160088054831691841691909117905560e083015160098054831691841691909117905561010080840151600a80548416918516919091179055610120840151600c80548416918516919091179055610140840151600b80548416918516919091179055610160840151600d80548416918516919091179055610180840151600e805484169185169190911790556101a0840151600f805484169185169190911790556101c084015160108054909316908416179091556101e09092015160128054610100600160a81b03191691909216909202919091179055565b6000600260005414156111e55760405162461bcd60e51b815260040161028d90615e31565b6002600055346112075760405162461bcd60e51b815260040161028d90615e06565b600260009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561125757600080fd5b505af115801561126b573d6000803e3d6000fd5b5050600254600d5460405163095ea7b360e01b81526001600160a01b03928316955063095ea7b394506112a693509116903490600401615493565b602060405180830381600087803b1580156112c057600080fd5b505af11580156112d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f891906150e4565b506002546000906113169030906001600160a01b03163487876135d8565b9050600080516020615f4b8339815191523382604051611337929190615493565b60405180910390a160016000559392505050565b6002600054141561136e5760405162461bcd60e51b815260040161028d90615e31565b6002600055600754600b546108f3916001600160a01b0390811691163380612ea3565b600260005414156113b45760405162461bcd60e51b815260040161028d90615e31565b60026000556113c2336121a2565b6004546108f39033906001600160a01b031683600161233e565b600260005414156113ff5760405162461bcd60e51b815260040161028d90615e31565b600260005561140d81613751565b6001600160a01b0381811660009081526013602052604090205433911681146114485760405162461bcd60e51b815260040161028d9061584c565b6001600160a01b038216600090815260136020526040902080546001600160a01b031916905561147781613877565b61148082612a2e565b600754600354604051637aeceb1f60e11b81526000926001600160a01b039081169263f5d9d63e926114b89288921690600401615479565b60206040518083038186803b1580156114d057600080fd5b505afa1580156114e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115089190615313565b905080156115445760035461152a9084906001600160a01b031683600061233e565b60035461154490849084906001600160a01b031684612ca4565b60075460048054604051637aeceb1f60e11b81526000936001600160a01b039081169363f5d9d63e9361157d938a939091169101615479565b60206040518083038186803b15801561159557600080fd5b505afa1580156115a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115cd9190615313565b90508015611609576004546115ef9085906001600160a01b031683600061233e565b60045461160990859085906001600160a01b031684612ca4565b600954600554604051637aeceb1f60e11b81526000926001600160a01b039081169263f5d9d63e92611641928a921690600401615479565b60206040518083038186803b15801561165957600080fd5b505afa15801561166d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116919190615313565b600a546009546005549293506116bc926001600160a01b039283169291821691899189911686614381565b600480546040516370a0823160e01b81526000926001600160a01b03909216916370a08231916116ee918a9101615465565b60206040518083038186803b15801561170657600080fd5b505afa15801561171a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173e9190615313565b905080156117cd57600480546040516323b872dd60e01b81526001600160a01b03909116916323b872dd91611779918a918a9187910161550f565b602060405180830381600087803b15801561179357600080fd5b505af11580156117a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117cb91906150e4565b505b6005546040516370a0823160e01b81526000916001600160a01b0316906370a08231906117fe908a90600401615465565b60206040518083038186803b15801561181657600080fd5b505afa15801561182a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184e9190615313565b905080156118845760055461186d906001600160a01b031688836144ed565b600554611884906001600160a01b03168783614552565b600c54600654604051637aeceb1f60e11b81526000926001600160a01b039081169263f5d9d63e926118bc928d921690600401615479565b60206040518083038186803b1580156118d457600080fd5b505afa1580156118e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061190c9190615313565b600b54600c54600654929350611937926001600160a01b0392831692918216918c918c911686614381565b600e54604051630f713c2360e41b81526001600160a01b039091169063f713c23090611969908b908b90600401615479565b600060405180830381600087803b15801561198357600080fd5b505af1158015611997573d6000803e3d6000fd5b5050600f54604051630f713c2360e41b81526001600160a01b03909116925063f713c23091506119cd908b908b90600401615479565b600060405180830381600087803b1580156119e757600080fd5b505af11580156119fb573d6000803e3d6000fd5b50505050611a0888613477565b611a1187613477565b50506001600055505050505050565b6001546001600160a01b03163314611a4a5760405162461bcd60e51b815260040161028d90615a73565b6012805460ff1916911515919091179055565b6004546001600160a01b031681565b6001546001600160a01b03163314611a965760405162461bcd60e51b815260040161028d90615a73565b60128054911515600160b01b0260ff60b01b19909216919091179055565b60125460ff1681565b6006546001600160a01b031681565b601254600160b01b900460ff1681565b6001546001600160a01b03163314611b065760405162461bcd60e51b815260040161028d90615a73565b601280546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600060026000541415611b535760405162461bcd60e51b815260040161028d90615e31565b600260008181559054611b71906001600160a01b031686863061289d565b600254604051632e1a7d4d60e01b81529192506001600160a01b031690632e1a7d4d90611ba2908490600401615ead565b600060405180830381600087803b158015611bbc57600080fd5b505af1158015611bd0573d6000803e3d6000fd5b50611be8925050506001600160a01b03841682614580565b600080516020615f6b8339815191523386604051611c07929190615493565b60405180910390a16001600055949350505050565b606081516001600160401b0381118015611c3557600080fd5b50604051908082528060200260200182016040528015611c6957816020015b6060815260200190600190039081611c545790505b50905060005b8251811015611d2b5760006060306001600160a01b0316858481518110611c9257fe5b6020026020010151604051611ca79190615446565b600060405180830381855af49150503d8060008114611ce2576040519150601f19603f3d011682016040523d82523d6000602084013e611ce7565b606091505b509150915081611d095760405162461bcd60e51b815260040161028d90615beb565b80848481518110611d1657fe5b60209081029190910101525050600101611c6f565b50919050565b600b546001600160a01b031681565b6001546001600160a01b03163314611d6a5760405162461bcd60e51b815260040161028d90615a73565b6012805482919060ff60a81b1916600160a81b836002811115611d8957fe5b021790555050565b6001546001600160a01b03163314611dbb5760405162461bcd60e51b815260040161028d90615a73565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60026000541415611e005760405162461bcd60e51b815260040161028d90615e31565b6002600055610fc43380612be7565b60026000541415611e325760405162461bcd60e51b815260040161028d90615e31565b6002600055601054604051630d59922b60e41b81526001600160a01b039091169063d59922b090611e6d90879087908790879060040161558e565b600060405180830381600087803b158015611e8757600080fd5b505af1158015611a11573d6000803e3d6000fd5b60115481565b6005546001600160a01b031681565b6013602052600090815260409020546001600160a01b031681565b600c546001600160a01b031681565b60026000541415611efd5760405162461bcd60e51b815260040161028d90615e31565b60026000556004546108f390339081906001600160a01b031684612ca4565b60026000541415611f3f5760405162461bcd60e51b815260040161028d90615e31565b6002600055611f4d33613751565b611f5681613877565b60125460ff161561208f57600a546040516310c1c10360e01b81526000916001600160a01b0316906310c1c10390611f92903390600401615465565b60206040518083038186803b158015611faa57600080fd5b505afa158015611fbe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe29190615313565b600a54604051636eb1769f60e11b81529192506000916001600160a01b039091169063dd62ed3e9061201a9033908790600401615479565b60206040518083038186803b15801561203257600080fd5b505afa158015612046573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061206a9190615313565b90508181101561208c5760405162461bcd60e51b815260040161028d906156fa565b50505b33600090815260136020526040812080546001600160a01b0319166001600160a01b03939093169290921790915560019055565b600260005414156120e65760405162461bcd60e51b815260040161028d90615e31565b60026000556003546108f390339081906001600160a01b031684612ca4565b600260005414156121285760405162461bcd60e51b815260040161028d90615e31565b600260005561213633612a2e565b6001600055565b600d546001600160a01b031681565b61088f8363a9059cbb60e01b848460405160240161216b929190615493565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261461c565b601254600160b01b900460ff166121b85761233b565b600a54600854604051637aeceb1f60e11b81526000926001600160a01b039081169263f5d9d63e926121f09287921690600401615479565b60206040518083038186803b15801561220857600080fd5b505afa15801561221c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122409190615313565b9050801561233957600e54604051635d50e72960e01b81526000916001600160a01b031690635d50e72990612279908690600401615465565b60206040518083038186803b15801561229157600080fd5b505afa1580156122a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c99190615313565b9050801561232657600e54600a546122ef916001600160a01b03918216911685846146ab565b6122f983836146d2565b61230283614813565b600e54600a54612321916001600160a01b0391821691869116846146ab565b61088f565b61233083836146d2565b61088f83614813565b505b50565b612347826135b8565b6007546040516310c1c10360e01b81526000916001600160a01b0316906310c1c10390612378908890600401615465565b60206040518083038186803b15801561239057600080fd5b505afa1580156123a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c89190615313565b600a5460095460405163098bf59d60e01b81529293506001600160a01b039182169263098bf59d92612405928a9291169088908390600401615533565b600060405180830381600087803b15801561241f57600080fd5b505af1158015612433573d6000803e3d6000fd5b505060095460085460405163098bf59d60e01b81526001600160a01b03928316945063098bf59d9350612470928a92169088908390600401615533565b600060405180830381600087803b15801561248a57600080fd5b505af115801561249e573d6000803e3d6000fd5b505060085460075460405163098bf59d60e01b81526001600160a01b03928316945063098bf59d93506124db928a92169088908390600401615533565b600060405180830381600087803b1580156124f557600080fd5b505af1158015612509573d6000803e3d6000fd5b505060075460405163098bf59d60e01b81526001600160a01b03909116925063098bf59d9150612543908890889088908390600401615533565b600060405180830381600087803b15801561255d57600080fd5b505af1158015612571573d6000803e3d6000fd5b505050508115612852576008546040516309f4173d60e11b81526001600160a01b03909116906313e82e7a906125ad9088908190600401615479565b602060405180830381600087803b1580156125c757600080fd5b505af11580156125db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125ff9190615313565b50600954600554604051637aeceb1f60e11b81526000926001600160a01b039081169263f5d9d63e92612638928b921690600401615479565b60206040518083038186803b15801561265057600080fd5b505afa158015612664573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126889190615313565b9050801561279a5760006126a6836126a08488614922565b9061495c565b600a5460095460405163098bf59d60e01b81529293506001600160a01b039182169263098bf59d926126e3928c9291169086908390600401615533565b600060405180830381600087803b1580156126fd57600080fd5b505af1158015612711573d6000803e3d6000fd5b505060095460055460405163098bf59d60e01b81526001600160a01b03928316945063098bf59d935061274e928c92169086908390600401615533565b600060405180830381600087803b15801561276857600080fd5b505af115801561277c573d6000803e3d6000fd5b505060055461279892506001600160a01b0316905088836144ed565b505b6005546040516370a0823160e01b81526000916001600160a01b0316906370a08231906127cb908a90600401615465565b60206040518083038186803b1580156127e357600080fd5b505afa1580156127f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061281b9190615313565b9050801561284f576000612833846126a08489614922565b60055490915061284d906001600160a01b031689836144ed565b505b50505b61285b85613477565b7fce8eb393006add0768cc6cefb3ca0fc4787015ce1ac86bd800e72a799931034585858560405161288e9392919061550f565b60405180910390a15050505050565b60008084116128be5760405162461bcd60e51b815260040161028d90615bbf565b600b54600c5460405163098bf59d60e01b815233926001600160a01b039081169263098bf59d926128f992869216908a908390600401615533565b600060405180830381600087803b15801561291357600080fd5b505af1158015612927573d6000803e3d6000fd5b5050600c5460065460405163098bf59d60e01b81526001600160a01b03928316945063098bf59d935061296492869216908a908390600401615533565b600060405180830381600087803b15801561297e57600080fd5b505af1158015612992573d6000803e3d6000fd5b5050600d546040516371d597ad60e01b8152600093506001600160a01b0390911691506371d597ad906129d19085908b908b908b908b9060040161555e565b602060405180830381600087803b1580156129eb57600080fd5b505af11580156129ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a239190615313565b979650505050505050565b6000612a3a8283612be7565b90508015612a5c57600354612a5c90839081906001600160a01b031684612ca4565b600754600b54600091612a7d916001600160a01b0391821691168580612ea3565b90508015612a9f57600454612a9f90849081906001600160a01b031684612ca4565b612aa8836121a2565b612ab183612fc4565b61088f83613477565b600e546040516309f4173d60e11b815260009182916001600160a01b03909116906313e82e7a90612af19087908790600401615479565b602060405180830381600087803b158015612b0b57600080fd5b505af1158015612b1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b439190615313565b600f546040516309f4173d60e11b81529192506000916001600160a01b03909116906313e82e7a90612b7b9088908890600401615479565b602060405180830381600087803b158015612b9557600080fd5b505af1158015612ba9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bcd9190615313565b90506000612bdb8383612c78565b93505050505b92915050565b6009546040516309f4173d60e11b815260009182916001600160a01b03909116906313e82e7a90612c1e9087908790600401615479565b602060405180830381600087803b158015612c3857600080fd5b505af1158015612c4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c709190615313565b949350505050565b600082820183811015612c9d5760405162461bcd60e51b815260040161028d9061572a565b9392505050565b612cad816135b8565b600754604051631e42d69b60e21b81526001600160a01b039091169063790b5a6c90612ce39087908790879087906004016154ac565b600060405180830381600087803b158015612cfd57600080fd5b505af1158015612d11573d6000803e3d6000fd5b5050600854600754604051631e42d69b60e21b81526001600160a01b03928316945063790b5a6c9350612d4f928892839291169087906004016154ac565b600060405180830381600087803b158015612d6957600080fd5b505af1158015612d7d573d6000803e3d6000fd5b5050600954600854604051631e42d69b60e21b81526001600160a01b03928316945063790b5a6c9350612dbb928892839291169087906004016154ac565b600060405180830381600087803b158015612dd557600080fd5b505af1158015612de9573d6000803e3d6000fd5b5050600a54600954604051631e42d69b60e21b81526001600160a01b03928316945063790b5a6c9350612e27928892839291169087906004016154ac565b600060405180830381600087803b158015612e4157600080fd5b505af1158015612e55573d6000803e3d6000fd5b50505050612e6283613477565b7fad0723806aa1e5a8fb826fc9f0c5b589e585a6b60dc768a1b20691c95062d2d6838383604051612e959392919061550f565b60405180910390a150505050565b600080856001600160a01b03166313e82e7a85856040518363ffffffff1660e01b8152600401612ed4929190615479565b602060405180830381600087803b158015612eee57600080fd5b505af1158015612f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f269190615313565b90506000856001600160a01b03166313e82e7a86866040518363ffffffff1660e01b8152600401612f58929190615479565b602060405180830381600087803b158015612f7257600080fd5b505af1158015612f86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612faa9190615313565b90506000612fb88383612c78565b98975050505050505050565b6008546040516309f4173d60e11b81526001600160a01b03909116906313e82e7a90612ff69084908190600401615479565b602060405180830381600087803b15801561301057600080fd5b505af1158015613024573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130489190615313565b506005546040516370a0823160e01b81526000916001600160a01b0316906370a082319061307a908590600401615465565b60206040518083038186803b15801561309257600080fd5b505afa1580156130a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130ca9190615313565b9050806130d7575061233b565b6007546040516310c1c10360e01b81526000916001600160a01b0316906310c1c10390613108908690600401615465565b60206040518083038186803b15801561312057600080fd5b505afa158015613134573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131589190615313565b905060006131776127106126a06011548561492290919063ffffffff16565b600954600554604051637aeceb1f60e11b81529293506000926001600160a01b039283169263f5d9d63e926131b4928a9290911690600401615479565b60206040518083038186803b1580156131cc57600080fd5b505afa1580156131e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132049190615313565b905081811415613217575050505061233b565b8181111561330f57600061322b828461499b565b600a5460095460405163098bf59d60e01b81529293506001600160a01b039182169263098bf59d92613268928b9291169086908390600401615533565b600060405180830381600087803b15801561328257600080fd5b505af1158015613296573d6000803e3d6000fd5b505060095460055460405163098bf59d60e01b81526001600160a01b03928316945063098bf59d93506132d3928b92169086908390600401615533565b600060405180830381600087803b1580156132ed57600080fd5b505af1158015613301573d6000803e3d6000fd5b50505050505050505061233b565b600061331b838361499b565b905080851115613329578094505b600954600554604051631e42d69b60e21b81526001600160a01b039283169263790b5a6c92613362928b92839216908b906004016154ac565b600060405180830381600087803b15801561337c57600080fd5b505af1158015613390573d6000803e3d6000fd5b5050600a54600954604051631e42d69b60e21b81526001600160a01b03928316945063790b5a6c93506133ce928b9283929116908b906004016154ac565b600060405180830381600087803b1580156133e857600080fd5b505af11580156133fc573d6000803e3d6000fd5b50505050505050505050565b600254604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d90613438908490600401615ead565b600060405180830381600087803b15801561345257600080fd5b505af1158015613466573d6000803e3d6000fd5b5061233b9250339150839050614580565b6000601254600160a81b900460ff16600281111561349157fe5b141561349c5761233b565b6001601254600160a81b900460ff1660028111156134b657fe5b141561354f576007546040516310c1c10360e01b81526000916001600160a01b0316906310c1c103906134ed908590600401615465565b60206040518083038186803b15801561350557600080fd5b505afa158015613519573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061353d9190615313565b905061354982826149dd565b5061233b565b6002601254600160a81b900460ff16600281111561356957fe5b14156135a057600a546040516310c1c10360e01b81526000916001600160a01b0316906310c1c103906134ed908590600401615465565b60405162461bcd60e51b815260040161028d90615666565b6000811161233b5760405162461bcd60e51b815260040161028d9061598a565b600d546040516317eb2a1560e01b8152600091339183916001600160a01b0316906317eb2a1590613617908b9086908c908c908c908c906004016154d6565b602060405180830381600087803b15801561363157600080fd5b505af1158015613645573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136699190615313565b600c54600654604051631e42d69b60e21b81529293506001600160a01b039182169263790b5a6c926136a792879283929091169087906004016154ac565b600060405180830381600087803b1580156136c157600080fd5b505af11580156136d5573d6000803e3d6000fd5b5050600b54600c54604051631e42d69b60e21b81526001600160a01b03928316945063790b5a6c9350613713928792839291169087906004016154ac565b600060405180830381600087803b15801561372d57600080fd5b505af1158015613741573d6000803e3d6000fd5b50929a9950505050505050505050565b600e546040516370a0823160e01b81526001600160a01b03909116906370a0823190613781908490600401615465565b60206040518083038186803b15801561379957600080fd5b505afa1580156137ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137d19190615313565b15801561385b5750600f546040516370a0823160e01b81526001600160a01b03909116906370a0823190613809908490600401615465565b60206040518083038186803b15801561382157600080fd5b505afa158015613835573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138599190615313565b155b61233b5760405162461bcd60e51b815260040161028d90615c53565b60075460405163a318021760e01b81526001600160a01b039091169063a3180217906138a7908490600401615465565b60206040518083038186803b1580156138bf57600080fd5b505afa1580156138d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f79190615313565b156139145760405162461bcd60e51b815260040161028d906157a9565b600754604051633792def360e01b81526001600160a01b0390911690633792def390613944908490600401615465565b60206040518083038186803b15801561395c57600080fd5b505afa158015613970573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139949190615313565b156139b15760405162461bcd60e51b815260040161028d90615620565b60085460405163a318021760e01b81526001600160a01b039091169063a3180217906139e1908490600401615465565b60206040518083038186803b1580156139f957600080fd5b505afa158015613a0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a319190615313565b15613a4e5760405162461bcd60e51b815260040161028d90615d78565b600854604051633792def360e01b81526001600160a01b0390911690633792def390613a7e908490600401615465565b60206040518083038186803b158015613a9657600080fd5b505afa158015613aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ace9190615313565b15613aeb5760405162461bcd60e51b815260040161028d90615e68565b60095460405163a318021760e01b81526001600160a01b039091169063a318021790613b1b908490600401615465565b60206040518083038186803b158015613b3357600080fd5b505afa158015613b47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b6b9190615313565b15613b885760405162461bcd60e51b815260040161028d906158f9565b600954604051633792def360e01b81526001600160a01b0390911690633792def390613bb8908490600401615465565b60206040518083038186803b158015613bd057600080fd5b505afa158015613be4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c089190615313565b15613c255760405162461bcd60e51b815260040161028d90615b2e565b600a5460405163a318021760e01b81526001600160a01b039091169063a318021790613c55908490600401615465565b60206040518083038186803b158015613c6d57600080fd5b505afa158015613c81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ca59190615313565b15613cc25760405162461bcd60e51b815260040161028d90615dc0565b600a54604051633792def360e01b81526001600160a01b0390911690633792def390613cf2908490600401615465565b60206040518083038186803b158015613d0a57600080fd5b505afa158015613d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d429190615313565b15613d5f5760405162461bcd60e51b815260040161028d90615c10565b600e54604051631ccdc0d760e21b81526001600160a01b0390911690637337035c90613d8f908490600401615465565b60206040518083038186803b158015613da757600080fd5b505afa158015613dbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ddf9190615313565b15613dfc5760405162461bcd60e51b815260040161028d90615a26565b600e54604051635b8de71560e11b81526001600160a01b039091169063b71bce2a90613e2c908490600401615465565b60206040518083038186803b158015613e4457600080fd5b505afa158015613e58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e7c9190615313565b15613e995760405162461bcd60e51b815260040161028d9061575f565b600b5460405163a318021760e01b81526001600160a01b039091169063a318021790613ec9908490600401615465565b60206040518083038186803b158015613ee157600080fd5b505afa158015613ef5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f199190615313565b15613f365760405162461bcd60e51b815260040161028d90615b76565b600b54604051633792def360e01b81526001600160a01b0390911690633792def390613f66908490600401615465565b60206040518083038186803b158015613f7e57600080fd5b505afa158015613f92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fb69190615313565b15613fd35760405162461bcd60e51b815260040161028d90615944565b600c5460405163a318021760e01b81526001600160a01b039091169063a318021790614003908490600401615465565b60206040518083038186803b15801561401b57600080fd5b505afa15801561402f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140539190615313565b156140705760405162461bcd60e51b815260040161028d906159e0565b600c54604051633792def360e01b81526001600160a01b0390911690633792def3906140a0908490600401615465565b60206040518083038186803b1580156140b857600080fd5b505afa1580156140cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140f09190615313565b1561410d5760405162461bcd60e51b815260040161028d90615c85565b600f54604051631ccdc0d760e21b81526001600160a01b0390911690637337035c9061413d908490600401615465565b60206040518083038186803b15801561415557600080fd5b505afa158015614169573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061418d9190615313565b156141aa5760405162461bcd60e51b815260040161028d90615a26565b600f54604051635b8de71560e11b81526001600160a01b039091169063b71bce2a906141da908490600401615465565b60206040518083038186803b1580156141f257600080fd5b505afa158015614206573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061422a9190615313565b156142475760405162461bcd60e51b815260040161028d9061575f565b600e546040516370a0823160e01b81526001600160a01b03909116906370a0823190614277908490600401615465565b60206040518083038186803b15801561428f57600080fd5b505afa1580156142a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c79190615313565b156142e45760405162461bcd60e51b815260040161028d90615cff565b600f546040516370a0823160e01b81526001600160a01b03909116906370a0823190614314908490600401615465565b60206040518083038186803b15801561432c57600080fd5b505afa158015614340573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143649190615313565b1561233b5760405162461bcd60e51b815260040161028d9061569b565b80156144e55760405163098bf59d60e01b81526001600160a01b0387169063098bf59d906143b9908790899086908390600401615533565b600060405180830381600087803b1580156143d357600080fd5b505af11580156143e7573d6000803e3d6000fd5b505060405163098bf59d60e01b81526001600160a01b038816925063098bf59d915061441d908790869086908390600401615533565b600060405180830381600087803b15801561443757600080fd5b505af115801561444b573d6000803e3d6000fd5b5050604051631e42d69b60e21b81526001600160a01b038816925063790b5a6c91506144819087908790879087906004016154ac565b600060405180830381600087803b15801561449b57600080fd5b505af11580156144af573d6000803e3d6000fd5b5050604051631e42d69b60e21b81526001600160a01b038916925063790b5a6c91506133ce90869081908a9087906004016154ac565b505050505050565b604051632770a7eb60e21b81526001600160a01b03841690639dc29fac9061451b9085908590600401615493565b600060405180830381600087803b15801561453557600080fd5b505af1158015614549573d6000803e3d6000fd5b50505050505050565b6040516340c10f1960e01b81526001600160a01b038416906340c10f199061451b9085908590600401615493565b804710156145a05760405162461bcd60e51b815260040161028d9061587c565b6000826001600160a01b0316826040516145b990615462565b60006040518083038185875af1925050503d80600081146145f6576040519150601f19603f3d011682016040523d82523d6000602084013e6145fb565b606091505b505090508061088f5760405162461bcd60e51b815260040161028d906157f2565b6060614671826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614ad89092919063ffffffff16565b80519091501561088f578080602001905181019061468f91906150e4565b61088f5760405162461bcd60e51b815260040161028d90615d2e565b6146cc846323b872dd60e01b85858560405160240161216b9392919061550f565b50505050565b600a5460085460405163098bf59d60e01b81526001600160a01b039283169263098bf59d9261470d9287929091169086908390600401615533565b600060405180830381600087803b15801561472757600080fd5b505af115801561473b573d6000803e3d6000fd5b5050600954600854604051631e42d69b60e21b81526001600160a01b03928316945063790b5a6c9350614779928792839291169087906004016154ac565b600060405180830381600087803b15801561479357600080fd5b505af11580156147a7573d6000803e3d6000fd5b5050600a54600954604051631e42d69b60e21b81526001600160a01b03928316945063790b5a6c93506147e5928792839291169087906004016154ac565b600060405180830381600087803b1580156147ff57600080fd5b505af11580156144e5573d6000803e3d6000fd5b600a54600554604051637aeceb1f60e11b81526000926001600160a01b039081169263f5d9d63e9261484b9287921690600401615479565b60206040518083038186803b15801561486357600080fd5b505afa158015614877573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061489b9190615313565b9050801561233957600a5460055460405163098bf59d60e01b81526001600160a01b039283169263098bf59d926148de9287929091169086908390600401615533565b600060405180830381600087803b1580156148f857600080fd5b505af115801561490c573d6000803e3d6000fd5b5050505061491982612fc4565b61233982613477565b60008261493157506000612be1565b8282028284828161493e57fe5b0414612c9d5760405162461bcd60e51b815260040161028d90615aed565b6000612c9d83836040518060400160405280601a815260200179536166654d6174683a206469766973696f6e206279207a65726f60301b815250614ae7565b6000612c9d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614b1e565b6012546040516370a0823160e01b815260009161010090046001600160a01b0316906370a0823190614a13908690600401615465565b60206040518083038186803b158015614a2b57600080fd5b505afa158015614a3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614a639190615313565b905081811415614a735750612339565b81811115614aad576000614a87828461499b565b601254909150614aa69061010090046001600160a01b031685836144ed565b5050612339565b6000614ab9838361499b565b6012549091506146cc9061010090046001600160a01b03168583614552565b6060612c708484600085614b4a565b60008183614b085760405162461bcd60e51b815260040161028d919061560d565b506000838581614b1457fe5b0495945050505050565b60008184841115614b425760405162461bcd60e51b815260040161028d919061560d565b505050900390565b606082471015614b6c5760405162461bcd60e51b815260040161028d906158b3565b614b7585614c00565b614b915760405162461bcd60e51b815260040161028d90615cc8565b60006060866001600160a01b03168587604051614bae9190615446565b60006040518083038185875af1925050503d8060008114614beb576040519150601f19603f3d011682016040523d82523d6000602084013e614bf0565b606091505b5091509150612a23828286614c06565b3b151590565b60608315614c15575081612c9d565b825115614c255782518084602001fd5b8160405162461bcd60e51b815260040161028d919061560d565b8035612be181615f27565b600082601f830112614c5a578081fd5b8135614c6d614c6882615edc565b615eb6565b818152915060208083019084810181840286018201871015614c8e57600080fd5b60005b84811015614cb6578135614ca481615f27565b84529282019290820190600101614c91565b505050505092915050565b6000601f8381840112614cd2578182fd5b8235614ce0614c6882615edc565b818152925060208084019085810160005b84811015614d72578135880189603f820112614d0c57600080fd5b808401356001600160401b03811115614d2457600080fd5b614d35818901601f19168601615eb6565b81815260408c81848601011115614d4b57600080fd5b82818501888401375060009181018601919091528552509282019290820190600101614cf1565b50505050505092915050565b600060208284031215614d8f578081fd5b8135612c9d81615f27565b600080600060608486031215614dae578182fd5b8335614db981615f27565b92506020840135614dc981615f27565b929592945050506040919091013590565b600080600080600080600080610100898b031215614df6578384fd5b8835614e0181615f27565b97506020890135614e1181615f3c565b96506040890135614e2181615f3c565b95506060890135614e3181615f3c565b94506080890135614e4181615f3c565b935060a0890135614e5181615f3c565b925060c0890135614e6181615f3c565b915060e0890135614e7181615f3c565b809150509295985092959890939650565b60008060008060808587031215614e97578384fd5b8435614ea281615f27565b935060208501359250604085013591506060850135614ec081615f27565b939692955090935050565b60008060008060808587031215614ee0578384fd5b8435614eeb81615f27565b966020860135965060408601359560600135945092505050565b600060208284031215614f16578081fd5b81356001600160401b03811115614f2b578182fd5b612c7084828501614c4a565b60008060008060808587031215614f4c578182fd5b84356001600160401b0380821115614f62578384fd5b614f6e88838901614c4a565b95506020870135915080821115614f83578384fd5b614f8f88838901614cc1565b94506040870135915080821115614fa4578384fd5b614fb088838901614c4a565b93506060870135915080821115614fc5578283fd5b50614fd287828801614c4a565b91505092959194509250565b60008060408385031215614ff0578182fd5b82356001600160401b0380821115615006578384fd5b61501286838701614c4a565b9350602091508185013581811115615028578384fd5b85019050601f8101861361503a578283fd5b8035615048614c6882615edc565b81815283810190838501858402850186018a1015615064578687fd5b8694505b83851015615086578035835260019490940193918501918501615068565b5080955050505050509250929050565b6000602082840312156150a7578081fd5b81356001600160401b038111156150bc578182fd5b612c7084828501614cc1565b6000602082840312156150d9578081fd5b8135612c9d81615f3c565b6000602082840312156150f5578081fd5b8151612c9d81615f3c565b600080600080600080600060e0888a03121561511a578081fd5b873561512581615f3c565b9650602088013561513581615f3c565b9550604088013561514581615f3c565b9450606088013561515581615f3c565b9350608088013561516581615f3c565b925060a088013561517581615f3c565b915060c088013561518581615f3c565b8091505092959891949750929550565b6000602082840312156151a6578081fd5b813560038110612c9d578182fd5b60006102008083850312156151c7578182fd5b6151d081615eb6565b90506151dc8484614c3f565b81526151eb8460208501614c3f565b60208201526151fd8460408501614c3f565b604082015261520f8460608501614c3f565b60608201526152218460808501614c3f565b60808201526152338460a08501614c3f565b60a08201526152458460c08501614c3f565b60c08201526152578460e08501614c3f565b60e082015261010061526b85828601614c3f565b9082015261012061527e85858301614c3f565b9082015261014061529185858301614c3f565b908201526101606152a485858301614c3f565b908201526101806152b785858301614c3f565b908201526101a06152ca85858301614c3f565b908201526101c06152dd85858301614c3f565b908201526101e06152f085858301614c3f565b908201529392505050565b60006020828403121561530c578081fd5b5035919050565b600060208284031215615324578081fd5b5051919050565b6000806040838503121561533d578182fd5b50508035926020909101359150565b600080600060608486031215615360578081fd5b8335925060208401359150604084013561537981615f27565b809150509250925092565b6000815180845260208085019450808401835b838110156153bc5781516001600160a01b031687529582019590820190600101615397565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b8581101561540d5782840389526153fb84835161541a565b988501989350908401906001016153e3565b5091979650505050505050565b60008151808452615432816020860160208601615efb565b601f01601f19169290920160200192915050565b60008251615458818460208701615efb565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925260a081019190915260c00190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03948516815292841660208401526040830191909152909116606082015260800190565b6001600160a01b039586168152938516602085015260408401929092526060830152909116608082015260a00190565b6000608082526155a16080830187615384565b82810360208401526155b381876153c7565b905082810360408401526155c78186615384565b90508281036060840152612a238185615384565b600060208252612c9d60208301846153c7565b901515815260200190565b602081016003831061560757fe5b91905290565b600060208252612c9d602083018461541a565b60208082526026908201527f7374616b6564476d78547261636b65722e63756d756c6174697665526577617260408201526506473203e20360d41b606082015260800190565b6020808252601b908201527a756e737570706f7274656420766f74696e67506f7765725479706560281b604082015260600190565b6020808252601590820152740676c705665737465722e62616c616e6365203e203605c1b604082015260600190565b6020808252601690820152752937baba32b91d1034b73b30b634b21039b2b73232b960511b604082015260600190565b602080825260169082015275696e73756666696369656e7420616c6c6f77616e636560501b604082015260600190565b6020808252601b908201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604082015260600190565b6020808252602a908201527f676d785665737465722e7472616e7366657272656443756d756c6174697665526040820152690657761726473203e20360b41b606082015260800190565b60208082526029908201527f7374616b6564476d78547261636b65722e617665726167655374616b6564416d60408201526806f756e7473203e20360bc1b606082015260800190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c20726040820152791958da5c1a595b9d081b585e481a185d99481c995d995c9d195960321b606082015260800190565b6020808252601690820152751d1c985b9cd9995c881b9bdd081cda59db985b1b195960521b604082015260600190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252602b908201527f657874656e646564476d78547261636b65722e617665726167655374616b656460408201526a0416d6f756e7473203e20360ac1b606082015260800190565b60208082526026908201527f7374616b6564476c70547261636b65722e63756d756c6174697665526577617260408201526506473203e20360d41b606082015260800190565b6020808252600f908201526e1a5b9d985b1a590817d85b5bdd5b9d608a1b604082015260600190565b602080825260139082015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604082015260600190565b60208082526026908201527f666565476c70547261636b65722e617665726167655374616b6564416d6f756e60408201526507473203e20360d41b606082015260800190565b6020808252602d908201527f676d785665737465722e7472616e73666572726564417665726167655374616b60408201526c06564416d6f756e7473203e203609c1b606082015260800190565b60208082526015908201527423b7bb32b93730b136329d103337b93134b23232b760591b604082015260600190565b6020808252602b908201527f63616e6e6f74207374616b6520474d58206966205f676d78526563656976657260408201526a08084f481858d8dbdd5b9d60aa1b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b60208082526028908201527f657874656e646564476d78547261636b65722e63756d756c6174697665526577604082015267061726473203e20360c41b606082015260800190565b60208082526029908201527f7374616b6564476c70547261636b65722e617665726167655374616b6564416d60408201526806f756e7473203e20360bc1b606082015260800190565b6020808252601290820152711a5b9d985b1a590817d9db1c105b5bdd5b9d60721b604082015260600190565b6020808252600b908201526a18d85b1b0819985a5b195960aa1b604082015260600190565b60208082526023908201527f666565476d78547261636b65722e63756d756c6174697665526577617264732060408201526203e20360ec1b606082015260800190565b60208082526018908201527773656e646572206861732076657374656420746f6b656e7360401b604082015260600190565b60208082526023908201527f666565476c70547261636b65722e63756d756c6174697665526577617264732060408201526203e20360ec1b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252601590820152740676d785665737465722e62616c616e6365203e203605c1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526028908201527f626f6e7573476d78547261636b65722e617665726167655374616b6564416d6f6040820152670756e7473203e20360c41b606082015260800190565b60208082526026908201527f666565476d78547261636b65722e617665726167655374616b6564416d6f756e60408201526507473203e20360d41b606082015260800190565b602080825260119082015270696e76616c6964206d73672e76616c756560781b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526025908201527f626f6e7573476d78547261636b65722e63756d756c6174697665526577617264604082015264073203e20360dc1b606082015260800190565b90815260200190565b6040518181016001600160401b0381118282101715615ed457600080fd5b604052919050565b60006001600160401b03821115615ef1578081fd5b5060209081020190565b60005b83811015615f16578181015183820152602001615efe565b838111156146cc5750506000910152565b6001600160a01b038116811461233b57600080fd5b801515811461233b57600080fdfea4725d47fa458d9222498e4d63f34527cf7318c1506f89d9092b35fdbcb64f3a1cb6202519b6b6c72ba5ed11e2c3f53af3cea010f96bfc705584e53e75cf034ca2646970667358221220c5871ff962531b74ae54b48c23eda76453b365ab92e26fad377199b8dd15ec8364736f6c634300060c0033
Deployed Bytecode
0x60806040526004361061025e5760003560e01c806301e336671461029d57806305268cff146102bd578063078580d2146102e857806308694e63146103085780630ce4018a1461032a5780630f3aa5541461033f578063126082cf1461036c57806312d43a51146103815780631af276a6146103965780631cf631bb146103b65780631fcd60e5146103d6578063204b4c6f146103eb5780632e944bd61461040057806330b70002146104155780633172fc231461043557806331e67c711461045557806335c1b1881461046a578063364e23111461048a5780633671df25146104aa578063392e53cd146104bf5780633fc8cef3146104e157806341d315b4146104f657806344d3a2011461050b5780634e71d92d1461052b57806351c3e3b4146105405780635261aef31461055557806353a8aa03146105755780635fe3945f1461058857806364f644671461059d578063655603a4146105bd57806365f8f4d0146105dd5780636a192a78146105fd5780636d6440f014610612578063743655ab1461063257806378a207ee1461064757806382b6aecc1461065c578063a86ea69514610671578063abb5e5e214610691578063ac9650d8146106b1578063af394d00146106de578063ba2db4f5146106f3578063cfad57a214610713578063d294f09314610733578063d59922b014610748578063dddfa31414610768578063e102f5641461077d578063e1b9db8914610792578063e1c363b7146107b2578063ef8c5994146107c7578063ef9aacfd146107e7578063f3daeacc14610807578063f69e204614610827578063fa6db1bc1461083c57610298565b36610298576002546001600160a01b031633146102965760405162461bcd60e51b815260040161028d906156ca565b60405180910390fd5b005b600080fd5b3480156102a957600080fd5b506102966102b8366004614d9a565b610851565b3480156102c957600080fd5b506102d2610894565b6040516102df9190615465565b60405180910390f35b3480156102f457600080fd5b506102966103033660046152fb565b6108a8565b34801561031457600080fd5b5061031d6108fb565b6040516102df91906155f9565b34801561033657600080fd5b506102d261090b565b34801561034b57600080fd5b5061035f61035a366004614e82565b61091a565b6040516102df9190615ead565b34801561037857600080fd5b5061035f610989565b34801561038d57600080fd5b506102d261098f565b3480156103a257600080fd5b506102966103b1366004614f05565b61099e565b3480156103c257600080fd5b506102966103d1366004614dda565b610a29565b3480156103e257600080fd5b506102d2610bc9565b3480156103f757600080fd5b506102d2610bd8565b34801561040c57600080fd5b506102d2610be7565b34801561042157600080fd5b50610296610430366004615100565b610bf6565b34801561044157600080fd5b50610296610450366004614fde565b610d64565b34801561046157600080fd5b506102d2610e13565b34801561047657600080fd5b506102966104853660046152fb565b610e22565b34801561049657600080fd5b5061035f6104a5366004614ecb565b610e51565b3480156104b657600080fd5b506102d2610eb4565b3480156104cb57600080fd5b506104d4610ec3565b6040516102df91906155ee565b3480156104ed57600080fd5b506102d2610ed3565b34801561050257600080fd5b506102d2610ee2565b34801561051757600080fd5b50610296610526366004614f05565b610ef1565b34801561053757600080fd5b50610296610f73565b34801561054c57600080fd5b506102d2610fe3565b34801561056157600080fd5b506102966105703660046151b4565b610ff2565b61035f61058336600461532b565b6111c0565b34801561059457600080fd5b5061029661134b565b3480156105a957600080fd5b506102966105b83660046152fb565b611391565b3480156105c957600080fd5b506102966105d8366004614d7e565b6113dc565b3480156105e957600080fd5b506102966105f83660046150c8565b611a20565b34801561060957600080fd5b506102d2611a5d565b34801561061e57600080fd5b5061029661062d3660046150c8565b611a6c565b34801561063e57600080fd5b506104d4611ab4565b34801561065357600080fd5b506102d2611abd565b34801561066857600080fd5b506104d4611acc565b34801561067d57600080fd5b5061029661068c366004614d7e565b611adc565b34801561069d57600080fd5b5061035f6106ac36600461534c565b611b2e565b3480156106bd57600080fd5b506106d16106cc366004615096565b611c1c565b6040516102df91906155db565b3480156106ea57600080fd5b506102d2611d31565b3480156106ff57600080fd5b5061029661070e366004615195565b611d40565b34801561071f57600080fd5b5061029661072e366004614d7e565b611d91565b34801561073f57600080fd5b50610296611ddd565b34801561075457600080fd5b50610296610763366004614f37565b611e0f565b34801561077457600080fd5b5061035f611e9b565b34801561078957600080fd5b506102d2611ea1565b34801561079e57600080fd5b506102d26107ad366004614d7e565b611eb0565b3480156107be57600080fd5b506102d2611ecb565b3480156107d357600080fd5b506102966107e23660046152fb565b611eda565b3480156107f357600080fd5b50610296610802366004614d7e565b611f1c565b34801561081357600080fd5b506102966108223660046152fb565b6120c3565b34801561083357600080fd5b50610296612105565b34801561084857600080fd5b506102d261213d565b6001546001600160a01b0316331461087b5760405162461bcd60e51b815260040161028d90615a73565b61088f6001600160a01b038416838361214c565b505050565b60125461010090046001600160a01b031681565b600260005414156108cb5760405162461bcd60e51b815260040161028d90615e31565b60026000556108d9336121a2565b6003546108f39033906001600160a01b031683600161233e565b506001600055565b601254600160a81b900460ff1681565b6007546001600160a01b031681565b60006002600054141561093f5760405162461bcd60e51b815260040161028d90615e31565b600260009081556109528686868661289d565b9050600080516020615f6b8339815191523386604051610973929190615493565b60405180910390a1600160005595945050505050565b61271081565b6001546001600160a01b031681565b600260005414156109c15760405162461bcd60e51b815260040161028d90615e31565b60026000556001546001600160a01b031633146109f05760405162461bcd60e51b815260040161028d90615a73565b60005b8151811015610a2057610a18828281518110610a0b57fe5b6020026020010151612a2e565b6001016109f3565b50506001600055565b60026000541415610a4c5760405162461bcd60e51b815260040161028d90615e31565b6002600090815533908815610a86576000610a67838c612aba565b90506000610a75848d612be7565b9050610a818282612c78565b925050505b878015610a935750600081115b15610ae357816001600160a01b03168a6001600160a01b031614610ac95760405162461bcd60e51b815260040161028d90615aa2565b600354610ae390839081906001600160a01b031684612ca4565b60008715610b0c57600754600b54610b09916001600160a01b0390811691168580612ea3565b90505b868015610b195750600081115b15610b3857600454610b3890849081906001600160a01b031684612ca4565b8515610b5057610b47836121a2565b610b5083612fc4565b8415610bae578315610b8e57600a54600c54600091610b7d916001600160a01b0391821691168630612ea3565b9050610b8881613408565b50610bae565b600a54600c54610bac916001600160a01b0390811691168580612ea3565b505b610bb783613477565b50506001600055505050505050505050565b6008546001600160a01b031681565b6009546001600160a01b031681565b6010546001600160a01b031681565b60026000541415610c195760405162461bcd60e51b815260040161028d90615e31565b6002600090815533908815610c53576000610c348384612aba565b90506000610c428485612be7565b9050610c4e8282612c78565b925050505b878015610c605750600081115b15610c7f57600354610c7f90839081906001600160a01b031684612ca4565b60008715610ca857600754600b54610ca5916001600160a01b0390811691168580612ea3565b90505b868015610cb55750600081115b15610cd457600454610cd490849081906001600160a01b031684612ca4565b8515610cec57610ce3836121a2565b610cec83612fc4565b8415610d4a578315610d2a57600a54600c54600091610d19916001600160a01b0391821691168630612ea3565b9050610d2481613408565b50610d4a565b600a54600c54610d48916001600160a01b0390811691168580612ea3565b505b610d5383613477565b505060016000555050505050505050565b60026000541415610d875760405162461bcd60e51b815260040161028d90615e31565b60026000556001546001600160a01b03163314610db65760405162461bcd60e51b815260040161028d90615a73565b6003546001600160a01b031660005b8351811015610e0857610e0033858381518110610dde57fe5b602002602001015184868581518110610df357fe5b6020026020010151612ca4565b600101610dc5565b505060016000555050565b6003546001600160a01b031681565b6001546001600160a01b03163314610e4c5760405162461bcd60e51b815260040161028d90615a73565b601155565b600060026000541415610e765760405162461bcd60e51b815260040161028d90615e31565b6002600055610e84846135b8565b6000610e9333878787876135d8565b9050600080516020615f4b8339815191523382604051610973929190615493565b600f546001600160a01b031681565b600154600160a01b900460ff1681565b6002546001600160a01b031681565b600e546001600160a01b031681565b60026000541415610f145760405162461bcd60e51b815260040161028d90615e31565b60026000556001546001600160a01b03163314610f435760405162461bcd60e51b815260040161028d90615a73565b60005b8151811015610a2057610f6b828281518110610f5e57fe5b60200260200101516121a2565b600101610f46565b60026000541415610f965760405162461bcd60e51b815260040161028d90615e31565b6002600055600754600b54610fb9916001600160a01b0390811691163380612ea3565b50610fc43333612be7565b50600a54600c546108f3916001600160a01b0390811691163380612ea3565b600a546001600160a01b031681565b6001546001600160a01b0316331461101c5760405162461bcd60e51b815260040161028d90615a73565b600154600160a01b900460ff16156110465760405162461bcd60e51b815260040161028d906159b3565b60018054600160a01b60ff60a01b199091161790558051600280546001600160a01b03199081166001600160a01b0393841617909155602083015160038054831691841691909117905560408301516004805483169184169190911790556060830151600580548316918416919091179055608083015160068054831691841691909117905560a083015160078054831691841691909117905560c083015160088054831691841691909117905560e083015160098054831691841691909117905561010080840151600a80548416918516919091179055610120840151600c80548416918516919091179055610140840151600b80548416918516919091179055610160840151600d80548416918516919091179055610180840151600e805484169185169190911790556101a0840151600f805484169185169190911790556101c084015160108054909316908416179091556101e09092015160128054610100600160a81b03191691909216909202919091179055565b6000600260005414156111e55760405162461bcd60e51b815260040161028d90615e31565b6002600055346112075760405162461bcd60e51b815260040161028d90615e06565b600260009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561125757600080fd5b505af115801561126b573d6000803e3d6000fd5b5050600254600d5460405163095ea7b360e01b81526001600160a01b03928316955063095ea7b394506112a693509116903490600401615493565b602060405180830381600087803b1580156112c057600080fd5b505af11580156112d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f891906150e4565b506002546000906113169030906001600160a01b03163487876135d8565b9050600080516020615f4b8339815191523382604051611337929190615493565b60405180910390a160016000559392505050565b6002600054141561136e5760405162461bcd60e51b815260040161028d90615e31565b6002600055600754600b546108f3916001600160a01b0390811691163380612ea3565b600260005414156113b45760405162461bcd60e51b815260040161028d90615e31565b60026000556113c2336121a2565b6004546108f39033906001600160a01b031683600161233e565b600260005414156113ff5760405162461bcd60e51b815260040161028d90615e31565b600260005561140d81613751565b6001600160a01b0381811660009081526013602052604090205433911681146114485760405162461bcd60e51b815260040161028d9061584c565b6001600160a01b038216600090815260136020526040902080546001600160a01b031916905561147781613877565b61148082612a2e565b600754600354604051637aeceb1f60e11b81526000926001600160a01b039081169263f5d9d63e926114b89288921690600401615479565b60206040518083038186803b1580156114d057600080fd5b505afa1580156114e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115089190615313565b905080156115445760035461152a9084906001600160a01b031683600061233e565b60035461154490849084906001600160a01b031684612ca4565b60075460048054604051637aeceb1f60e11b81526000936001600160a01b039081169363f5d9d63e9361157d938a939091169101615479565b60206040518083038186803b15801561159557600080fd5b505afa1580156115a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115cd9190615313565b90508015611609576004546115ef9085906001600160a01b031683600061233e565b60045461160990859085906001600160a01b031684612ca4565b600954600554604051637aeceb1f60e11b81526000926001600160a01b039081169263f5d9d63e92611641928a921690600401615479565b60206040518083038186803b15801561165957600080fd5b505afa15801561166d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116919190615313565b600a546009546005549293506116bc926001600160a01b039283169291821691899189911686614381565b600480546040516370a0823160e01b81526000926001600160a01b03909216916370a08231916116ee918a9101615465565b60206040518083038186803b15801561170657600080fd5b505afa15801561171a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173e9190615313565b905080156117cd57600480546040516323b872dd60e01b81526001600160a01b03909116916323b872dd91611779918a918a9187910161550f565b602060405180830381600087803b15801561179357600080fd5b505af11580156117a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117cb91906150e4565b505b6005546040516370a0823160e01b81526000916001600160a01b0316906370a08231906117fe908a90600401615465565b60206040518083038186803b15801561181657600080fd5b505afa15801561182a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184e9190615313565b905080156118845760055461186d906001600160a01b031688836144ed565b600554611884906001600160a01b03168783614552565b600c54600654604051637aeceb1f60e11b81526000926001600160a01b039081169263f5d9d63e926118bc928d921690600401615479565b60206040518083038186803b1580156118d457600080fd5b505afa1580156118e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061190c9190615313565b600b54600c54600654929350611937926001600160a01b0392831692918216918c918c911686614381565b600e54604051630f713c2360e41b81526001600160a01b039091169063f713c23090611969908b908b90600401615479565b600060405180830381600087803b15801561198357600080fd5b505af1158015611997573d6000803e3d6000fd5b5050600f54604051630f713c2360e41b81526001600160a01b03909116925063f713c23091506119cd908b908b90600401615479565b600060405180830381600087803b1580156119e757600080fd5b505af11580156119fb573d6000803e3d6000fd5b50505050611a0888613477565b611a1187613477565b50506001600055505050505050565b6001546001600160a01b03163314611a4a5760405162461bcd60e51b815260040161028d90615a73565b6012805460ff1916911515919091179055565b6004546001600160a01b031681565b6001546001600160a01b03163314611a965760405162461bcd60e51b815260040161028d90615a73565b60128054911515600160b01b0260ff60b01b19909216919091179055565b60125460ff1681565b6006546001600160a01b031681565b601254600160b01b900460ff1681565b6001546001600160a01b03163314611b065760405162461bcd60e51b815260040161028d90615a73565b601280546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600060026000541415611b535760405162461bcd60e51b815260040161028d90615e31565b600260008181559054611b71906001600160a01b031686863061289d565b600254604051632e1a7d4d60e01b81529192506001600160a01b031690632e1a7d4d90611ba2908490600401615ead565b600060405180830381600087803b158015611bbc57600080fd5b505af1158015611bd0573d6000803e3d6000fd5b50611be8925050506001600160a01b03841682614580565b600080516020615f6b8339815191523386604051611c07929190615493565b60405180910390a16001600055949350505050565b606081516001600160401b0381118015611c3557600080fd5b50604051908082528060200260200182016040528015611c6957816020015b6060815260200190600190039081611c545790505b50905060005b8251811015611d2b5760006060306001600160a01b0316858481518110611c9257fe5b6020026020010151604051611ca79190615446565b600060405180830381855af49150503d8060008114611ce2576040519150601f19603f3d011682016040523d82523d6000602084013e611ce7565b606091505b509150915081611d095760405162461bcd60e51b815260040161028d90615beb565b80848481518110611d1657fe5b60209081029190910101525050600101611c6f565b50919050565b600b546001600160a01b031681565b6001546001600160a01b03163314611d6a5760405162461bcd60e51b815260040161028d90615a73565b6012805482919060ff60a81b1916600160a81b836002811115611d8957fe5b021790555050565b6001546001600160a01b03163314611dbb5760405162461bcd60e51b815260040161028d90615a73565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60026000541415611e005760405162461bcd60e51b815260040161028d90615e31565b6002600055610fc43380612be7565b60026000541415611e325760405162461bcd60e51b815260040161028d90615e31565b6002600055601054604051630d59922b60e41b81526001600160a01b039091169063d59922b090611e6d90879087908790879060040161558e565b600060405180830381600087803b158015611e8757600080fd5b505af1158015611a11573d6000803e3d6000fd5b60115481565b6005546001600160a01b031681565b6013602052600090815260409020546001600160a01b031681565b600c546001600160a01b031681565b60026000541415611efd5760405162461bcd60e51b815260040161028d90615e31565b60026000556004546108f390339081906001600160a01b031684612ca4565b60026000541415611f3f5760405162461bcd60e51b815260040161028d90615e31565b6002600055611f4d33613751565b611f5681613877565b60125460ff161561208f57600a546040516310c1c10360e01b81526000916001600160a01b0316906310c1c10390611f92903390600401615465565b60206040518083038186803b158015611faa57600080fd5b505afa158015611fbe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe29190615313565b600a54604051636eb1769f60e11b81529192506000916001600160a01b039091169063dd62ed3e9061201a9033908790600401615479565b60206040518083038186803b15801561203257600080fd5b505afa158015612046573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061206a9190615313565b90508181101561208c5760405162461bcd60e51b815260040161028d906156fa565b50505b33600090815260136020526040812080546001600160a01b0319166001600160a01b03939093169290921790915560019055565b600260005414156120e65760405162461bcd60e51b815260040161028d90615e31565b60026000556003546108f390339081906001600160a01b031684612ca4565b600260005414156121285760405162461bcd60e51b815260040161028d90615e31565b600260005561213633612a2e565b6001600055565b600d546001600160a01b031681565b61088f8363a9059cbb60e01b848460405160240161216b929190615493565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261461c565b601254600160b01b900460ff166121b85761233b565b600a54600854604051637aeceb1f60e11b81526000926001600160a01b039081169263f5d9d63e926121f09287921690600401615479565b60206040518083038186803b15801561220857600080fd5b505afa15801561221c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122409190615313565b9050801561233957600e54604051635d50e72960e01b81526000916001600160a01b031690635d50e72990612279908690600401615465565b60206040518083038186803b15801561229157600080fd5b505afa1580156122a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c99190615313565b9050801561232657600e54600a546122ef916001600160a01b03918216911685846146ab565b6122f983836146d2565b61230283614813565b600e54600a54612321916001600160a01b0391821691869116846146ab565b61088f565b61233083836146d2565b61088f83614813565b505b50565b612347826135b8565b6007546040516310c1c10360e01b81526000916001600160a01b0316906310c1c10390612378908890600401615465565b60206040518083038186803b15801561239057600080fd5b505afa1580156123a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c89190615313565b600a5460095460405163098bf59d60e01b81529293506001600160a01b039182169263098bf59d92612405928a9291169088908390600401615533565b600060405180830381600087803b15801561241f57600080fd5b505af1158015612433573d6000803e3d6000fd5b505060095460085460405163098bf59d60e01b81526001600160a01b03928316945063098bf59d9350612470928a92169088908390600401615533565b600060405180830381600087803b15801561248a57600080fd5b505af115801561249e573d6000803e3d6000fd5b505060085460075460405163098bf59d60e01b81526001600160a01b03928316945063098bf59d93506124db928a92169088908390600401615533565b600060405180830381600087803b1580156124f557600080fd5b505af1158015612509573d6000803e3d6000fd5b505060075460405163098bf59d60e01b81526001600160a01b03909116925063098bf59d9150612543908890889088908390600401615533565b600060405180830381600087803b15801561255d57600080fd5b505af1158015612571573d6000803e3d6000fd5b505050508115612852576008546040516309f4173d60e11b81526001600160a01b03909116906313e82e7a906125ad9088908190600401615479565b602060405180830381600087803b1580156125c757600080fd5b505af11580156125db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125ff9190615313565b50600954600554604051637aeceb1f60e11b81526000926001600160a01b039081169263f5d9d63e92612638928b921690600401615479565b60206040518083038186803b15801561265057600080fd5b505afa158015612664573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126889190615313565b9050801561279a5760006126a6836126a08488614922565b9061495c565b600a5460095460405163098bf59d60e01b81529293506001600160a01b039182169263098bf59d926126e3928c9291169086908390600401615533565b600060405180830381600087803b1580156126fd57600080fd5b505af1158015612711573d6000803e3d6000fd5b505060095460055460405163098bf59d60e01b81526001600160a01b03928316945063098bf59d935061274e928c92169086908390600401615533565b600060405180830381600087803b15801561276857600080fd5b505af115801561277c573d6000803e3d6000fd5b505060055461279892506001600160a01b0316905088836144ed565b505b6005546040516370a0823160e01b81526000916001600160a01b0316906370a08231906127cb908a90600401615465565b60206040518083038186803b1580156127e357600080fd5b505afa1580156127f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061281b9190615313565b9050801561284f576000612833846126a08489614922565b60055490915061284d906001600160a01b031689836144ed565b505b50505b61285b85613477565b7fce8eb393006add0768cc6cefb3ca0fc4787015ce1ac86bd800e72a799931034585858560405161288e9392919061550f565b60405180910390a15050505050565b60008084116128be5760405162461bcd60e51b815260040161028d90615bbf565b600b54600c5460405163098bf59d60e01b815233926001600160a01b039081169263098bf59d926128f992869216908a908390600401615533565b600060405180830381600087803b15801561291357600080fd5b505af1158015612927573d6000803e3d6000fd5b5050600c5460065460405163098bf59d60e01b81526001600160a01b03928316945063098bf59d935061296492869216908a908390600401615533565b600060405180830381600087803b15801561297e57600080fd5b505af1158015612992573d6000803e3d6000fd5b5050600d546040516371d597ad60e01b8152600093506001600160a01b0390911691506371d597ad906129d19085908b908b908b908b9060040161555e565b602060405180830381600087803b1580156129eb57600080fd5b505af11580156129ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a239190615313565b979650505050505050565b6000612a3a8283612be7565b90508015612a5c57600354612a5c90839081906001600160a01b031684612ca4565b600754600b54600091612a7d916001600160a01b0391821691168580612ea3565b90508015612a9f57600454612a9f90849081906001600160a01b031684612ca4565b612aa8836121a2565b612ab183612fc4565b61088f83613477565b600e546040516309f4173d60e11b815260009182916001600160a01b03909116906313e82e7a90612af19087908790600401615479565b602060405180830381600087803b158015612b0b57600080fd5b505af1158015612b1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b439190615313565b600f546040516309f4173d60e11b81529192506000916001600160a01b03909116906313e82e7a90612b7b9088908890600401615479565b602060405180830381600087803b158015612b9557600080fd5b505af1158015612ba9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bcd9190615313565b90506000612bdb8383612c78565b93505050505b92915050565b6009546040516309f4173d60e11b815260009182916001600160a01b03909116906313e82e7a90612c1e9087908790600401615479565b602060405180830381600087803b158015612c3857600080fd5b505af1158015612c4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c709190615313565b949350505050565b600082820183811015612c9d5760405162461bcd60e51b815260040161028d9061572a565b9392505050565b612cad816135b8565b600754604051631e42d69b60e21b81526001600160a01b039091169063790b5a6c90612ce39087908790879087906004016154ac565b600060405180830381600087803b158015612cfd57600080fd5b505af1158015612d11573d6000803e3d6000fd5b5050600854600754604051631e42d69b60e21b81526001600160a01b03928316945063790b5a6c9350612d4f928892839291169087906004016154ac565b600060405180830381600087803b158015612d6957600080fd5b505af1158015612d7d573d6000803e3d6000fd5b5050600954600854604051631e42d69b60e21b81526001600160a01b03928316945063790b5a6c9350612dbb928892839291169087906004016154ac565b600060405180830381600087803b158015612dd557600080fd5b505af1158015612de9573d6000803e3d6000fd5b5050600a54600954604051631e42d69b60e21b81526001600160a01b03928316945063790b5a6c9350612e27928892839291169087906004016154ac565b600060405180830381600087803b158015612e4157600080fd5b505af1158015612e55573d6000803e3d6000fd5b50505050612e6283613477565b7fad0723806aa1e5a8fb826fc9f0c5b589e585a6b60dc768a1b20691c95062d2d6838383604051612e959392919061550f565b60405180910390a150505050565b600080856001600160a01b03166313e82e7a85856040518363ffffffff1660e01b8152600401612ed4929190615479565b602060405180830381600087803b158015612eee57600080fd5b505af1158015612f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f269190615313565b90506000856001600160a01b03166313e82e7a86866040518363ffffffff1660e01b8152600401612f58929190615479565b602060405180830381600087803b158015612f7257600080fd5b505af1158015612f86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612faa9190615313565b90506000612fb88383612c78565b98975050505050505050565b6008546040516309f4173d60e11b81526001600160a01b03909116906313e82e7a90612ff69084908190600401615479565b602060405180830381600087803b15801561301057600080fd5b505af1158015613024573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130489190615313565b506005546040516370a0823160e01b81526000916001600160a01b0316906370a082319061307a908590600401615465565b60206040518083038186803b15801561309257600080fd5b505afa1580156130a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130ca9190615313565b9050806130d7575061233b565b6007546040516310c1c10360e01b81526000916001600160a01b0316906310c1c10390613108908690600401615465565b60206040518083038186803b15801561312057600080fd5b505afa158015613134573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131589190615313565b905060006131776127106126a06011548561492290919063ffffffff16565b600954600554604051637aeceb1f60e11b81529293506000926001600160a01b039283169263f5d9d63e926131b4928a9290911690600401615479565b60206040518083038186803b1580156131cc57600080fd5b505afa1580156131e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132049190615313565b905081811415613217575050505061233b565b8181111561330f57600061322b828461499b565b600a5460095460405163098bf59d60e01b81529293506001600160a01b039182169263098bf59d92613268928b9291169086908390600401615533565b600060405180830381600087803b15801561328257600080fd5b505af1158015613296573d6000803e3d6000fd5b505060095460055460405163098bf59d60e01b81526001600160a01b03928316945063098bf59d93506132d3928b92169086908390600401615533565b600060405180830381600087803b1580156132ed57600080fd5b505af1158015613301573d6000803e3d6000fd5b50505050505050505061233b565b600061331b838361499b565b905080851115613329578094505b600954600554604051631e42d69b60e21b81526001600160a01b039283169263790b5a6c92613362928b92839216908b906004016154ac565b600060405180830381600087803b15801561337c57600080fd5b505af1158015613390573d6000803e3d6000fd5b5050600a54600954604051631e42d69b60e21b81526001600160a01b03928316945063790b5a6c93506133ce928b9283929116908b906004016154ac565b600060405180830381600087803b1580156133e857600080fd5b505af11580156133fc573d6000803e3d6000fd5b50505050505050505050565b600254604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d90613438908490600401615ead565b600060405180830381600087803b15801561345257600080fd5b505af1158015613466573d6000803e3d6000fd5b5061233b9250339150839050614580565b6000601254600160a81b900460ff16600281111561349157fe5b141561349c5761233b565b6001601254600160a81b900460ff1660028111156134b657fe5b141561354f576007546040516310c1c10360e01b81526000916001600160a01b0316906310c1c103906134ed908590600401615465565b60206040518083038186803b15801561350557600080fd5b505afa158015613519573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061353d9190615313565b905061354982826149dd565b5061233b565b6002601254600160a81b900460ff16600281111561356957fe5b14156135a057600a546040516310c1c10360e01b81526000916001600160a01b0316906310c1c103906134ed908590600401615465565b60405162461bcd60e51b815260040161028d90615666565b6000811161233b5760405162461bcd60e51b815260040161028d9061598a565b600d546040516317eb2a1560e01b8152600091339183916001600160a01b0316906317eb2a1590613617908b9086908c908c908c908c906004016154d6565b602060405180830381600087803b15801561363157600080fd5b505af1158015613645573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136699190615313565b600c54600654604051631e42d69b60e21b81529293506001600160a01b039182169263790b5a6c926136a792879283929091169087906004016154ac565b600060405180830381600087803b1580156136c157600080fd5b505af11580156136d5573d6000803e3d6000fd5b5050600b54600c54604051631e42d69b60e21b81526001600160a01b03928316945063790b5a6c9350613713928792839291169087906004016154ac565b600060405180830381600087803b15801561372d57600080fd5b505af1158015613741573d6000803e3d6000fd5b50929a9950505050505050505050565b600e546040516370a0823160e01b81526001600160a01b03909116906370a0823190613781908490600401615465565b60206040518083038186803b15801561379957600080fd5b505afa1580156137ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137d19190615313565b15801561385b5750600f546040516370a0823160e01b81526001600160a01b03909116906370a0823190613809908490600401615465565b60206040518083038186803b15801561382157600080fd5b505afa158015613835573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138599190615313565b155b61233b5760405162461bcd60e51b815260040161028d90615c53565b60075460405163a318021760e01b81526001600160a01b039091169063a3180217906138a7908490600401615465565b60206040518083038186803b1580156138bf57600080fd5b505afa1580156138d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f79190615313565b156139145760405162461bcd60e51b815260040161028d906157a9565b600754604051633792def360e01b81526001600160a01b0390911690633792def390613944908490600401615465565b60206040518083038186803b15801561395c57600080fd5b505afa158015613970573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139949190615313565b156139b15760405162461bcd60e51b815260040161028d90615620565b60085460405163a318021760e01b81526001600160a01b039091169063a3180217906139e1908490600401615465565b60206040518083038186803b1580156139f957600080fd5b505afa158015613a0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a319190615313565b15613a4e5760405162461bcd60e51b815260040161028d90615d78565b600854604051633792def360e01b81526001600160a01b0390911690633792def390613a7e908490600401615465565b60206040518083038186803b158015613a9657600080fd5b505afa158015613aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ace9190615313565b15613aeb5760405162461bcd60e51b815260040161028d90615e68565b60095460405163a318021760e01b81526001600160a01b039091169063a318021790613b1b908490600401615465565b60206040518083038186803b158015613b3357600080fd5b505afa158015613b47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b6b9190615313565b15613b885760405162461bcd60e51b815260040161028d906158f9565b600954604051633792def360e01b81526001600160a01b0390911690633792def390613bb8908490600401615465565b60206040518083038186803b158015613bd057600080fd5b505afa158015613be4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c089190615313565b15613c255760405162461bcd60e51b815260040161028d90615b2e565b600a5460405163a318021760e01b81526001600160a01b039091169063a318021790613c55908490600401615465565b60206040518083038186803b158015613c6d57600080fd5b505afa158015613c81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ca59190615313565b15613cc25760405162461bcd60e51b815260040161028d90615dc0565b600a54604051633792def360e01b81526001600160a01b0390911690633792def390613cf2908490600401615465565b60206040518083038186803b158015613d0a57600080fd5b505afa158015613d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d429190615313565b15613d5f5760405162461bcd60e51b815260040161028d90615c10565b600e54604051631ccdc0d760e21b81526001600160a01b0390911690637337035c90613d8f908490600401615465565b60206040518083038186803b158015613da757600080fd5b505afa158015613dbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ddf9190615313565b15613dfc5760405162461bcd60e51b815260040161028d90615a26565b600e54604051635b8de71560e11b81526001600160a01b039091169063b71bce2a90613e2c908490600401615465565b60206040518083038186803b158015613e4457600080fd5b505afa158015613e58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e7c9190615313565b15613e995760405162461bcd60e51b815260040161028d9061575f565b600b5460405163a318021760e01b81526001600160a01b039091169063a318021790613ec9908490600401615465565b60206040518083038186803b158015613ee157600080fd5b505afa158015613ef5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f199190615313565b15613f365760405162461bcd60e51b815260040161028d90615b76565b600b54604051633792def360e01b81526001600160a01b0390911690633792def390613f66908490600401615465565b60206040518083038186803b158015613f7e57600080fd5b505afa158015613f92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fb69190615313565b15613fd35760405162461bcd60e51b815260040161028d90615944565b600c5460405163a318021760e01b81526001600160a01b039091169063a318021790614003908490600401615465565b60206040518083038186803b15801561401b57600080fd5b505afa15801561402f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140539190615313565b156140705760405162461bcd60e51b815260040161028d906159e0565b600c54604051633792def360e01b81526001600160a01b0390911690633792def3906140a0908490600401615465565b60206040518083038186803b1580156140b857600080fd5b505afa1580156140cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140f09190615313565b1561410d5760405162461bcd60e51b815260040161028d90615c85565b600f54604051631ccdc0d760e21b81526001600160a01b0390911690637337035c9061413d908490600401615465565b60206040518083038186803b15801561415557600080fd5b505afa158015614169573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061418d9190615313565b156141aa5760405162461bcd60e51b815260040161028d90615a26565b600f54604051635b8de71560e11b81526001600160a01b039091169063b71bce2a906141da908490600401615465565b60206040518083038186803b1580156141f257600080fd5b505afa158015614206573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061422a9190615313565b156142475760405162461bcd60e51b815260040161028d9061575f565b600e546040516370a0823160e01b81526001600160a01b03909116906370a0823190614277908490600401615465565b60206040518083038186803b15801561428f57600080fd5b505afa1580156142a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c79190615313565b156142e45760405162461bcd60e51b815260040161028d90615cff565b600f546040516370a0823160e01b81526001600160a01b03909116906370a0823190614314908490600401615465565b60206040518083038186803b15801561432c57600080fd5b505afa158015614340573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143649190615313565b1561233b5760405162461bcd60e51b815260040161028d9061569b565b80156144e55760405163098bf59d60e01b81526001600160a01b0387169063098bf59d906143b9908790899086908390600401615533565b600060405180830381600087803b1580156143d357600080fd5b505af11580156143e7573d6000803e3d6000fd5b505060405163098bf59d60e01b81526001600160a01b038816925063098bf59d915061441d908790869086908390600401615533565b600060405180830381600087803b15801561443757600080fd5b505af115801561444b573d6000803e3d6000fd5b5050604051631e42d69b60e21b81526001600160a01b038816925063790b5a6c91506144819087908790879087906004016154ac565b600060405180830381600087803b15801561449b57600080fd5b505af11580156144af573d6000803e3d6000fd5b5050604051631e42d69b60e21b81526001600160a01b038916925063790b5a6c91506133ce90869081908a9087906004016154ac565b505050505050565b604051632770a7eb60e21b81526001600160a01b03841690639dc29fac9061451b9085908590600401615493565b600060405180830381600087803b15801561453557600080fd5b505af1158015614549573d6000803e3d6000fd5b50505050505050565b6040516340c10f1960e01b81526001600160a01b038416906340c10f199061451b9085908590600401615493565b804710156145a05760405162461bcd60e51b815260040161028d9061587c565b6000826001600160a01b0316826040516145b990615462565b60006040518083038185875af1925050503d80600081146145f6576040519150601f19603f3d011682016040523d82523d6000602084013e6145fb565b606091505b505090508061088f5760405162461bcd60e51b815260040161028d906157f2565b6060614671826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614ad89092919063ffffffff16565b80519091501561088f578080602001905181019061468f91906150e4565b61088f5760405162461bcd60e51b815260040161028d90615d2e565b6146cc846323b872dd60e01b85858560405160240161216b9392919061550f565b50505050565b600a5460085460405163098bf59d60e01b81526001600160a01b039283169263098bf59d9261470d9287929091169086908390600401615533565b600060405180830381600087803b15801561472757600080fd5b505af115801561473b573d6000803e3d6000fd5b5050600954600854604051631e42d69b60e21b81526001600160a01b03928316945063790b5a6c9350614779928792839291169087906004016154ac565b600060405180830381600087803b15801561479357600080fd5b505af11580156147a7573d6000803e3d6000fd5b5050600a54600954604051631e42d69b60e21b81526001600160a01b03928316945063790b5a6c93506147e5928792839291169087906004016154ac565b600060405180830381600087803b1580156147ff57600080fd5b505af11580156144e5573d6000803e3d6000fd5b600a54600554604051637aeceb1f60e11b81526000926001600160a01b039081169263f5d9d63e9261484b9287921690600401615479565b60206040518083038186803b15801561486357600080fd5b505afa158015614877573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061489b9190615313565b9050801561233957600a5460055460405163098bf59d60e01b81526001600160a01b039283169263098bf59d926148de9287929091169086908390600401615533565b600060405180830381600087803b1580156148f857600080fd5b505af115801561490c573d6000803e3d6000fd5b5050505061491982612fc4565b61233982613477565b60008261493157506000612be1565b8282028284828161493e57fe5b0414612c9d5760405162461bcd60e51b815260040161028d90615aed565b6000612c9d83836040518060400160405280601a815260200179536166654d6174683a206469766973696f6e206279207a65726f60301b815250614ae7565b6000612c9d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614b1e565b6012546040516370a0823160e01b815260009161010090046001600160a01b0316906370a0823190614a13908690600401615465565b60206040518083038186803b158015614a2b57600080fd5b505afa158015614a3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614a639190615313565b905081811415614a735750612339565b81811115614aad576000614a87828461499b565b601254909150614aa69061010090046001600160a01b031685836144ed565b5050612339565b6000614ab9838361499b565b6012549091506146cc9061010090046001600160a01b03168583614552565b6060612c708484600085614b4a565b60008183614b085760405162461bcd60e51b815260040161028d919061560d565b506000838581614b1457fe5b0495945050505050565b60008184841115614b425760405162461bcd60e51b815260040161028d919061560d565b505050900390565b606082471015614b6c5760405162461bcd60e51b815260040161028d906158b3565b614b7585614c00565b614b915760405162461bcd60e51b815260040161028d90615cc8565b60006060866001600160a01b03168587604051614bae9190615446565b60006040518083038185875af1925050503d8060008114614beb576040519150601f19603f3d011682016040523d82523d6000602084013e614bf0565b606091505b5091509150612a23828286614c06565b3b151590565b60608315614c15575081612c9d565b825115614c255782518084602001fd5b8160405162461bcd60e51b815260040161028d919061560d565b8035612be181615f27565b600082601f830112614c5a578081fd5b8135614c6d614c6882615edc565b615eb6565b818152915060208083019084810181840286018201871015614c8e57600080fd5b60005b84811015614cb6578135614ca481615f27565b84529282019290820190600101614c91565b505050505092915050565b6000601f8381840112614cd2578182fd5b8235614ce0614c6882615edc565b818152925060208084019085810160005b84811015614d72578135880189603f820112614d0c57600080fd5b808401356001600160401b03811115614d2457600080fd5b614d35818901601f19168601615eb6565b81815260408c81848601011115614d4b57600080fd5b82818501888401375060009181018601919091528552509282019290820190600101614cf1565b50505050505092915050565b600060208284031215614d8f578081fd5b8135612c9d81615f27565b600080600060608486031215614dae578182fd5b8335614db981615f27565b92506020840135614dc981615f27565b929592945050506040919091013590565b600080600080600080600080610100898b031215614df6578384fd5b8835614e0181615f27565b97506020890135614e1181615f3c565b96506040890135614e2181615f3c565b95506060890135614e3181615f3c565b94506080890135614e4181615f3c565b935060a0890135614e5181615f3c565b925060c0890135614e6181615f3c565b915060e0890135614e7181615f3c565b809150509295985092959890939650565b60008060008060808587031215614e97578384fd5b8435614ea281615f27565b935060208501359250604085013591506060850135614ec081615f27565b939692955090935050565b60008060008060808587031215614ee0578384fd5b8435614eeb81615f27565b966020860135965060408601359560600135945092505050565b600060208284031215614f16578081fd5b81356001600160401b03811115614f2b578182fd5b612c7084828501614c4a565b60008060008060808587031215614f4c578182fd5b84356001600160401b0380821115614f62578384fd5b614f6e88838901614c4a565b95506020870135915080821115614f83578384fd5b614f8f88838901614cc1565b94506040870135915080821115614fa4578384fd5b614fb088838901614c4a565b93506060870135915080821115614fc5578283fd5b50614fd287828801614c4a565b91505092959194509250565b60008060408385031215614ff0578182fd5b82356001600160401b0380821115615006578384fd5b61501286838701614c4a565b9350602091508185013581811115615028578384fd5b85019050601f8101861361503a578283fd5b8035615048614c6882615edc565b81815283810190838501858402850186018a1015615064578687fd5b8694505b83851015615086578035835260019490940193918501918501615068565b5080955050505050509250929050565b6000602082840312156150a7578081fd5b81356001600160401b038111156150bc578182fd5b612c7084828501614cc1565b6000602082840312156150d9578081fd5b8135612c9d81615f3c565b6000602082840312156150f5578081fd5b8151612c9d81615f3c565b600080600080600080600060e0888a03121561511a578081fd5b873561512581615f3c565b9650602088013561513581615f3c565b9550604088013561514581615f3c565b9450606088013561515581615f3c565b9350608088013561516581615f3c565b925060a088013561517581615f3c565b915060c088013561518581615f3c565b8091505092959891949750929550565b6000602082840312156151a6578081fd5b813560038110612c9d578182fd5b60006102008083850312156151c7578182fd5b6151d081615eb6565b90506151dc8484614c3f565b81526151eb8460208501614c3f565b60208201526151fd8460408501614c3f565b604082015261520f8460608501614c3f565b60608201526152218460808501614c3f565b60808201526152338460a08501614c3f565b60a08201526152458460c08501614c3f565b60c08201526152578460e08501614c3f565b60e082015261010061526b85828601614c3f565b9082015261012061527e85858301614c3f565b9082015261014061529185858301614c3f565b908201526101606152a485858301614c3f565b908201526101806152b785858301614c3f565b908201526101a06152ca85858301614c3f565b908201526101c06152dd85858301614c3f565b908201526101e06152f085858301614c3f565b908201529392505050565b60006020828403121561530c578081fd5b5035919050565b600060208284031215615324578081fd5b5051919050565b6000806040838503121561533d578182fd5b50508035926020909101359150565b600080600060608486031215615360578081fd5b8335925060208401359150604084013561537981615f27565b809150509250925092565b6000815180845260208085019450808401835b838110156153bc5781516001600160a01b031687529582019590820190600101615397565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b8581101561540d5782840389526153fb84835161541a565b988501989350908401906001016153e3565b5091979650505050505050565b60008151808452615432816020860160208601615efb565b601f01601f19169290920160200192915050565b60008251615458818460208701615efb565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b6001600160a01b03968716815294861660208601529290941660408401526060830152608082019290925260a081019190915260c00190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03948516815292841660208401526040830191909152909116606082015260800190565b6001600160a01b039586168152938516602085015260408401929092526060830152909116608082015260a00190565b6000608082526155a16080830187615384565b82810360208401526155b381876153c7565b905082810360408401526155c78186615384565b90508281036060840152612a238185615384565b600060208252612c9d60208301846153c7565b901515815260200190565b602081016003831061560757fe5b91905290565b600060208252612c9d602083018461541a565b60208082526026908201527f7374616b6564476d78547261636b65722e63756d756c6174697665526577617260408201526506473203e20360d41b606082015260800190565b6020808252601b908201527a756e737570706f7274656420766f74696e67506f7765725479706560281b604082015260600190565b6020808252601590820152740676c705665737465722e62616c616e6365203e203605c1b604082015260600190565b6020808252601690820152752937baba32b91d1034b73b30b634b21039b2b73232b960511b604082015260600190565b602080825260169082015275696e73756666696369656e7420616c6c6f77616e636560501b604082015260600190565b6020808252601b908201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604082015260600190565b6020808252602a908201527f676d785665737465722e7472616e7366657272656443756d756c6174697665526040820152690657761726473203e20360b41b606082015260800190565b60208082526029908201527f7374616b6564476d78547261636b65722e617665726167655374616b6564416d60408201526806f756e7473203e20360bc1b606082015260800190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c20726040820152791958da5c1a595b9d081b585e481a185d99481c995d995c9d195960321b606082015260800190565b6020808252601690820152751d1c985b9cd9995c881b9bdd081cda59db985b1b195960521b604082015260600190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252602b908201527f657874656e646564476d78547261636b65722e617665726167655374616b656460408201526a0416d6f756e7473203e20360ac1b606082015260800190565b60208082526026908201527f7374616b6564476c70547261636b65722e63756d756c6174697665526577617260408201526506473203e20360d41b606082015260800190565b6020808252600f908201526e1a5b9d985b1a590817d85b5bdd5b9d608a1b604082015260600190565b602080825260139082015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604082015260600190565b60208082526026908201527f666565476c70547261636b65722e617665726167655374616b6564416d6f756e60408201526507473203e20360d41b606082015260800190565b6020808252602d908201527f676d785665737465722e7472616e73666572726564417665726167655374616b60408201526c06564416d6f756e7473203e203609c1b606082015260800190565b60208082526015908201527423b7bb32b93730b136329d103337b93134b23232b760591b604082015260600190565b6020808252602b908201527f63616e6e6f74207374616b6520474d58206966205f676d78526563656976657260408201526a08084f481858d8dbdd5b9d60aa1b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b60208082526028908201527f657874656e646564476d78547261636b65722e63756d756c6174697665526577604082015267061726473203e20360c41b606082015260800190565b60208082526029908201527f7374616b6564476c70547261636b65722e617665726167655374616b6564416d60408201526806f756e7473203e20360bc1b606082015260800190565b6020808252601290820152711a5b9d985b1a590817d9db1c105b5bdd5b9d60721b604082015260600190565b6020808252600b908201526a18d85b1b0819985a5b195960aa1b604082015260600190565b60208082526023908201527f666565476d78547261636b65722e63756d756c6174697665526577617264732060408201526203e20360ec1b606082015260800190565b60208082526018908201527773656e646572206861732076657374656420746f6b656e7360401b604082015260600190565b60208082526023908201527f666565476c70547261636b65722e63756d756c6174697665526577617264732060408201526203e20360ec1b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252601590820152740676d785665737465722e62616c616e6365203e203605c1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526028908201527f626f6e7573476d78547261636b65722e617665726167655374616b6564416d6f6040820152670756e7473203e20360c41b606082015260800190565b60208082526026908201527f666565476d78547261636b65722e617665726167655374616b6564416d6f756e60408201526507473203e20360d41b606082015260800190565b602080825260119082015270696e76616c6964206d73672e76616c756560781b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526025908201527f626f6e7573476d78547261636b65722e63756d756c6174697665526577617264604082015264073203e20360dc1b606082015260800190565b90815260200190565b6040518181016001600160401b0381118282101715615ed457600080fd5b604052919050565b60006001600160401b03821115615ef1578081fd5b5060209081020190565b60005b83811015615f16578181015183820152602001615efe565b838111156146cc5750506000910152565b6001600160a01b038116811461233b57600080fd5b801515811461233b57600080fdfea4725d47fa458d9222498e4d63f34527cf7318c1506f89d9092b35fdbcb64f3a1cb6202519b6b6c72ba5ed11e2c3f53af3cea010f96bfc705584e53e75cf034ca2646970667358221220c5871ff962531b74ae54b48c23eda76453b365ab92e26fad377199b8dd15ec8364736f6c634300060c0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.