More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 46,298 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw | 60790561 | 13 mins ago | IN | 0 AVAX | 0.00003953 | ||||
Withdraw | 60790553 | 13 mins ago | IN | 0 AVAX | 0.00004074 | ||||
Deposit | 60790539 | 14 mins ago | IN | 0.01 AVAX | 0.00002939 | ||||
Withdraw | 60788845 | 50 mins ago | IN | 0 AVAX | 0.00047361 | ||||
Deposit | 60788243 | 1 hr ago | IN | 33.3338323 AVAX | 0.00025144 | ||||
Withdraw | 60785354 | 2 hrs ago | IN | 0 AVAX | 0.00047004 | ||||
Withdraw | 60757945 | 12 hrs ago | IN | 0 AVAX | 0.00080072 | ||||
Withdraw | 60740111 | 19 hrs ago | IN | 0 AVAX | 0.00341941 | ||||
Withdraw | 60739433 | 19 hrs ago | IN | 0 AVAX | 0.01408108 | ||||
Withdraw | 60690441 | 39 hrs ago | IN | 0 AVAX | 0.00003202 | ||||
Withdraw | 60690429 | 39 hrs ago | IN | 0 AVAX | 0.00003231 | ||||
Deposit | 60690419 | 39 hrs ago | IN | 0.01 AVAX | 0.00003023 | ||||
Withdraw | 60686370 | 41 hrs ago | IN | 0 AVAX | 0.00033036 | ||||
Deposit | 60638016 | 2 days ago | IN | 52.90184208 AVAX | 0.00037148 | ||||
Withdraw | 60562708 | 3 days ago | IN | 0 AVAX | 0.00057893 | ||||
Withdraw | 60520573 | 4 days ago | IN | 0 AVAX | 0.00029525 | ||||
Withdraw | 60481630 | 5 days ago | IN | 0 AVAX | 0.00046712 | ||||
Withdraw | 60452126 | 5 days ago | IN | 0 AVAX | 0.00029528 | ||||
Withdraw | 60418359 | 6 days ago | IN | 0 AVAX | 0.00029235 | ||||
Withdraw | 60386397 | 6 days ago | IN | 0 AVAX | 0.00047 | ||||
Withdraw | 60373418 | 7 days ago | IN | 0 AVAX | 0.00029233 | ||||
Withdraw | 60373224 | 7 days ago | IN | 0 AVAX | 0.00046899 | ||||
Deposit | 60371901 | 7 days ago | IN | 0.00562376 AVAX | 0.00025144 | ||||
Withdraw | 60279569 | 8 days ago | IN | 0 AVAX | 0.00046696 | ||||
Deposit | 60221481 | 9 days ago | IN | 11.17424877 AVAX | 0.00039905 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
60790561 | 13 mins ago | 0.005 AVAX | ||||
60790561 | 13 mins ago | 0.005 AVAX | ||||
60790553 | 13 mins ago | 0.005 AVAX | ||||
60790553 | 13 mins ago | 0.005 AVAX | ||||
60790539 | 14 mins ago | 0.01 AVAX | ||||
60788845 | 50 mins ago | 33.33384536 AVAX | ||||
60788845 | 50 mins ago | 33.33384536 AVAX | ||||
60788243 | 1 hr ago | 33.3338323 AVAX | ||||
60785354 | 2 hrs ago | 40.96889314 AVAX | ||||
60785354 | 2 hrs ago | 40.96889314 AVAX | ||||
60757945 | 12 hrs ago | 272.25178589 AVAX | ||||
60757945 | 12 hrs ago | 272.25178589 AVAX | ||||
60740111 | 19 hrs ago | 640.79316463 AVAX | ||||
60740111 | 19 hrs ago | 640.79316463 AVAX | ||||
60739433 | 19 hrs ago | 100.1441333 AVAX | ||||
60739433 | 19 hrs ago | 100.1441333 AVAX | ||||
60690441 | 39 hrs ago | 0.005 AVAX | ||||
60690441 | 39 hrs ago | 0.005 AVAX | ||||
60690429 | 39 hrs ago | 0.005 AVAX | ||||
60690429 | 39 hrs ago | 0.005 AVAX | ||||
60690419 | 39 hrs ago | 0.01 AVAX | ||||
60686370 | 41 hrs ago | 33.58497433 AVAX | ||||
60686370 | 41 hrs ago | 33.58497433 AVAX | ||||
60638016 | 2 days ago | 52.90184208 AVAX | ||||
60562708 | 3 days ago | 17.17443362 AVAX |
Loading...
Loading
Contract Name:
BenqiStrategyAvaxV1
Compiler Version
v0.7.3+commit.9bfce1f6
Optimization Enabled:
Yes with 999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "../YakStrategyV2Payable.sol"; import "../interfaces/IBenqiUnitroller.sol"; import "../interfaces/IBenqiAVAXDelegator.sol"; import "../interfaces/IWAVAX.sol"; import "../interfaces/IERC20.sol"; import "../lib/DexLibrary.sol"; import "../lib/ReentrancyGuard.sol"; contract BenqiStrategyAvaxV1 is YakStrategyV2Payable, ReentrancyGuard { using SafeMath for uint; IBenqiUnitroller private rewardController; IBenqiAVAXDelegator private tokenDelegator; IERC20 private rewardToken0; IPair private swapPairToken0; // swaps rewardToken0 to WAVAX IWAVAX private constant WAVAX = IWAVAX(0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7); uint private leverageLevel; uint private leverageBips; uint private minMinting; constructor ( string memory _name, address _rewardController, address _tokenDelegator, address _rewardToken0, address _swapPairToken0, address _timelock, uint _minMinting, uint _leverageLevel, uint _leverageBips, uint _minTokensToReinvest, uint _adminFeeBips, uint _devFeeBips, uint _reinvestRewardBips ) { name = _name; depositToken = IERC20(address(0)); rewardController = IBenqiUnitroller(_rewardController); tokenDelegator = IBenqiAVAXDelegator(_tokenDelegator); rewardToken0 = IERC20(_rewardToken0); rewardToken = IERC20(address(WAVAX)); minMinting = _minMinting; _updateLeverage(_leverageLevel, _leverageBips); devAddr = msg.sender; _enterMarket(); assignSwapPairSafely(_swapPairToken0); setAllowances(); updateMinTokensToReinvest(_minTokensToReinvest); updateAdminFee(_adminFeeBips); updateDevFee(_devFeeBips); updateReinvestReward(_reinvestRewardBips); updateDepositsEnabled(true); transferOwnership(_timelock); emit Reinvest(0, 0); } function totalDeposits() public override view returns (uint) { (, uint256 internalBalance, uint borrow, uint256 exchangeRate) = tokenDelegator.getAccountSnapshot(address(this)); return internalBalance.mul(exchangeRate).div(1e18).sub(borrow); } function _totalDepositsFresh() internal returns (uint) { uint borrow = tokenDelegator.borrowBalanceCurrent(address(this)); uint balance = tokenDelegator.balanceOfUnderlying(address(this)); return balance.sub(borrow); } function _enterMarket() internal { address[] memory tokens = new address[](1); tokens[0] = address(tokenDelegator); rewardController.enterMarkets(tokens); } function _updateLeverage(uint _leverageLevel, uint _leverageBips) internal { leverageLevel = _leverageLevel; leverageBips = _leverageBips; } function updateLeverage(uint _leverageLevel, uint _leverageBips) external onlyDev { _updateLeverage(_leverageLevel, _leverageBips); _unrollDebt(); uint balance = tokenDelegator.balanceOfUnderlying(address(this)); if (balance > 0) { _rollupDebt(balance, 0); } } /** * @notice Initialization helper for Pair deposit tokens * @dev Checks that selected Pairs are valid for trading deposit tokens * @dev Assigns values to swapPairToken0 and swapPairToken1 */ function assignSwapPairSafely(address _swapPairToken0) private { require(_swapPairToken0 > address(0), "Swap pair 0 is necessary but not supplied"); require( address(rewardToken0) == IPair(address(_swapPairToken0)).token0() || address(rewardToken0) == IPair(address(_swapPairToken0)).token1(), "Swap pair 0 does not match rewardToken0" ); require( address(WAVAX) == IPair(address(_swapPairToken0)).token0() || address(WAVAX) == IPair(address(_swapPairToken0)).token1(), "Swap pair 0 does not match WAVAX" ); swapPairToken0 = IPair(_swapPairToken0); } function setAllowances() public override onlyOwner { tokenDelegator.approve(address(tokenDelegator), type(uint256).max); } function deposit() external payable override nonReentrant { _deposit(msg.sender, msg.value); } function depositFor(address account) external payable override nonReentrant { _deposit(account, msg.value); } function deposit(uint amount) external override { revert(); } function depositWithPermit(uint amount, uint deadline, uint8 v, bytes32 r, bytes32 s) external override { revert(); } function depositFor(address account, uint amount) external override { revert(); } function _deposit(address account, uint amount) private onlyAllowedDeposits { require(DEPOSITS_ENABLED == true, "BenqiStrategyV1::_deposit"); if (MAX_TOKENS_TO_DEPOSIT_WITHOUT_REINVEST > 0) { (uint qiRewards, uint avaxRewards, uint totalAvaxRewards) = _checkRewards(); if (totalAvaxRewards > MAX_TOKENS_TO_DEPOSIT_WITHOUT_REINVEST) { _reinvest(qiRewards, avaxRewards, totalAvaxRewards); } } uint depositTokenAmount = amount; uint balance = _totalDepositsFresh(); if (totalSupply.mul(balance) > 0) { depositTokenAmount = amount.mul(totalSupply).div(balance); } _mint(account, depositTokenAmount); _stakeDepositTokens(amount); emit Deposit(account, amount); } function withdraw(uint amount) external override nonReentrant { require(amount > minMinting, "BenqiStrategyV1::below minimum withdraw"); uint depositTokenAmount = _totalDepositsFresh().mul(amount).div(totalSupply); if (depositTokenAmount > 0) { _burn(msg.sender, amount); _withdrawDepositTokens(depositTokenAmount); (bool success, ) = msg.sender.call{value: depositTokenAmount}(""); require(success, "BenqiStrategyV1::withdraw transfer failed"); emit Withdraw(msg.sender, depositTokenAmount); } } function _withdrawDepositTokens(uint amount) private { _unrollDebt(); require(tokenDelegator.redeemUnderlying(amount) == 0, "BenqiStrategyV1::redeem failed"); uint balance = tokenDelegator.balanceOfUnderlying(address(this)); if (balance > 0) { _rollupDebt(balance, 0); } } function reinvest() external override onlyEOA nonReentrant { (uint qiRewards, uint avaxRewards, uint totalAvaxRewards) = _checkRewards(); require(totalAvaxRewards >= MIN_TOKENS_TO_REINVEST, "BenqiStrategyV1::reinvest"); _reinvest(qiRewards, avaxRewards, totalAvaxRewards); } receive() external payable { require( msg.sender == address(rewardController) || msg.sender == address(WAVAX) || msg.sender == address(tokenDelegator), "BenqiStrategyV1::payments not allowed" ); } /** * @notice Reinvest rewards from staking contract to deposit tokens * @dev Reverts if the expected amount of tokens are not returned from `stakingContract` * @param amount deposit tokens to reinvest */ function _reinvest(uint qiRewards, uint avaxRewards, uint amount) private { rewardController.claimReward(0, address(this)); rewardController.claimReward(1, address(this)); if (qiRewards > 0) { uint convertedWavax = DexLibrary.swap(qiRewards, address(rewardToken0), address(WAVAX), swapPairToken0); WAVAX.withdraw(convertedWavax); } amount = address(this).balance; uint devFee = amount.mul(DEV_FEE_BIPS).div(BIPS_DIVISOR); uint adminFee = amount.mul(ADMIN_FEE_BIPS).div(BIPS_DIVISOR); uint reinvestFee = amount.mul(REINVEST_REWARD_BIPS).div(BIPS_DIVISOR); WAVAX.deposit{value: devFee.add(adminFee).add(reinvestFee)}(); if (devFee > 0) { _safeTransfer(address(rewardToken), devAddr, devFee); } if (adminFee > 0) { _safeTransfer(address(rewardToken), owner(), adminFee); } if (reinvestFee > 0) { _safeTransfer(address(rewardToken), msg.sender, reinvestFee); } _stakeDepositTokens(amount.sub(devFee).sub(adminFee).sub(reinvestFee)); emit Reinvest(totalDeposits(), totalSupply); } function _rollupDebt(uint principal, uint borrowed) internal { (uint borrowLimit, uint borrowBips) = _getBorrowLimit(); uint supplied = principal; uint lendTarget = principal.sub(borrowed).mul(leverageLevel).div(leverageBips); uint totalBorrowed = borrowed; while(supplied < lendTarget) { uint toBorrowAmount = _getBorrowable(supplied, totalBorrowed, borrowLimit, borrowBips); if (supplied.add(toBorrowAmount) > lendTarget) { toBorrowAmount = lendTarget.sub(supplied); } // safeguard needed because we can't mint below a certain threshold if (toBorrowAmount < minMinting) { break; } require(tokenDelegator.borrow(toBorrowAmount) == 0, "BenqiStrategyV1::borrowing failed"); tokenDelegator.mint{value: toBorrowAmount}(); supplied = tokenDelegator.balanceOfUnderlying(address(this)); totalBorrowed = totalBorrowed.add(toBorrowAmount); } } function _getRedeemable(uint balance, uint borrowed, uint borrowLimit, uint bips) internal pure returns (uint256) { return balance.sub(borrowed.mul(bips).div(borrowLimit)); } function _getBorrowable(uint balance, uint borrowed, uint borrowLimit, uint bips) internal pure returns (uint256) { return balance.mul(borrowLimit).div(bips).sub(borrowed); } function _getBorrowLimit() internal view returns (uint, uint) { (, uint borrowLimit) = rewardController.markets(address(tokenDelegator)); return (borrowLimit, 1e18); } function _unrollDebt() internal { uint borrowed = tokenDelegator.borrowBalanceCurrent(address(this)); uint balance = tokenDelegator.balanceOfUnderlying(address(this)); (uint borrowLimit, uint borrowBips) = _getBorrowLimit(); while(borrowed > 0) { uint unrollAmount = _getRedeemable(balance, borrowed, borrowLimit, borrowBips); if (unrollAmount > borrowed) { unrollAmount = borrowed; } require(tokenDelegator.redeemUnderlying(unrollAmount) == 0, "BenqiStrategyV1::failed to redeem"); tokenDelegator.repayBorrow{value: unrollAmount}(); balance = balance.sub(unrollAmount); borrowed = borrowed.sub(unrollAmount); } } function _stakeDepositTokens(uint amount) private { require(amount > 0, "BenqiStrategyV1::_stakeDepositTokens"); tokenDelegator.mint{value: amount}(); uint borrowed = tokenDelegator.borrowBalanceCurrent(address(this)); uint principal = tokenDelegator.balanceOfUnderlying(address(this)); _rollupDebt(principal, borrowed); } /** * @notice Safely transfer using an anonymosu ERC20 token * @dev Requires token to return true on transfer * @param token address * @param to recipient address * @param value amount */ function _safeTransfer(address token, address to, uint256 value) private { require(IERC20(token).transfer(to, value), 'BenqiStrategyV1::TRANSFER_FROM_FAILED'); } function _checkRewards() internal view returns (uint qiAmount, uint avaxAmount, uint totalAvaxAmount) { uint qiRewards = _getReward(0, address(this)); uint avaxRewards = _getReward(1, address(this)); uint qiAsWavax = DexLibrary.estimateConversionThroughPair( qiRewards, address(rewardToken0), address(WAVAX), swapPairToken0 ); return (qiRewards, avaxRewards, avaxRewards.add(qiAsWavax)); } function checkReward() public override view returns (uint) { (,,uint avaxRewards) = _checkRewards(); return avaxRewards; } function _getReward(uint8 tokenIndex, address account) internal view returns (uint) { uint rewardAccrued = rewardController.rewardAccrued(tokenIndex, account); (uint224 supplyIndex, ) = rewardController.rewardSupplyState(tokenIndex, account); uint supplierIndex = rewardController.rewardSupplierIndex(tokenIndex, address(tokenDelegator), account); uint supplyIndexDelta = 0; if (supplyIndex > supplierIndex) { supplyIndexDelta = supplyIndex - supplierIndex; } uint supplyAccrued = tokenDelegator.balanceOf(account).mul(supplyIndexDelta); (uint224 borrowIndex, ) = rewardController.rewardBorrowState(tokenIndex, account); uint borrowerIndex = rewardController.rewardBorrowerIndex(tokenIndex, address(tokenDelegator), account); uint borrowIndexDelta = 0; if (borrowIndex > borrowerIndex) { borrowIndexDelta = borrowIndex - borrowerIndex; } uint borrowAccrued = tokenDelegator.borrowBalanceStored(account).mul(borrowIndexDelta); return rewardAccrued.add(supplyAccrued.sub(borrowAccrued)); } function getActualLeverage() public view returns (uint) { (, uint256 internalBalance, uint256 borrow, uint256 exchangeRate) = tokenDelegator.getAccountSnapshot(address(this)); uint balance = internalBalance.mul(exchangeRate).div(1e18); return balance.mul(1e18).div(balance.sub(borrow)); } function estimateDeployedBalance() external override view returns (uint) { return totalDeposits(); } function rescueDeployedFunds(uint minReturnAmountAccepted, bool disableDeposits) external override onlyOwner { uint balanceBefore = depositToken.balanceOf(address(this)); _unrollDebt(); tokenDelegator.redeemUnderlying(tokenDelegator.balanceOfUnderlying(address(this))); uint balanceAfter = depositToken.balanceOf(address(this)); require(balanceAfter.sub(balanceBefore) >= minReturnAmountAccepted, "BenqiStrategyV1::rescueDeployedFunds"); emit Reinvest(totalDeposits(), totalSupply); if (DEPOSITS_ENABLED == true && disableDeposits == true) { updateDepositsEnabled(false); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "./lib/SafeMath.sol"; import "./lib/Ownable.sol"; import "./lib/Permissioned.sol"; import "./interfaces/IERC20.sol"; import "./YakERC20.sol"; import "./YakStrategyV2.sol"; /** * @notice YakStrategy should be inherited by new strategies */ abstract contract YakStrategyV2Payable is YakStrategyV2 { /** * @notice Deposit and deploy deposits tokens to the strategy using AVAX * @dev Must mint receipt tokens to `msg.sender` */ function deposit() external payable virtual; /** * @notice Deposit on behalf of another account using AVAX * @dev Must mint receipt tokens to `account` * @param account address to receive receipt tokens */ function depositFor(address account) external payable virtual; }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; interface IBenqiUnitroller { function enterMarkets(address[] memory cTokens) external returns (uint[] memory); function exitMarket(address cTokenAddress) external returns (uint); function mintAllowed(address cToken, address minter, uint mintAmount) external returns (uint); function redeemAllowed(address cToken, address redeemer, uint redeemTokens) external returns (uint); function borrowAllowed(address cToken, address borrower, uint borrowAmount) external returns (uint); function claimReward(uint8 rewardType, address holder) external; //reward type 0 is qi, 1 is avax function rewardAccrued(uint8 rewardType, address holder) external view returns (uint); function markets(address cTokenAddress) external view returns (bool, uint); function getClaimableRewards(uint rewardToken) external view returns (uint, uint); function rewardSupplyState(uint8 rewardType, address holder) external view returns (uint224 index, uint32 timestamp); function rewardBorrowState(uint8 rewardType, address holder) external view returns (uint224 index, uint32 timestamp); function rewardSupplierIndex(uint8 rewardType, address qiContractAddress, address holder) external view returns (uint supplierIndex); function rewardBorrowerIndex(uint8 rewardType, address qiContractAddress, address holder) external view returns (uint borrowerIndex); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "./IERC20.sol"; interface IBenqiAVAXDelegator is IERC20 { function exchangeRateStored() external view returns (uint256); function exchangeRateCurrent() external returns (uint); function mint() external payable; function redeem(uint256 redeemTokens) external returns (uint256); function redeemUnderlying(uint256 redeemAmount) external returns (uint256); function borrow(uint256 borrowAmount) external returns (uint256); function repayBorrow() external payable; function balanceOfUnderlying(address owner) external returns (uint256); function borrowBalanceCurrent(address owner) external returns (uint256); function borrowBalanceStored(address owner) external view returns (uint256); function getAccountSnapshot(address account) external view returns (uint256 error, uint256 balance, uint256 borrow, uint256 mantissa); function getCash() external returns (uint); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; interface IWAVAX { function deposit() external payable; function transfer(address to, uint value) external returns (bool); function balanceOf(address owner) external view returns (uint); function withdraw(uint) external; function approve(address to, uint value) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; interface IERC20 { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "./SafeMath.sol"; import "../interfaces/IPair.sol"; import "../interfaces/IWAVAX.sol"; library DexLibrary { using SafeMath for uint; bytes private constant zeroBytes = new bytes(0); IWAVAX private constant WAVAX = IWAVAX(0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7); /** * @notice Swap directly through a Pair * @param amountIn input amount * @param fromToken address * @param toToken address * @param pair Pair used for swap * @return output amount */ function swap(uint amountIn, address fromToken, address toToken, IPair pair) internal returns (uint) { (address token0,) = sortTokens(fromToken, toToken); (uint112 reserve0, uint112 reserve1,) = pair.getReserves(); if (token0 != fromToken) (reserve0, reserve1) = (reserve1, reserve0); uint amountOut1 = 0; uint amountOut2 = getAmountOut(amountIn, reserve0, reserve1); if (token0 != fromToken) (amountOut1, amountOut2) = (amountOut2, amountOut1); safeTransfer(fromToken, address(pair), amountIn); pair.swap(amountOut1, amountOut2, address(this), zeroBytes); return amountOut2 > amountOut1 ? amountOut2 : amountOut1; } function checkSwapPairCompatibility(IPair pair, address tokenA, address tokenB) internal pure returns (bool) { return (tokenA == pair.token0() || tokenA == pair.token1()) && (tokenB == pair.token0() || tokenB == pair.token1()) && tokenA != tokenB; } function estimateConversionThroughPair(uint amountIn, address fromToken, address toToken, IPair swapPair) internal view returns (uint) { (address token0,) = sortTokens(fromToken, toToken); (uint112 reserve0, uint112 reserve1,) = swapPair.getReserves(); if (token0 != fromToken) (reserve0, reserve1) = (reserve1, reserve0); return getAmountOut(amountIn, reserve0, reserve1); } /** * @notice Converts reward tokens to deposit tokens * @dev No price checks enforced * @param amount reward tokens * @return deposit tokens */ function convertRewardTokensToDepositTokens(uint amount, address rewardToken, address depositToken, IPair swapPairToken0, IPair swapPairToken1) internal returns (uint) { uint amountIn = amount.div(2); require(amountIn > 0, "DexLibrary::_convertRewardTokensToDepositTokens"); address token0 = IPair(depositToken).token0(); uint amountOutToken0 = amountIn; if (rewardToken != token0) { amountOutToken0 = DexLibrary.swap(amountIn, rewardToken, token0, swapPairToken0); } address token1 = IPair(depositToken).token1(); uint amountOutToken1 = amountIn; if (rewardToken != token1) { amountOutToken1 = DexLibrary.swap(amountIn, rewardToken, token1, swapPairToken1); } return DexLibrary.addLiquidity(depositToken, amountOutToken0, amountOutToken1); } /** * @notice Add liquidity directly through a Pair * @dev Checks adding the max of each token amount * @param depositToken address * @param maxAmountIn0 amount token0 * @param maxAmountIn1 amount token1 * @return liquidity tokens */ function addLiquidity(address depositToken, uint maxAmountIn0, uint maxAmountIn1) internal returns (uint) { (uint112 reserve0, uint112 reserve1,) = IPair(address(depositToken)).getReserves(); uint amountIn1 = _quoteLiquidityAmountOut(maxAmountIn0, reserve0, reserve1); if (amountIn1 > maxAmountIn1) { amountIn1 = maxAmountIn1; maxAmountIn0 = _quoteLiquidityAmountOut(maxAmountIn1, reserve1, reserve0); } safeTransfer(IPair(depositToken).token0(), depositToken, maxAmountIn0); safeTransfer(IPair(depositToken).token1(), depositToken, amountIn1); return IPair(depositToken).mint(address(this)); } /** * @notice Quote liquidity amount out * @param amountIn input tokens * @param reserve0 size of input asset reserve * @param reserve1 size of output asset reserve * @return liquidity tokens */ function _quoteLiquidityAmountOut(uint amountIn, uint reserve0, uint reserve1) private pure returns (uint) { return amountIn.mul(reserve1).div(reserve0); } /** * @notice Given two tokens, it'll return the tokens in the right order for the tokens pair * @dev TokenA must be different from TokenB, and both shouldn't be address(0), no validations * @param tokenA address * @param tokenB address * @return sorted tokens */ function sortTokens(address tokenA, address tokenB) internal pure returns (address, address) { return tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); } /** * @notice Given an input amount of an asset and pair reserves, returns maximum output amount of the other asset * @dev Assumes swap fee is 0.30% * @param amountIn input asset * @param reserveIn size of input asset reserve * @param reserveOut size of output asset reserve * @return maximum output amount */ function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint) { uint amountInWithFee = amountIn.mul(997); uint numerator = amountInWithFee.mul(reserveOut); uint denominator = reserveIn.mul(1000).add(amountInWithFee); return numerator.div(denominator); } /** * @notice Safely transfer using an anonymous ERC20 token * @dev Requires token to return true on transfer * @param token address * @param to recipient address * @param value amount */ function safeTransfer(address token, address to, uint256 value) internal { require(IERC20(token).transfer(to, value), "DexLibrary::TRANSFER_FROM_FAILED"); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @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]. */ abstract 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.7.0; // From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/Math.sol // Subject to the MIT license. /** * @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 addition of two unsigned integers, reverting with custom message on overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, errorMessage); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on underflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot underflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction underflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on underflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot underflow. */ 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 multiplication of two unsigned integers, reverting on overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b, string memory errorMessage) 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, errorMessage); 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) { // Solidity only automatically asserts when dividing by 0 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.7.0; import "./Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "./Ownable.sol"; import "./SafeMath.sol"; abstract contract Permissioned is Ownable { using SafeMath for uint; uint public numberOfAllowedDepositors; mapping(address => bool) public allowedDepositors; event AllowDepositor(address indexed account); event RemoveDepositor(address indexed account); modifier onlyAllowedDeposits() { if (numberOfAllowedDepositors > 0) { require(allowedDepositors[msg.sender] == true, "Permissioned::onlyAllowedDeposits, not allowed"); } _; } /** * @notice Add an allowed depositor * @param depositor address */ function allowDepositor(address depositor) external onlyOwner { require(allowedDepositors[depositor] == false, "Permissioned::allowDepositor"); allowedDepositors[depositor] = true; numberOfAllowedDepositors = numberOfAllowedDepositors.add(1); emit AllowDepositor(depositor); } /** * @notice Remove an allowed depositor * @param depositor address */ function removeDepositor(address depositor) external onlyOwner { require(numberOfAllowedDepositors > 0, "Permissioned::removeDepositor, no allowed depositors"); require(allowedDepositors[depositor] == true, "Permissioned::removeDepositor, not allowed"); allowedDepositors[depositor] = false; numberOfAllowedDepositors = numberOfAllowedDepositors.sub(1); emit RemoveDepositor(depositor); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; import "./lib/SafeMath.sol"; import "./interfaces/IERC20.sol"; abstract contract YakERC20 { using SafeMath for uint256; string public name = "Yield Yak"; string public symbol = "YRT"; uint8 public constant decimals = 18; uint256 public totalSupply; mapping (address => mapping (address => uint256)) internal allowances; mapping (address => uint256) internal balances; /// @dev keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)") bytes32 public constant DOMAIN_TYPEHASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f; /// @dev keccak256("1"); bytes32 public constant VERSION_HASH = 0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6; /// @dev keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; mapping(address => uint) public nonces; event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); constructor() {} /** * @notice Get the number of tokens `spender` is approved to spend on behalf of `account` * @param account The address of the account holding the funds * @param spender The address of the account spending the funds * @return The number of tokens approved */ function allowance(address account, address spender) external view returns (uint) { return allowances[account][spender]; } /** * @notice Approve `spender` to transfer up to `amount` from `src` * @dev This will overwrite the approval amount for `spender` * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve) * It is recommended to use increaseAllowance and decreaseAllowance instead * @param spender The address of the account which may transfer tokens * @param amount The number of tokens that are approved (2^256-1 means infinite) * @return Whether or not the approval succeeded */ function approve(address spender, uint256 amount) external returns (bool) { _approve(msg.sender, spender, amount); return true; } /** * @notice Get the number of tokens held by the `account` * @param account The address of the account to get the balance of * @return The number of tokens held */ function balanceOf(address account) external view returns (uint) { return balances[account]; } /** * @notice Transfer `amount` tokens from `msg.sender` to `dst` * @param dst The address of the destination account * @param amount The number of tokens to transfer * @return Whether or not the transfer succeeded */ function transfer(address dst, uint256 amount) external returns (bool) { _transferTokens(msg.sender, dst, amount); return true; } /** * @notice Transfer `amount` tokens from `src` to `dst` * @param src The address of the source account * @param dst The address of the destination account * @param amount The number of tokens to transfer * @return Whether or not the transfer succeeded */ function transferFrom(address src, address dst, uint256 amount) external returns (bool) { address spender = msg.sender; uint256 spenderAllowance = allowances[src][spender]; if (spender != src && spenderAllowance != uint256(-1)) { uint256 newAllowance = spenderAllowance.sub(amount, "transferFrom: transfer amount exceeds allowance"); allowances[src][spender] = newAllowance; emit Approval(src, spender, newAllowance); } _transferTokens(src, dst, amount); return true; } /** * @notice Approval implementation * @param owner The address of the account which owns tokens * @param spender The address of the account which may transfer tokens * @param amount The number of tokens that are approved (2^256-1 means infinite) */ function _approve(address owner, address spender, uint256 amount) internal { require(owner != address(0), "_approve::owner zero address"); require(spender != address(0), "_approve::spender zero address"); allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @notice Transfer implementation * @param from The address of the account which owns tokens * @param to The address of the account which is receiving tokens * @param value The number of tokens that are being transferred */ function _transferTokens(address from, address to, uint256 value) internal { require(to != address(0), "_transferTokens: cannot transfer to the zero address"); balances[from] = balances[from].sub(value, "_transferTokens: transfer exceeds from balance"); balances[to] = balances[to].add(value); emit Transfer(from, to, value); } function _mint(address to, uint256 value) internal { totalSupply = totalSupply.add(value); balances[to] = balances[to].add(value); emit Transfer(address(0), to, value); } function _burn(address from, uint256 value) internal { balances[from] = balances[from].sub(value, "_burn: burn amount exceeds from balance"); totalSupply = totalSupply.sub(value, "_burn: burn amount exceeds total supply"); emit Transfer(from, address(0), value); } /** * @notice Triggers an approval from owner to spender * @param owner The address to approve from * @param spender The address to be approved * @param value The number of tokens that are approved (2^256-1 means infinite) * @param deadline The time at which to expire the signature * @param v The recovery byte of the signature * @param r Half of the ECDSA signature pair * @param s Half of the ECDSA signature pair */ function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external { require(deadline >= block.timestamp, "permit::expired"); bytes32 encodeData = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)); _validateSignedData(owner, encodeData, v, r, s); _approve(owner, spender, value); } /** * @notice Recovers address from signed data and validates the signature * @param signer Address that signed the data * @param encodeData Data signed by the address * @param v The recovery byte of the signature * @param r Half of the ECDSA signature pair * @param s Half of the ECDSA signature pair */ function _validateSignedData(address signer, bytes32 encodeData, uint8 v, bytes32 r, bytes32 s) internal view { bytes32 digest = keccak256( abi.encodePacked( "\x19\x01", getDomainSeparator(), encodeData ) ); address recoveredAddress = ecrecover(digest, v, r, s); // Explicitly disallow authorizations for address(0) as ecrecover returns address(0) on malformed messages require(recoveredAddress != address(0) && recoveredAddress == signer, "Arch::validateSig: invalid signature"); } /** * @notice EIP-712 Domain separator * @return Separator */ function getDomainSeparator() public view returns (bytes32) { return keccak256( abi.encode( DOMAIN_TYPEHASH, keccak256(bytes(name)), VERSION_HASH, _getChainId(), address(this) ) ); } /** * @notice Current id of the chain where this contract is deployed * @return Chain id */ function _getChainId() internal pure returns (uint) { uint256 chainId; assembly { chainId := chainid() } return chainId; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "./lib/SafeMath.sol"; import "./lib/Ownable.sol"; import "./lib/Permissioned.sol"; import "./interfaces/IERC20.sol"; import "./YakERC20.sol"; /** * @notice YakStrategy should be inherited by new strategies */ abstract contract YakStrategyV2 is YakERC20, Ownable, Permissioned { using SafeMath for uint; IERC20 public depositToken; IERC20 public rewardToken; address public devAddr; uint public MIN_TOKENS_TO_REINVEST; uint public MAX_TOKENS_TO_DEPOSIT_WITHOUT_REINVEST; bool public DEPOSITS_ENABLED; uint public REINVEST_REWARD_BIPS; uint public ADMIN_FEE_BIPS; uint public DEV_FEE_BIPS; uint constant internal BIPS_DIVISOR = 10000; uint constant internal MAX_UINT = uint(-1); event Deposit(address indexed account, uint amount); event Withdraw(address indexed account, uint amount); event Reinvest(uint newTotalDeposits, uint newTotalSupply); event Recovered(address token, uint amount); event UpdateAdminFee(uint oldValue, uint newValue); event UpdateDevFee(uint oldValue, uint newValue); event UpdateReinvestReward(uint oldValue, uint newValue); event UpdateMinTokensToReinvest(uint oldValue, uint newValue); event UpdateMaxTokensToDepositWithoutReinvest(uint oldValue, uint newValue); event UpdateDevAddr(address oldValue, address newValue); event DepositsEnabled(bool newValue); /** * @notice Throws if called by smart contract */ modifier onlyEOA() { require(tx.origin == msg.sender, "YakStrategy::onlyEOA"); _; } /** * @notice Only called by dev */ modifier onlyDev() { require(msg.sender == devAddr, "YakStrategy::onlyDev"); _; } /** * @notice Approve tokens for use in Strategy * @dev Should use modifier `onlyOwner` to avoid griefing */ function setAllowances() public virtual; /** * @notice Revoke token allowance * @param token address * @param spender address */ function revokeAllowance(address token, address spender) external onlyOwner { require(IERC20(token).approve(spender, 0)); } /** * @notice Deposit and deploy deposits tokens to the strategy * @dev Must mint receipt tokens to `msg.sender` * @param amount deposit tokens */ function deposit(uint amount) external virtual; /** * @notice Deposit using Permit * @dev Should revert for tokens without Permit * @param amount Amount of tokens to deposit * @param deadline The time at which to expire the signature * @param v The recovery byte of the signature * @param r Half of the ECDSA signature pair * @param s Half of the ECDSA signature pair */ function depositWithPermit(uint amount, uint deadline, uint8 v, bytes32 r, bytes32 s) external virtual; /** * @notice Deposit on behalf of another account * @dev Must mint receipt tokens to `account` * @param account address to receive receipt tokens * @param amount deposit tokens */ function depositFor(address account, uint amount) external virtual; /** * @notice Redeem receipt tokens for deposit tokens * @param amount receipt tokens */ function withdraw(uint amount) external virtual; /** * @notice Reinvest reward tokens into deposit tokens */ function reinvest() external virtual; /** * @notice Estimate reinvest reward * @return reward tokens */ function estimateReinvestReward() external view returns (uint) { uint unclaimedRewards = checkReward(); if (unclaimedRewards >= MIN_TOKENS_TO_REINVEST) { return unclaimedRewards.mul(REINVEST_REWARD_BIPS).div(BIPS_DIVISOR); } return 0; } /** * @notice Reward tokens avialable to strategy, including balance * @return reward tokens */ function checkReward() public virtual view returns (uint); /** * @notice Estimated deposit token balance deployed by strategy, excluding balance * @return deposit tokens */ function estimateDeployedBalance() external virtual view returns (uint); /** * @notice Rescue all available deployed deposit tokens back to Strategy * @param minReturnAmountAccepted min deposit tokens to receive * @param disableDeposits bool */ function rescueDeployedFunds(uint minReturnAmountAccepted, bool disableDeposits) external virtual; /** * @notice This function returns a snapshot of last available quotes * @return total deposits available on the contract */ function totalDeposits() public virtual view returns (uint); /** * @notice Calculate receipt tokens for a given amount of deposit tokens * @dev If contract is empty, use 1:1 ratio * @dev Could return zero shares for very low amounts of deposit tokens * @param amount deposit tokens * @return receipt tokens */ function getSharesForDepositTokens(uint amount) public view returns (uint) { if (totalSupply.mul(totalDeposits()) == 0) { return amount; } return amount.mul(totalSupply).div(totalDeposits()); } /** * @notice Calculate deposit tokens for a given amount of receipt tokens * @param amount receipt tokens * @return deposit tokens */ function getDepositTokensForShares(uint amount) public view returns (uint) { if (totalSupply.mul(totalDeposits()) == 0) { return 0; } return amount.mul(totalDeposits()).div(totalSupply); } /** * @notice Update reinvest min threshold * @param newValue threshold */ function updateMinTokensToReinvest(uint newValue) public onlyOwner { emit UpdateMinTokensToReinvest(MIN_TOKENS_TO_REINVEST, newValue); MIN_TOKENS_TO_REINVEST = newValue; } /** * @notice Update reinvest max threshold before a deposit * @param newValue threshold */ function updateMaxTokensToDepositWithoutReinvest(uint newValue) public onlyOwner { emit UpdateMaxTokensToDepositWithoutReinvest(MAX_TOKENS_TO_DEPOSIT_WITHOUT_REINVEST, newValue); MAX_TOKENS_TO_DEPOSIT_WITHOUT_REINVEST = newValue; } /** * @notice Update developer fee * @param newValue fee in BIPS */ function updateDevFee(uint newValue) public onlyOwner { require(newValue.add(ADMIN_FEE_BIPS).add(REINVEST_REWARD_BIPS) <= BIPS_DIVISOR); emit UpdateDevFee(DEV_FEE_BIPS, newValue); DEV_FEE_BIPS = newValue; } /** * @notice Update admin fee * @param newValue fee in BIPS */ function updateAdminFee(uint newValue) public onlyOwner { require(newValue.add(DEV_FEE_BIPS).add(REINVEST_REWARD_BIPS) <= BIPS_DIVISOR); emit UpdateAdminFee(ADMIN_FEE_BIPS, newValue); ADMIN_FEE_BIPS = newValue; } /** * @notice Update reinvest reward * @param newValue fee in BIPS */ function updateReinvestReward(uint newValue) public onlyOwner { require(newValue.add(ADMIN_FEE_BIPS).add(DEV_FEE_BIPS) <= BIPS_DIVISOR); emit UpdateReinvestReward(REINVEST_REWARD_BIPS, newValue); REINVEST_REWARD_BIPS = newValue; } /** * @notice Enable/disable deposits * @param newValue bool */ function updateDepositsEnabled(bool newValue) public onlyOwner { require(DEPOSITS_ENABLED != newValue); DEPOSITS_ENABLED = newValue; emit DepositsEnabled(newValue); } /** * @notice Update devAddr * @param newValue address */ function updateDevAddr(address newValue) public onlyDev { emit UpdateDevAddr(devAddr, newValue); devAddr = newValue; } /** * @notice Recover ERC20 from contract * @param tokenAddress token address * @param tokenAmount amount to recover */ function recoverERC20(address tokenAddress, uint tokenAmount) external onlyOwner { require(tokenAmount > 0); require(IERC20(tokenAddress).transfer(msg.sender, tokenAmount)); emit Recovered(tokenAddress, tokenAmount); } /** * @notice Recover AVAX from contract * @param amount amount */ function recoverAVAX(uint amount) external onlyOwner { require(amount > 0); msg.sender.transfer(amount); emit Recovered(address(0), amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "./IERC20.sol"; interface IPair is IERC20 { function token0() external pure returns (address); function token1() external pure returns (address); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function mint(address to) external returns (uint liquidity); function sync() external; }
{ "optimizer": { "enabled": true, "runs": 999 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"address","name":"_rewardController","type":"address"},{"internalType":"address","name":"_tokenDelegator","type":"address"},{"internalType":"address","name":"_rewardToken0","type":"address"},{"internalType":"address","name":"_swapPairToken0","type":"address"},{"internalType":"address","name":"_timelock","type":"address"},{"internalType":"uint256","name":"_minMinting","type":"uint256"},{"internalType":"uint256","name":"_leverageLevel","type":"uint256"},{"internalType":"uint256","name":"_leverageBips","type":"uint256"},{"internalType":"uint256","name":"_minTokensToReinvest","type":"uint256"},{"internalType":"uint256","name":"_adminFeeBips","type":"uint256"},{"internalType":"uint256","name":"_devFeeBips","type":"uint256"},{"internalType":"uint256","name":"_reinvestRewardBips","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"AllowDepositor","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"newValue","type":"bool"}],"name":"DepositsEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTotalDeposits","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTotalSupply","type":"uint256"}],"name":"Reinvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"RemoveDepositor","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdateAdminFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"UpdateDevAddr","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdateDevFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdateMaxTokensToDepositWithoutReinvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdateMinTokensToReinvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdateReinvestReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"ADMIN_FEE_BIPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSITS_ENABLED","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEV_FEE_BIPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS_TO_DEPOSIT_WITHOUT_REINVEST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_TOKENS_TO_REINVEST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REINVEST_REWARD_BIPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"depositor","type":"address"}],"name":"allowDepositor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowedDepositors","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"depositFor","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"depositToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"depositWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"devAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"estimateDeployedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"estimateReinvestReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getActualLeverage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getDepositTokensForShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDomainSeparator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getSharesForDepositTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numberOfAllowedDepositors","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverAVAX","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reinvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"depositor","type":"address"}],"name":"removeDepositor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minReturnAmountAccepted","type":"uint256"},{"internalType":"bool","name":"disableDeposits","type":"bool"}],"name":"rescueDeployedFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"revokeAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"setAllowances","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateAdminFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newValue","type":"bool"}],"name":"updateDepositsEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newValue","type":"address"}],"name":"updateDevAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateDevFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_leverageLevel","type":"uint256"},{"internalType":"uint256","name":"_leverageBips","type":"uint256"}],"name":"updateLeverage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateMaxTokensToDepositWithoutReinvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateMinTokensToReinvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateReinvestReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60c060405260096080819052685969656c642059616b60b81b60a09081526200002c916000919062000e73565b506040805180820190915260038082526216549560ea1b6020909201918252620000599160019162000e73565b503480156200006757600080fd5b5060405162005ccf38038062005ccf83398181016040526101a08110156200008e57600080fd5b8101908080516040519392919084640100000000821115620000af57600080fd5b908301906020820185811115620000c557600080fd5b8251640100000000811182820188101715620000e057600080fd5b82525081516020918201929091019080838360005b838110156200010f578181015183820152602001620000f5565b50505050905090810190601f1680156200013d5780820380516001836020036101000a031916815260200191505b5060409081526020820151908201516060830151608084015160a085015160c086015160e08701516101008801516101208901516101408a01516101608b0151610180909b0151999c50979a509598949793969295919490939192916000620001a56200033d565b600680546001600160a01b0319166001600160a01b0383169081179091556040519192509060009060008051602062005c88833981519152908290a35060016012819055508c600090805190602001906200020292919062000e73565b50600980546001600160a01b03199081169091556013805482166001600160a01b038f8116919091179091556014805483168e8316179055601580548316918d16919091179055600a805473b31f66aa3c1e785363f0875a1b74e27b85fd66c7921691909117905560198790556200027b868662000341565b600b80546001600160a01b03191633179055620002976200034c565b620002a289620004f9565b620002ac62000801565b620002b784620008f0565b620002c2836200099a565b620002cd8262000a8a565b620002d88162000b66565b620002e4600162000c42565b620002ef8862000d08565b604080516000808252602082015281517fc7606d21ac05cd309191543e409f0845c016120563783d70e4f41419dc0ef234929181900390910190a15050505050505050505050505062000f0f565b3390565b601791909155601855565b60408051600180825281830190925260609160208083019080368337505060145482519293506001600160a01b0316918391506000906200038957fe5b6001600160a01b03928316602091820292909201810191909152601354604051631853304760e31b815260048101838152855160248301528551929094169363c299823893869391928392604490910191858101910280838360005b83811015620003ff578181015183820152602001620003e5565b5050505090500192505050600060405180830381600087803b1580156200042557600080fd5b505af11580156200043a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156200046457600080fd5b81019080805160405193929190846401000000008211156200048557600080fd5b9083019060208201858111156200049b57600080fd5b8251866020820283011164010000000082111715620004b957600080fd5b82525081516020918201928201910280838360005b83811015620004e8578181015183820152602001620004ce565b505050509050016040525050505050565b6001600160a01b038116620005405760405162461bcd60e51b815260040180806020018281038252602981526020018062005c3f6029913960400191505060405180910390fd5b806001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156200057a57600080fd5b505afa1580156200058f573d6000803e3d6000fd5b505050506040513d6020811015620005a657600080fd5b50516015546001600160a01b03908116911614806200063a5750806001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015620005fa57600080fd5b505afa1580156200060f573d6000803e3d6000fd5b505050506040513d60208110156200062657600080fd5b50516015546001600160a01b039081169116145b620006775760405162461bcd60e51b815260040180806020018281038252602781526020018062005ca86027913960400191505060405180910390fd5b806001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015620006b157600080fd5b505afa158015620006c6573d6000803e3d6000fd5b505050506040513d6020811015620006dd57600080fd5b50516001600160a01b031673b31f66aa3c1e785363f0875a1b74e27b85fd66c714806200078d5750806001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156200073f57600080fd5b505afa15801562000754573d6000803e3d6000fd5b505050506040513d60208110156200076b57600080fd5b50516001600160a01b031673b31f66aa3c1e785363f0875a1b74e27b85fd66c7145b620007df576040805162461bcd60e51b815260206004820181905260248201527f537761702070616972203020646f6573206e6f74206d61746368205741564158604482015290519081900360640190fd5b601680546001600160a01b0319166001600160a01b0392909216919091179055565b6200080b6200033d565b6001600160a01b03166200081e62000e02565b6001600160a01b03161462000869576040805162461bcd60e51b8152602060048201819052602482015260008051602062005c68833981519152604482015290519081900360640190fd5b6014546040805163095ea7b360e01b81526001600160a01b039092166004830181905260001960248401529051909163095ea7b39160448083019260209291908290030181600087803b158015620008c057600080fd5b505af1158015620008d5573d6000803e3d6000fd5b505050506040513d6020811015620008ec57600080fd5b5050565b620008fa6200033d565b6001600160a01b03166200090d62000e02565b6001600160a01b03161462000958576040805162461bcd60e51b8152602060048201819052602482015260008051602062005c68833981519152604482015290519081900360640190fd5b600c54604080519182526020820183905280517f481f79ac3a523b6d6db3c5a720e190e986d1cc1b41adcdf50f9caef8499011009281900390910190a1600c55565b620009a46200033d565b6001600160a01b0316620009b762000e02565b6001600160a01b03161462000a02576040805162461bcd60e51b8152602060048201819052602482015260008051602062005c68833981519152604482015290519081900360640190fd5b61271062000a3c600f5462000a286011548562000e1160201b62002a561790919060201c565b62000e1160201b62002a561790919060201c565b111562000a4857600080fd5b601054604080519182526020820183905280517f3cc372f330f95ac9540626dc8a25f5bf21ba607215a5d58304cb804d446f104a9281900390910190a1601055565b62000a946200033d565b6001600160a01b031662000aa762000e02565b6001600160a01b03161462000af2576040805162461bcd60e51b8152602060048201819052602482015260008051602062005c68833981519152604482015290519081900360640190fd5b61271062000b18600f5462000a286010548562000e1160201b62002a561790919060201c565b111562000b2457600080fd5b601154604080519182526020820183905280517f2a42303d002f0ba6cfe8259c91d4684443fb0b3de286ba74991175d6517261319281900390910190a1601155565b62000b706200033d565b6001600160a01b031662000b8362000e02565b6001600160a01b03161462000bce576040805162461bcd60e51b8152602060048201819052602482015260008051602062005c68833981519152604482015290519081900360640190fd5b61271062000bf460115462000a286010548562000e1160201b62002a561790919060201c565b111562000c0057600080fd5b600f54604080519182526020820183905280517fe7f97d51d307dc44045597c9978bec0f842e6bb40d19b9444084cfa30d9ed4f29281900390910190a1600f55565b62000c4c6200033d565b6001600160a01b031662000c5f62000e02565b6001600160a01b03161462000caa576040805162461bcd60e51b8152602060048201819052602482015260008051602062005c68833981519152604482015290519081900360640190fd5b600e5460ff161515811515141562000cc157600080fd5b600e805482151560ff19909116811790915560408051918252517f7b014ed3854e7f5cb0218d58b3c6ae7d53a68bb0af2f67bfb029ea42c38a7e859181900360200190a150565b62000d126200033d565b6001600160a01b031662000d2562000e02565b6001600160a01b03161462000d70576040805162461bcd60e51b8152602060048201819052602482015260008051602062005c68833981519152604482015290519081900360640190fd5b6001600160a01b03811662000db75760405162461bcd60e51b815260040180806020018281038252602681526020018062005c196026913960400191505060405180910390fd5b6006546040516001600160a01b0380841692169060008051602062005c8883398151915290600090a3600680546001600160a01b0319166001600160a01b0392909216919091179055565b6006546001600160a01b031690565b60008282018381101562000e6c576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1062000eb657805160ff191683800117855562000ee6565b8280016001018555821562000ee6579182015b8281111562000ee657825182559160200191906001019062000ec9565b5062000ef492915062000ef8565b5090565b5b8082111562000ef4576000815560010162000ef9565b614cfa8062000f1f6000396000f3fe6080604052600436106103855760003560e01c80639291d563116101d1578063c89039c511610102578063dd62ed3e116100a0578063ed24911d1161006f578063ed24911d14610ca4578063f2fde38b14610cb9578063f7c618c114610cec578063fdb5a03e14610d0157610408565b8063dd62ed3e14610beb578063dd8ce4d614610c26578063e21ac82514610c50578063eab89a5a14610c7a57610408565b8063d505accf116100dc578063d505accf14610b4e578063da09c72c14610bac578063db8dd95c14610bc1578063dbd9a4d414610bd657610408565b8063c89039c514610b07578063cff1b6ef14610b1c578063d0e30db014610b4657610408565b8063aa67c9191161016f578063b6b55f2511610149578063b6b55f2514610a9e578063b9e57b8014610ac8578063bd079f5514610add578063c4b24a4614610af257610408565b8063aa67c91914610a31578063ac0d31ff14610a57578063b52a321f14610a8957610408565b80639e4e7318116101ab5780639e4e731814610989578063a24159d31461099e578063a8ae2b7c146109ce578063a9059cbb146109f857610408565b80639291d5631461091757806395d89b411461094a57806399729ec11461095f57610408565b80634bebd1e7116102b65780637ae26773116102545780638980f11f116102235780638980f11f146108655780638aff733d1461089e5780638b73e606146108b35780638da5cb5b146108e657610408565b80637ae26773146107b85780637d882097146107f35780637ecebe0014610808578063818372301461083b57610408565b80635ea682ea116102905780635ea682ea1461074657806370a082311461075b578063715018a61461078e578063789139bc146107a357610408565b80634bebd1e7146106bd5780634e77ace5146106f05780634ebb79161461071c57610408565b80632e1a7d4d11610323578063313ce567116102fd578063313ce567146106055780633bdc6e7214610630578063483c2ef0146106455780634a970be71461067857610408565b80632e1a7d4d1461058d5780632f4f21e2146105b757806330adf81f146105f057610408565b80630f23475d1161035f5780630f23475d1461050b57806318160ddd1461052057806320606b701461053557806323b872dd1461054a57610408565b806306fdde031461040d5780630767711114610497578063095ea7b3146104be57610408565b36610408576013546001600160a01b03163314806103b657503373b31f66aa3c1e785363f0875a1b74e27b85fd66c7145b806103cb57506014546001600160a01b031633145b6104065760405162461bcd60e51b81526004018080602001828103825260258152602001806149ab6025913960400191505060405180910390fd5b005b600080fd5b34801561041957600080fd5b50610422610d16565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561045c578181015183820152602001610444565b50505050905090810190601f1680156104895780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156104a357600080fd5b506104ac610da4565b60408051918252519081900360200190f35b3480156104ca57600080fd5b506104f7600480360360408110156104e157600080fd5b506001600160a01b038135169060200135610daa565b604080519115158252519081900360200190f35b34801561051757600080fd5b506104ac610dc1565b34801561052c57600080fd5b506104ac610dd1565b34801561054157600080fd5b506104ac610dd7565b34801561055657600080fd5b506104f76004803603606081101561056d57600080fd5b506001600160a01b03813581169160208101359091169060400135610dfb565b34801561059957600080fd5b50610406600480360360208110156105b057600080fd5b5035610edd565b3480156105c357600080fd5b50610406600480360360408110156105da57600080fd5b506001600160a01b038135169060200135610408565b3480156105fc57600080fd5b506104ac61107d565b34801561061157600080fd5b5061061a6110a1565b6040805160ff9092168252519081900360200190f35b34801561063c57600080fd5b506104ac6110a6565b34801561065157600080fd5b506104f76004803603602081101561066857600080fd5b50356001600160a01b03166110ac565b34801561068457600080fd5b50610406600480360360a081101561069b57600080fd5b5080359060208101359060ff6040820135169060608101359060800135610408565b3480156106c957600080fd5b50610406600480360360208110156106e057600080fd5b50356001600160a01b03166110c1565b3480156106fc57600080fd5b506104066004803603602081101561071357600080fd5b503515156111fd565b34801561072857600080fd5b506104066004803603602081101561073f57600080fd5b50356112bc565b34801561075257600080fd5b506104ac611398565b34801561076757600080fd5b506104ac6004803603602081101561077e57600080fd5b50356001600160a01b031661139e565b34801561079a57600080fd5b506104066113bd565b3480156107af57600080fd5b506104ac611476565b3480156107c457600080fd5b50610406600480360360408110156107db57600080fd5b506001600160a01b038135811691602001351661147c565b3480156107ff57600080fd5b506104ac61156f565b34801561081457600080fd5b506104ac6004803603602081101561082b57600080fd5b50356001600160a01b031661162b565b34801561084757600080fd5b506104066004803603602081101561085e57600080fd5b503561163d565b34801561087157600080fd5b506104066004803603604081101561088857600080fd5b506001600160a01b0381351690602001356116e1565b3480156108aa57600080fd5b506104ac611835565b3480156108bf57600080fd5b50610406600480360360208110156108d657600080fd5b50356001600160a01b031661183b565b3480156108f257600080fd5b506108fb6119a2565b604080516001600160a01b039092168252519081900360200190f35b34801561092357600080fd5b506104066004803603602081101561093a57600080fd5b50356001600160a01b03166119b1565b34801561095657600080fd5b50610422611a87565b34801561096b57600080fd5b506104066004803603602081101561098257600080fd5b5035611ae1565b34801561099557600080fd5b506104ac611bb4565b3480156109aa57600080fd5b50610406600480360360408110156109c157600080fd5b5080359060200135611bd8565b3480156109da57600080fd5b50610406600480360360208110156109f157600080fd5b5035611cd9565b348015610a0457600080fd5b506104f760048036036040811015610a1b57600080fd5b506001600160a01b038135169060200135611da6565b61040660048036036020811015610a4757600080fd5b50356001600160a01b0316611db3565b348015610a6357600080fd5b5061040660048036036040811015610a7a57600080fd5b50803590602001351515611e22565b348015610a9557600080fd5b506104f761213c565b348015610aaa57600080fd5b5061040660048036036020811015610ac157600080fd5b5035610408565b348015610ad457600080fd5b506104ac612145565b348015610ae957600080fd5b506104ac612186565b348015610afe57600080fd5b506104ac61218c565b348015610b1357600080fd5b506108fb612197565b348015610b2857600080fd5b5061040660048036036020811015610b3f57600080fd5b50356121a6565b610406612273565b348015610b5a57600080fd5b50610406600480360360e0811015610b7157600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c001356122e1565b348015610bb857600080fd5b506108fb6123e1565b348015610bcd57600080fd5b506104ac6123f0565b348015610be257600080fd5b506104066124c6565b348015610bf757600080fd5b506104ac60048036036040811015610c0e57600080fd5b506001600160a01b03813581169160200135166125c1565b348015610c3257600080fd5b506104ac60048036036020811015610c4957600080fd5b50356125ec565b348015610c5c57600080fd5b5061040660048036036020811015610c7357600080fd5b5035612626565b348015610c8657600080fd5b506104ac60048036036020811015610c9d57600080fd5b50356126ca565b348015610cb057600080fd5b506104ac6126fb565b348015610cc557600080fd5b5061040660048036036020811015610cdc57600080fd5b50356001600160a01b0316612808565b348015610cf857600080fd5b506108fb612918565b348015610d0d57600080fd5b50610406612927565b6000805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610d9c5780601f10610d7157610100808354040283529160200191610d9c565b820191906000526020600020905b815481529060010190602001808311610d7f57829003601f168201915b505050505081565b60105481565b6000610db7338484612ab7565b5060015b92915050565b6000610dcb61156f565b90505b90565b60025481565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6001600160a01b038316600081815260036020908152604080832033808552925282205491929091908214801590610e3557506000198114155b15610ec6576000610e61856040518060600160405280602f8152602001614bfb602f9139849190612bcf565b6001600160a01b0380891660008181526003602090815260408083209489168084529482529182902085905581518581529151949550929391927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92592918290030190a3505b610ed1868686612c66565b50600195945050505050565b60026012541415610f35576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026012556019548111610f7a5760405162461bcd60e51b81526004018080602001828103825260278152602001806149f66027913960400191505060405180910390fd5b6000610f9a600254610f9484610f8e612d73565b90612e81565b90612eda565b9050801561107457610fac3383612f1c565b610fb581612ff1565b604051600090339083908381818185875af1925050503d8060008114610ff7576040519150601f19603f3d011682016040523d82523d6000602084013e610ffc565b606091505b505090508061103c5760405162461bcd60e51b8152600401808060200182810382526029815260200180614b156029913960400191505060405180910390fd5b60408051838152905133917f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364919081900360200190a2505b50506001601255565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b60075481565b60086020526000908152604090205460ff1681565b6110c9613150565b6001600160a01b03166110da6119a2565b6001600160a01b031614611123576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526008602052604090205460ff1615611191576040805162461bcd60e51b815260206004820152601c60248201527f5065726d697373696f6e65643a3a616c6c6f774465706f7369746f7200000000604482015290519081900360640190fd5b6001600160a01b0381166000908152600860205260409020805460ff191660019081179091556007546111c391612a56565b6007556040516001600160a01b038216907fc0a1035c16faf8d1304056d92c00edf028f87e62b8235a938f00af9e3c0312c590600090a250565b611205613150565b6001600160a01b03166112166119a2565b6001600160a01b03161461125f576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b600e5460ff161515811515141561127557600080fd5b600e805482151560ff19909116811790915560408051918252517f7b014ed3854e7f5cb0218d58b3c6ae7d53a68bb0af2f67bfb029ea42c38a7e859181900360200190a150565b6112c4613150565b6001600160a01b03166112d56119a2565b6001600160a01b03161461131e576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b6000811161132b57600080fd5b604051339082156108fc029083906000818181858888f19350505050158015611358573d6000803e3d6000fd5b5060408051600081526020810183905281517f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa28929181900390910190a150565b60115481565b6001600160a01b0381166000908152600460205260409020545b919050565b6113c5613150565b6001600160a01b03166113d66119a2565b6001600160a01b03161461141f576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b6006546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36006805473ffffffffffffffffffffffffffffffffffffffff19169055565b600d5481565b611484613150565b6001600160a01b03166114956119a2565b6001600160a01b0316146114de576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b816001600160a01b031663095ea7b38260006040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561153657600080fd5b505af115801561154a573d6000803e3d6000fd5b505050506040513d602081101561156057600080fd5b505161156b57600080fd5b5050565b601454604080516361bfb47160e11b815230600482015290516000928392839283926001600160a01b03169163c37f68e2916024808301926080929190829003018186803b1580156115c057600080fd5b505afa1580156115d4573d6000803e3d6000fd5b505050506040513d60808110156115ea57600080fd5b506020810151604082015160609092015190945090925090506116238261161d670de0b6b3a7640000610f948786612e81565b90613154565b935050505090565b60056020526000908152604090205481565b611645613150565b6001600160a01b03166116566119a2565b6001600160a01b03161461169f576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b600c54604080519182526020820183905280517f481f79ac3a523b6d6db3c5a720e190e986d1cc1b41adcdf50f9caef8499011009281900390910190a1600c55565b6116e9613150565b6001600160a01b03166116fa6119a2565b6001600160a01b031614611743576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b6000811161175057600080fd5b604080517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905290516001600160a01b0384169163a9059cbb9160448083019260209291908290030181600087803b1580156117b857600080fd5b505af11580156117cc573d6000803e3d6000fd5b505050506040513d60208110156117e257600080fd5b50516117ed57600080fd5b604080516001600160a01b03841681526020810183905281517f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa28929181900390910190a15050565b600f5481565b611843613150565b6001600160a01b03166118546119a2565b6001600160a01b03161461189d576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b6000600754116118de5760405162461bcd60e51b8152600401808060200182810382526034815260200180614a4b6034913960400191505060405180910390fd5b6001600160a01b03811660009081526008602052604090205460ff16151560011461193a5760405162461bcd60e51b815260040180806020018281038252602a815260200180614aa3602a913960400191505060405180910390fd5b6001600160a01b0381166000908152600860205260409020805460ff19169055600754611968906001613154565b6007556040516001600160a01b038216907f0e86f6608b536e5339a25b65ff531f5ea91e1313d056ecd4752b35cbd16137d490600090a250565b6006546001600160a01b031690565b600b546001600160a01b03163314611a10576040805162461bcd60e51b815260206004820152601460248201527f59616b53747261746567793a3a6f6e6c79446576000000000000000000000000604482015290519081900360640190fd5b600b54604080516001600160a01b039283168152918316602083015280517fa8e91499ed37682f43cffb045fcc7d379a91e8c9a14e6321877ee34dee564c009281900390910190a1600b805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60018054604080516020600284861615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610d9c5780601f10610d7157610100808354040283529160200191610d9c565b611ae9613150565b6001600160a01b0316611afa6119a2565b6001600160a01b031614611b43576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b612710611b67600f54611b6160105485612a5690919063ffffffff16565b90612a56565b1115611b7257600080fd5b601154604080519182526020820183905280517f2a42303d002f0ba6cfe8259c91d4684443fb0b3de286ba74991175d6517261319281900390910190a1601155565b7fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc681565b600b546001600160a01b03163314611c37576040805162461bcd60e51b815260206004820152601460248201527f59616b53747261746567793a3a6f6e6c79446576000000000000000000000000604482015290519081900360640190fd5b611c418282613196565b611c496131a1565b60145460408051633af9e66960e01b815230600482015290516000926001600160a01b031691633af9e66991602480830192602092919082900301818787803b158015611c9557600080fd5b505af1158015611ca9573d6000803e3d6000fd5b505050506040513d6020811015611cbf57600080fd5b505190508015611cd457611cd4816000613410565b505050565b611ce1613150565b6001600160a01b0316611cf26119a2565b6001600160a01b031614611d3b576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b612710611d59601154611b6160105485612a5690919063ffffffff16565b1115611d6457600080fd5b600f54604080519182526020820183905280517fe7f97d51d307dc44045597c9978bec0f842e6bb40d19b9444084cfa30d9ed4f29281900390910190a1600f55565b6000610db7338484612c66565b60026012541415611e0b576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002601255611e1a813461365b565b506001601255565b611e2a613150565b6001600160a01b0316611e3b6119a2565b6001600160a01b031614611e84576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b600954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611ecf57600080fd5b505afa158015611ee3573d6000803e3d6000fd5b505050506040513d6020811015611ef957600080fd5b50519050611f056131a1565b60145460408051633af9e66960e01b815230600482015290516001600160a01b039092169163852a12e3918391633af9e669916024808201926020929091908290030181600087803b158015611f5a57600080fd5b505af1158015611f6e573d6000803e3d6000fd5b505050506040513d6020811015611f8457600080fd5b5051604080517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092525160248083019260209291908290030181600087803b158015611fdd57600080fd5b505af1158015611ff1573d6000803e3d6000fd5b505050506040513d602081101561200757600080fd5b5050600954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561205457600080fd5b505afa158015612068573d6000803e3d6000fd5b505050506040513d602081101561207e57600080fd5b505190508361208d8284613154565b10156120ca5760405162461bcd60e51b8152600401808060200182810382526024815260200180614bd76024913960400191505060405180910390fd5b7fc7606d21ac05cd309191543e409f0845c016120563783d70e4f41419dc0ef2346120f361156f565b6002546040805192835260208301919091528051918290030190a1600e5460ff161515600114801561212757506001831515145b156121365761213660006111fd565b50505050565b600e5460ff1681565b60008061215061218c565b9050600c54811061217e57612176612710610f94600f5484612e8190919063ffffffff16565b915050610dce565b600091505090565b600c5481565b6000806116236137e4565b6009546001600160a01b031681565b6121ae613150565b6001600160a01b03166121bf6119a2565b6001600160a01b031614612208576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b612710612226600f54611b6160115485612a5690919063ffffffff16565b111561223157600080fd5b601054604080519182526020820183905280517f3cc372f330f95ac9540626dc8a25f5bf21ba607215a5d58304cb804d446f104a9281900390910190a1601055565b600260125414156122cb576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026012556122da333461365b565b6001601255565b42841015612336576040805162461bcd60e51b815260206004820152600f60248201527f7065726d69743a3a657870697265640000000000000000000000000000000000604482015290519081900360640190fd5b6001600160a01b0380881660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938a1660608401526080830189905260a083019390935260c08083018890528151808403909101815260e0909201905280519101206123cc888286868661385a565b6123d7888888612ab7565b5050505050505050565b600b546001600160a01b031681565b601454604080516361bfb47160e11b815230600482015290516000928392839283926001600160a01b03169163c37f68e2916024808301926080929190829003018186803b15801561244157600080fd5b505afa158015612455573d6000803e3d6000fd5b505050506040513d608081101561246b57600080fd5b50602081015160408201516060909201519094509092509050600061249c670de0b6b3a7640000610f948685612e81565b90506124bd6124ab8285613154565b610f9483670de0b6b3a7640000612e81565b94505050505090565b6124ce613150565b6001600160a01b03166124df6119a2565b6001600160a01b031614612528576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b601454604080517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b039092166004830181905260001960248401529051909163095ea7b39160448083019260209291908290030181600087803b15801561259757600080fd5b505af11580156125ab573d6000803e3d6000fd5b505050506040513d602081101561156b57600080fd5b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b60006126026125f961156f565b60025490612e81565b61260d5750806113b8565b610dbb61261861156f565b600254610f94908590612e81565b61262e613150565b6001600160a01b031661263f6119a2565b6001600160a01b031614612688576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b600d54604080519182526020820183905280517fa5dae50539d56dfe1fb5273d883b0c39bc76750a25d036fc5fbd09ad8fd5f57f9281900390910190a1600d55565b60006126d76125f961156f565b6126e3575060006113b8565b610dbb600254610f946126f461156f565b8590612e81565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60001b6000604051808280546001816001161561010002031660029004801561277e5780601f1061275c57610100808354040283529182019161277e565b820191906000526020600020905b81548152906001019060200180831161276a575b505091505060405180910390207fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660001b6127b7613989565b3060405160200180868152602001858152602001848152602001838152602001826001600160a01b031681526020019550505050505060405160208183030381529060405280519060200120905090565b612810613150565b6001600160a01b03166128216119a2565b6001600160a01b03161461286a576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b6001600160a01b0381166128af5760405162461bcd60e51b81526004018080602001828103825260268152602001806149d06026913960400191505060405180910390fd5b6006546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36006805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b600a546001600160a01b031681565b32331461297b576040805162461bcd60e51b815260206004820152601460248201527f59616b53747261746567793a3a6f6e6c79454f41000000000000000000000000604482015290519081900360640190fd5b600260125414156129d3576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002601255600080806129e46137e4565b925092509250600c54811015612a41576040805162461bcd60e51b815260206004820152601960248201527f42656e7169537472617465677956313a3a7265696e7665737400000000000000604482015290519081900360640190fd5b612a4c83838361398d565b5050600160125550565b600082820183811015612ab0576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038316612b12576040805162461bcd60e51b815260206004820152601c60248201527f5f617070726f76653a3a6f776e6572207a65726f206164647265737300000000604482015290519081900360640190fd5b6001600160a01b038216612b6d576040805162461bcd60e51b815260206004820152601e60248201527f5f617070726f76653a3a7370656e646572207a65726f20616464726573730000604482015290519081900360640190fd5b6001600160a01b03808416600081815260036020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b60008184841115612c5e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612c23578181015183820152602001612c0b565b50505050905090810190601f168015612c505780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6001600160a01b038216612cab5760405162461bcd60e51b8152600401808060200182810382526034815260200180614ba36034913960400191505060405180910390fd5b612ce8816040518060600160405280602e8152602001614c97602e91396001600160a01b0386166000908152600460205260409020549190612bcf565b6001600160a01b038085166000908152600460205260408082209390935590841681522054612d179082612a56565b6001600160a01b0380841660008181526004602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b601454604080516305eff7ef60e21b8152306004820152905160009283926001600160a01b03909116916317bfdfbc9160248082019260209290919082900301818787803b158015612dc457600080fd5b505af1158015612dd8573d6000803e3d6000fd5b505050506040513d6020811015612dee57600080fd5b505160145460408051633af9e66960e01b815230600482015290519293506000926001600160a01b0390921691633af9e6699160248082019260209290919082900301818787803b158015612e4257600080fd5b505af1158015612e56573d6000803e3d6000fd5b505050506040513d6020811015612e6c57600080fd5b50519050612e7a8183613154565b9250505090565b600082612e9057506000610dbb565b82820282848281612e9d57fe5b0414612ab05760405162461bcd60e51b8152600401808060200182810382526021815260200180614b3e6021913960400191505060405180910390fd5b6000612ab083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613caf565b612f5981604051806060016040528060278152602001614c4b602791396001600160a01b0385166000908152600460205260409020549190612bcf565b60046000846001600160a01b03166001600160a01b0316815260200190815260200160002081905550612fa981604051806060016040528060278152602001614acd602791396002549190612bcf565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b612ff96131a1565b6014546040805163852a12e360e01b81526004810184905290516001600160a01b039092169163852a12e3916024808201926020929091908290030181600087803b15801561304757600080fd5b505af115801561305b573d6000803e3d6000fd5b505050506040513d602081101561307157600080fd5b5051156130c5576040805162461bcd60e51b815260206004820152601e60248201527f42656e7169537472617465677956313a3a72656465656d206661696c65640000604482015290519081900360640190fd5b60145460408051633af9e66960e01b815230600482015290516000926001600160a01b031691633af9e66991602480830192602092919082900301818787803b15801561311157600080fd5b505af1158015613125573d6000803e3d6000fd5b505050506040513d602081101561313b57600080fd5b50519050801561156b5761156b816000613410565b3390565b6000612ab083836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f7700815250612bcf565b601791909155601855565b601454604080516305eff7ef60e21b815230600482015290516000926001600160a01b0316916317bfdfbc91602480830192602092919082900301818787803b1580156131ed57600080fd5b505af1158015613201573d6000803e3d6000fd5b505050506040513d602081101561321757600080fd5b505160145460408051633af9e66960e01b815230600482015290519293506000926001600160a01b0390921691633af9e6699160248082019260209290919082900301818787803b15801561326b57600080fd5b505af115801561327f573d6000803e3d6000fd5b505050506040513d602081101561329557600080fd5b505190506000806132a4613d14565b915091505b83156121365760006132bd84868585613dbe565b9050848111156132ca5750835b6014546040805163852a12e360e01b81526004810184905290516001600160a01b039092169163852a12e3916024808201926020929091908290030181600087803b15801561331857600080fd5b505af115801561332c573d6000803e3d6000fd5b505050506040513d602081101561334257600080fd5b5051156133805760405162461bcd60e51b8152600401808060200182810382526021815260200180614c2a6021913960400191505060405180910390fd5b601460009054906101000a90046001600160a01b03166001600160a01b0316634e4d9fea826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156133d057600080fd5b505af11580156133e4573d6000803e3d6000fd5b50505050506133fc818561315490919063ffffffff16565b93506134088582613154565b9450506132a9565b60008061341b613d14565b9150915060008490506000613445601854610f94601754610f8e898b61315490919063ffffffff16565b9050845b8183101561365257600061345f84838888613de1565b90508261346c8583612a56565b111561347f5761347c8385613154565b90505b60195481101561348f5750613652565b601454604080517fc5ebeaec0000000000000000000000000000000000000000000000000000000081526004810184905290516001600160a01b039092169163c5ebeaec916024808201926020929091908290030181600087803b1580156134f657600080fd5b505af115801561350a573d6000803e3d6000fd5b505050506040513d602081101561352057600080fd5b50511561355e5760405162461bcd60e51b8152600401808060200182810382526021815260200180614af46021913960400191505060405180910390fd5b601460009054906101000a90046001600160a01b03166001600160a01b0316631249c58b826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156135ae57600080fd5b505af11580156135c2573d6000803e3d6000fd5b505060145460408051633af9e66960e01b815230600482015290516001600160a01b039092169450633af9e669935060248082019350602092918290030181600087803b15801561361257600080fd5b505af1158015613626573d6000803e3d6000fd5b505050506040513d602081101561363c57600080fd5b5051935061364a8282612a56565b915050613449565b50505050505050565b600754156136b6573360009081526008602052604090205460ff1615156001146136b65760405162461bcd60e51b815260040180806020018281038252602e815260200180614a1d602e913960400191505060405180910390fd5b600e5460ff161515600114613712576040805162461bcd60e51b815260206004820152601960248201527f42656e7169537472617465677956313a3a5f6465706f73697400000000000000604482015290519081900360640190fd5b600d54156137465760008060006137276137e4565b925092509250600d548111156137425761374283838361398d565b5050505b806000613751612d73565b9050600061376a82600254612e8190919063ffffffff16565b111561378c5761378981610f9460025486612e8190919063ffffffff16565b91505b6137968483613df5565b61379f83613e80565b6040805184815290516001600160a01b038616917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a250505050565b6000806000806137f560003061402d565b9050600061380460013061402d565b60155460165491925060009161383e9185916001600160a01b039182169173b31f66aa3c1e785363f0875a1b74e27b85fd66c791166144bf565b9050828261384c8184612a56565b955095509550505050909192565b60006138646126fb565b8560405160200180807f190100000000000000000000000000000000000000000000000000000000000081525060020183815260200182815260200192505050604051602081830303815290604052805190602001209050600060018286868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015613918573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381161580159061394e5750866001600160a01b0316816001600160a01b0316145b6136525760405162461bcd60e51b8152600401808060200182810382526024815260200180614a7f6024913960400191505060405180910390fd5b4690565b60135460408051630952c56360e01b815260006004820181905230602483015291516001600160a01b0390931692630952c5639260448084019391929182900301818387803b1580156139df57600080fd5b505af11580156139f3573d6000803e3d6000fd5b505060135460408051630952c56360e01b81526001600482015230602482015290516001600160a01b039092169350630952c563925060448082019260009290919082900301818387803b158015613a4a57600080fd5b505af1158015613a5e573d6000803e3d6000fd5b505050506000831115613b1857601554601654600091613aa29186916001600160a01b039081169173b31f66aa3c1e785363f0875a1b74e27b85fd66c7911661458f565b905073b31f66aa3c1e785363f0875a1b74e27b85fd66c76001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015613afe57600080fd5b505af1158015613b12573d6000803e3d6000fd5b50505050505b4790506000613b38612710610f9460115485612e8190919063ffffffff16565b90506000613b57612710610f9460105486612e8190919063ffffffff16565b90506000613b76612710610f94600f5487612e8190919063ffffffff16565b905073b31f66aa3c1e785363f0875a1b74e27b85fd66c763d0e30db0613ba083611b618787612a56565b6040518263ffffffff1660e01b81526004016000604051808303818588803b158015613bcb57600080fd5b505af1158015613bdf573d6000803e3d6000fd5b50505050506000831115613c0a57600a54600b54613c0a916001600160a01b0390811691168561479f565b8115613c2e57600a54613c2e906001600160a01b0316613c286119a2565b8461479f565b8015613c4b57600a54613c4b906001600160a01b0316338361479f565b613c63613c5e8261161d85818989613154565b613e80565b7fc7606d21ac05cd309191543e409f0845c016120563783d70e4f41419dc0ef234613c8c61156f565b6002546040805192835260208301919091528051918290030190a1505050505050565b60008183613cfe5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612c23578181015183820152602001612c0b565b506000838581613d0a57fe5b0495945050505050565b601354601454604080517f8e8f294b0000000000000000000000000000000000000000000000000000000081526001600160a01b039283166004820152815160009485948594911692638e8f294b9260248083019392829003018186803b158015613d7e57600080fd5b505afa158015613d92573d6000803e3d6000fd5b505050506040513d6040811015613da857600080fd5b506020015193670de0b6b3a76400009350915050565b6000613dd8613dd184610f948786612e81565b8690613154565b95945050505050565b6000613dd88461161d84610f948988612e81565b600254613e029082612a56565b6002556001600160a01b038216600090815260046020526040902054613e289082612a56565b6001600160a01b03831660008181526004602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b60008111613ebf5760405162461bcd60e51b8152600401808060200182810382526024815260200180614b7f6024913960400191505060405180910390fd5b601460009054906101000a90046001600160a01b03166001600160a01b0316631249c58b826040518263ffffffff1660e01b81526004016000604051808303818588803b158015613f0f57600080fd5b505af1158015613f23573d6000803e3d6000fd5b5050601454604080516305eff7ef60e21b81523060048201529051600095506001600160a01b0390921693506317bfdfbc925060248082019260209290919082900301818787803b158015613f7757600080fd5b505af1158015613f8b573d6000803e3d6000fd5b505050506040513d6020811015613fa157600080fd5b505160145460408051633af9e66960e01b815230600482015290519293506000926001600160a01b0390921691633af9e6699160248082019260209290919082900301818787803b158015613ff557600080fd5b505af1158015614009573d6000803e3d6000fd5b505050506040513d602081101561401f57600080fd5b50519050611cd48183613410565b601354604080517f05b9783d00000000000000000000000000000000000000000000000000000000815260ff851660048201526001600160a01b0384811660248301529151600093849316916305b9783d916044808301926020929190829003018186803b15801561409e57600080fd5b505afa1580156140b2573d6000803e3d6000fd5b505050506040513d60208110156140c857600080fd5b5051601354604080517fd81c5e4500000000000000000000000000000000000000000000000000000000815260ff881660048201526001600160a01b038781166024830152825194955060009493169263d81c5e4592604480840193919291829003018186803b15801561413b57600080fd5b505afa15801561414f573d6000803e3d6000fd5b505050506040513d604081101561416557600080fd5b5051601354601454604080517f88e972b800000000000000000000000000000000000000000000000000000000815260ff8a1660048201526001600160a01b0392831660248201528883166044820152905193945060009391909216916388e972b8916064808301926020929190829003018186803b1580156141e757600080fd5b505afa1580156141fb573d6000803e3d6000fd5b505050506040513d602081101561421157600080fd5b5051905060006001600160e01b0383168210156142375781836001600160e01b03160390505b601454604080516370a0823160e01b81526001600160a01b03898116600483015291516000936142be9386939116916370a0823191602480820192602092909190829003018186803b15801561428c57600080fd5b505afa1580156142a0573d6000803e3d6000fd5b505050506040513d60208110156142b657600080fd5b505190612e81565b601354604080517f4b3a0a7400000000000000000000000000000000000000000000000000000000815260ff8c1660048201526001600160a01b038b811660248301528251949550600094931692634b3a0a7492604480840193919291829003018186803b15801561432f57600080fd5b505afa158015614343573d6000803e3d6000fd5b505050506040513d604081101561435957600080fd5b5051601354601454604080517f7937969d00000000000000000000000000000000000000000000000000000000815260ff8e1660048201526001600160a01b0392831660248201528c8316604482015290519394506000939190921691637937969d916064808301926020929190829003018186803b1580156143db57600080fd5b505afa1580156143ef573d6000803e3d6000fd5b505050506040513d602081101561440557600080fd5b5051905060006001600160e01b03831682101561442b5781836001600160e01b03160390505b601454604080517f95dd91930000000000000000000000000000000000000000000000000000000081526001600160a01b038d8116600483015291516000936144999386939116916395dd919391602480820192602092909190829003018186803b15801561428c57600080fd5b90506144af6144a88683613154565b8a90612a56565b9c9b505050505050505050505050565b6000806144cc858561485d565b509050600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561450b57600080fd5b505afa15801561451f573d6000803e3d6000fd5b505050506040513d606081101561453557600080fd5b50805160209091015190925090506001600160a01b038381169088161461455857905b61458388836dffffffffffffffffffffffffffff16836dffffffffffffffffffffffffffff1661488e565b98975050505050505050565b60008061459c858561485d565b509050600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156145db57600080fd5b505afa1580156145ef573d6000803e3d6000fd5b505050506040513d606081101561460557600080fd5b50805160209091015190925090506001600160a01b038381169088161461462857905b6000806146568a856dffffffffffffffffffffffffffff16856dffffffffffffffffffffffffffff1661488e565b9050886001600160a01b0316856001600160a01b03161461467357905b61467e89888c6148d6565b60408051600080825260208201928390527f022c0d9f00000000000000000000000000000000000000000000000000000000835260248201858152604483018590523060648401819052608060848501908152845160a486018190526001600160a01b038e169663022c0d9f968a968a9691949193919260c486019290918190849084905b8381101561471b578181015183820152602001614703565b50505050905090810190601f1680156147485780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b15801561476a57600080fd5b505af115801561477e573d6000803e3d6000fd5b5050505081811161478f5781614791565b805b9a9950505050505050505050565b826001600160a01b031663a9059cbb83836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156147f657600080fd5b505af115801561480a573d6000803e3d6000fd5b505050506040513d602081101561482057600080fd5b5051611cd45760405162461bcd60e51b8152600401808060200182810382526025815260200180614c726025913960400191505060405180910390fd5b600080826001600160a01b0316846001600160a01b031610614880578284614883565b83835b915091509250929050565b60008061489d856103e5612e81565b905060006148ab8285612e81565b905060006148bf83611b61886103e8612e81565b90506148cb8282612eda565b979650505050505050565b826001600160a01b031663a9059cbb83836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561492d57600080fd5b505af1158015614941573d6000803e3d6000fd5b505050506040513d602081101561495757600080fd5b5051611cd4576040805162461bcd60e51b815260206004820181905260248201527f4465784c6962726172793a3a5452414e534645525f46524f4d5f4641494c4544604482015290519081900360640190fdfe42656e7169537472617465677956313a3a7061796d656e7473206e6f7420616c6c6f7765644f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737342656e7169537472617465677956313a3a62656c6f77206d696e696d756d2077697468647261775065726d697373696f6e65643a3a6f6e6c79416c6c6f7765644465706f736974732c206e6f7420616c6c6f7765645065726d697373696f6e65643a3a72656d6f76654465706f7369746f722c206e6f20616c6c6f776564206465706f7369746f7273417263683a3a76616c69646174655369673a20696e76616c6964207369676e61747572655065726d697373696f6e65643a3a72656d6f76654465706f7369746f722c206e6f7420616c6c6f7765645f6275726e3a206275726e20616d6f756e74206578636565647320746f74616c20737570706c7942656e7169537472617465677956313a3a626f72726f77696e67206661696c656442656e7169537472617465677956313a3a7769746864726177207472616e73666572206661696c6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657242656e7169537472617465677956313a3a5f7374616b654465706f736974546f6b656e735f7472616e73666572546f6b656e733a2063616e6e6f74207472616e7366657220746f20746865207a65726f206164647265737342656e7169537472617465677956313a3a7265736375654465706c6f79656446756e64737472616e7366657246726f6d3a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636542656e7169537472617465677956313a3a6661696c656420746f2072656465656d5f6275726e3a206275726e20616d6f756e7420657863656564732066726f6d2062616c616e636542656e7169537472617465677956313a3a5452414e534645525f46524f4d5f4641494c45445f7472616e73666572546f6b656e733a207472616e7366657220657863656564732066726f6d2062616c616e6365a26469706673582212201952876c8b3ea7622fb6a9b296dffe22b10ad28b548b4033c79c8a4965598a8964736f6c634300070300334f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735377617020706169722030206973206e656365737361727920627574206e6f7420737570706c6965644f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65728be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0537761702070616972203020646f6573206e6f74206d6174636820726577617264546f6b656e3000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000486af39519b4dc9a7fccd318217352830e8ad9b40000000000000000000000005c0401e81bc07ca70fad469b451682c0d747ef1c0000000000000000000000008729438eb15e2c8b576fcc6aecda6a148776c0f5000000000000000000000000e530dc2095ef5653205cf5ea79f8979a7028065c0000000000000000000000008d36c5c6947adccd25ef49ea1aac2ceacfff0bd7000000000000000000000000000000000000000000000000000000e8d4a510000000000000000000000000000000000000000000000000000000000000003f700000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000e8d4a510000000000000000000000000000000000000000000000000000000000000000258000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000155969656c642059616b3a2042656e716920415641580000000000000000000000
Deployed Bytecode
0x6080604052600436106103855760003560e01c80639291d563116101d1578063c89039c511610102578063dd62ed3e116100a0578063ed24911d1161006f578063ed24911d14610ca4578063f2fde38b14610cb9578063f7c618c114610cec578063fdb5a03e14610d0157610408565b8063dd62ed3e14610beb578063dd8ce4d614610c26578063e21ac82514610c50578063eab89a5a14610c7a57610408565b8063d505accf116100dc578063d505accf14610b4e578063da09c72c14610bac578063db8dd95c14610bc1578063dbd9a4d414610bd657610408565b8063c89039c514610b07578063cff1b6ef14610b1c578063d0e30db014610b4657610408565b8063aa67c9191161016f578063b6b55f2511610149578063b6b55f2514610a9e578063b9e57b8014610ac8578063bd079f5514610add578063c4b24a4614610af257610408565b8063aa67c91914610a31578063ac0d31ff14610a57578063b52a321f14610a8957610408565b80639e4e7318116101ab5780639e4e731814610989578063a24159d31461099e578063a8ae2b7c146109ce578063a9059cbb146109f857610408565b80639291d5631461091757806395d89b411461094a57806399729ec11461095f57610408565b80634bebd1e7116102b65780637ae26773116102545780638980f11f116102235780638980f11f146108655780638aff733d1461089e5780638b73e606146108b35780638da5cb5b146108e657610408565b80637ae26773146107b85780637d882097146107f35780637ecebe0014610808578063818372301461083b57610408565b80635ea682ea116102905780635ea682ea1461074657806370a082311461075b578063715018a61461078e578063789139bc146107a357610408565b80634bebd1e7146106bd5780634e77ace5146106f05780634ebb79161461071c57610408565b80632e1a7d4d11610323578063313ce567116102fd578063313ce567146106055780633bdc6e7214610630578063483c2ef0146106455780634a970be71461067857610408565b80632e1a7d4d1461058d5780632f4f21e2146105b757806330adf81f146105f057610408565b80630f23475d1161035f5780630f23475d1461050b57806318160ddd1461052057806320606b701461053557806323b872dd1461054a57610408565b806306fdde031461040d5780630767711114610497578063095ea7b3146104be57610408565b36610408576013546001600160a01b03163314806103b657503373b31f66aa3c1e785363f0875a1b74e27b85fd66c7145b806103cb57506014546001600160a01b031633145b6104065760405162461bcd60e51b81526004018080602001828103825260258152602001806149ab6025913960400191505060405180910390fd5b005b600080fd5b34801561041957600080fd5b50610422610d16565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561045c578181015183820152602001610444565b50505050905090810190601f1680156104895780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156104a357600080fd5b506104ac610da4565b60408051918252519081900360200190f35b3480156104ca57600080fd5b506104f7600480360360408110156104e157600080fd5b506001600160a01b038135169060200135610daa565b604080519115158252519081900360200190f35b34801561051757600080fd5b506104ac610dc1565b34801561052c57600080fd5b506104ac610dd1565b34801561054157600080fd5b506104ac610dd7565b34801561055657600080fd5b506104f76004803603606081101561056d57600080fd5b506001600160a01b03813581169160208101359091169060400135610dfb565b34801561059957600080fd5b50610406600480360360208110156105b057600080fd5b5035610edd565b3480156105c357600080fd5b50610406600480360360408110156105da57600080fd5b506001600160a01b038135169060200135610408565b3480156105fc57600080fd5b506104ac61107d565b34801561061157600080fd5b5061061a6110a1565b6040805160ff9092168252519081900360200190f35b34801561063c57600080fd5b506104ac6110a6565b34801561065157600080fd5b506104f76004803603602081101561066857600080fd5b50356001600160a01b03166110ac565b34801561068457600080fd5b50610406600480360360a081101561069b57600080fd5b5080359060208101359060ff6040820135169060608101359060800135610408565b3480156106c957600080fd5b50610406600480360360208110156106e057600080fd5b50356001600160a01b03166110c1565b3480156106fc57600080fd5b506104066004803603602081101561071357600080fd5b503515156111fd565b34801561072857600080fd5b506104066004803603602081101561073f57600080fd5b50356112bc565b34801561075257600080fd5b506104ac611398565b34801561076757600080fd5b506104ac6004803603602081101561077e57600080fd5b50356001600160a01b031661139e565b34801561079a57600080fd5b506104066113bd565b3480156107af57600080fd5b506104ac611476565b3480156107c457600080fd5b50610406600480360360408110156107db57600080fd5b506001600160a01b038135811691602001351661147c565b3480156107ff57600080fd5b506104ac61156f565b34801561081457600080fd5b506104ac6004803603602081101561082b57600080fd5b50356001600160a01b031661162b565b34801561084757600080fd5b506104066004803603602081101561085e57600080fd5b503561163d565b34801561087157600080fd5b506104066004803603604081101561088857600080fd5b506001600160a01b0381351690602001356116e1565b3480156108aa57600080fd5b506104ac611835565b3480156108bf57600080fd5b50610406600480360360208110156108d657600080fd5b50356001600160a01b031661183b565b3480156108f257600080fd5b506108fb6119a2565b604080516001600160a01b039092168252519081900360200190f35b34801561092357600080fd5b506104066004803603602081101561093a57600080fd5b50356001600160a01b03166119b1565b34801561095657600080fd5b50610422611a87565b34801561096b57600080fd5b506104066004803603602081101561098257600080fd5b5035611ae1565b34801561099557600080fd5b506104ac611bb4565b3480156109aa57600080fd5b50610406600480360360408110156109c157600080fd5b5080359060200135611bd8565b3480156109da57600080fd5b50610406600480360360208110156109f157600080fd5b5035611cd9565b348015610a0457600080fd5b506104f760048036036040811015610a1b57600080fd5b506001600160a01b038135169060200135611da6565b61040660048036036020811015610a4757600080fd5b50356001600160a01b0316611db3565b348015610a6357600080fd5b5061040660048036036040811015610a7a57600080fd5b50803590602001351515611e22565b348015610a9557600080fd5b506104f761213c565b348015610aaa57600080fd5b5061040660048036036020811015610ac157600080fd5b5035610408565b348015610ad457600080fd5b506104ac612145565b348015610ae957600080fd5b506104ac612186565b348015610afe57600080fd5b506104ac61218c565b348015610b1357600080fd5b506108fb612197565b348015610b2857600080fd5b5061040660048036036020811015610b3f57600080fd5b50356121a6565b610406612273565b348015610b5a57600080fd5b50610406600480360360e0811015610b7157600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c001356122e1565b348015610bb857600080fd5b506108fb6123e1565b348015610bcd57600080fd5b506104ac6123f0565b348015610be257600080fd5b506104066124c6565b348015610bf757600080fd5b506104ac60048036036040811015610c0e57600080fd5b506001600160a01b03813581169160200135166125c1565b348015610c3257600080fd5b506104ac60048036036020811015610c4957600080fd5b50356125ec565b348015610c5c57600080fd5b5061040660048036036020811015610c7357600080fd5b5035612626565b348015610c8657600080fd5b506104ac60048036036020811015610c9d57600080fd5b50356126ca565b348015610cb057600080fd5b506104ac6126fb565b348015610cc557600080fd5b5061040660048036036020811015610cdc57600080fd5b50356001600160a01b0316612808565b348015610cf857600080fd5b506108fb612918565b348015610d0d57600080fd5b50610406612927565b6000805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610d9c5780601f10610d7157610100808354040283529160200191610d9c565b820191906000526020600020905b815481529060010190602001808311610d7f57829003601f168201915b505050505081565b60105481565b6000610db7338484612ab7565b5060015b92915050565b6000610dcb61156f565b90505b90565b60025481565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6001600160a01b038316600081815260036020908152604080832033808552925282205491929091908214801590610e3557506000198114155b15610ec6576000610e61856040518060600160405280602f8152602001614bfb602f9139849190612bcf565b6001600160a01b0380891660008181526003602090815260408083209489168084529482529182902085905581518581529151949550929391927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92592918290030190a3505b610ed1868686612c66565b50600195945050505050565b60026012541415610f35576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026012556019548111610f7a5760405162461bcd60e51b81526004018080602001828103825260278152602001806149f66027913960400191505060405180910390fd5b6000610f9a600254610f9484610f8e612d73565b90612e81565b90612eda565b9050801561107457610fac3383612f1c565b610fb581612ff1565b604051600090339083908381818185875af1925050503d8060008114610ff7576040519150601f19603f3d011682016040523d82523d6000602084013e610ffc565b606091505b505090508061103c5760405162461bcd60e51b8152600401808060200182810382526029815260200180614b156029913960400191505060405180910390fd5b60408051838152905133917f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364919081900360200190a2505b50506001601255565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b60075481565b60086020526000908152604090205460ff1681565b6110c9613150565b6001600160a01b03166110da6119a2565b6001600160a01b031614611123576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526008602052604090205460ff1615611191576040805162461bcd60e51b815260206004820152601c60248201527f5065726d697373696f6e65643a3a616c6c6f774465706f7369746f7200000000604482015290519081900360640190fd5b6001600160a01b0381166000908152600860205260409020805460ff191660019081179091556007546111c391612a56565b6007556040516001600160a01b038216907fc0a1035c16faf8d1304056d92c00edf028f87e62b8235a938f00af9e3c0312c590600090a250565b611205613150565b6001600160a01b03166112166119a2565b6001600160a01b03161461125f576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b600e5460ff161515811515141561127557600080fd5b600e805482151560ff19909116811790915560408051918252517f7b014ed3854e7f5cb0218d58b3c6ae7d53a68bb0af2f67bfb029ea42c38a7e859181900360200190a150565b6112c4613150565b6001600160a01b03166112d56119a2565b6001600160a01b03161461131e576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b6000811161132b57600080fd5b604051339082156108fc029083906000818181858888f19350505050158015611358573d6000803e3d6000fd5b5060408051600081526020810183905281517f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa28929181900390910190a150565b60115481565b6001600160a01b0381166000908152600460205260409020545b919050565b6113c5613150565b6001600160a01b03166113d66119a2565b6001600160a01b03161461141f576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b6006546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36006805473ffffffffffffffffffffffffffffffffffffffff19169055565b600d5481565b611484613150565b6001600160a01b03166114956119a2565b6001600160a01b0316146114de576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b816001600160a01b031663095ea7b38260006040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561153657600080fd5b505af115801561154a573d6000803e3d6000fd5b505050506040513d602081101561156057600080fd5b505161156b57600080fd5b5050565b601454604080516361bfb47160e11b815230600482015290516000928392839283926001600160a01b03169163c37f68e2916024808301926080929190829003018186803b1580156115c057600080fd5b505afa1580156115d4573d6000803e3d6000fd5b505050506040513d60808110156115ea57600080fd5b506020810151604082015160609092015190945090925090506116238261161d670de0b6b3a7640000610f948786612e81565b90613154565b935050505090565b60056020526000908152604090205481565b611645613150565b6001600160a01b03166116566119a2565b6001600160a01b03161461169f576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b600c54604080519182526020820183905280517f481f79ac3a523b6d6db3c5a720e190e986d1cc1b41adcdf50f9caef8499011009281900390910190a1600c55565b6116e9613150565b6001600160a01b03166116fa6119a2565b6001600160a01b031614611743576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b6000811161175057600080fd5b604080517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905290516001600160a01b0384169163a9059cbb9160448083019260209291908290030181600087803b1580156117b857600080fd5b505af11580156117cc573d6000803e3d6000fd5b505050506040513d60208110156117e257600080fd5b50516117ed57600080fd5b604080516001600160a01b03841681526020810183905281517f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa28929181900390910190a15050565b600f5481565b611843613150565b6001600160a01b03166118546119a2565b6001600160a01b03161461189d576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b6000600754116118de5760405162461bcd60e51b8152600401808060200182810382526034815260200180614a4b6034913960400191505060405180910390fd5b6001600160a01b03811660009081526008602052604090205460ff16151560011461193a5760405162461bcd60e51b815260040180806020018281038252602a815260200180614aa3602a913960400191505060405180910390fd5b6001600160a01b0381166000908152600860205260409020805460ff19169055600754611968906001613154565b6007556040516001600160a01b038216907f0e86f6608b536e5339a25b65ff531f5ea91e1313d056ecd4752b35cbd16137d490600090a250565b6006546001600160a01b031690565b600b546001600160a01b03163314611a10576040805162461bcd60e51b815260206004820152601460248201527f59616b53747261746567793a3a6f6e6c79446576000000000000000000000000604482015290519081900360640190fd5b600b54604080516001600160a01b039283168152918316602083015280517fa8e91499ed37682f43cffb045fcc7d379a91e8c9a14e6321877ee34dee564c009281900390910190a1600b805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60018054604080516020600284861615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610d9c5780601f10610d7157610100808354040283529160200191610d9c565b611ae9613150565b6001600160a01b0316611afa6119a2565b6001600160a01b031614611b43576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b612710611b67600f54611b6160105485612a5690919063ffffffff16565b90612a56565b1115611b7257600080fd5b601154604080519182526020820183905280517f2a42303d002f0ba6cfe8259c91d4684443fb0b3de286ba74991175d6517261319281900390910190a1601155565b7fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc681565b600b546001600160a01b03163314611c37576040805162461bcd60e51b815260206004820152601460248201527f59616b53747261746567793a3a6f6e6c79446576000000000000000000000000604482015290519081900360640190fd5b611c418282613196565b611c496131a1565b60145460408051633af9e66960e01b815230600482015290516000926001600160a01b031691633af9e66991602480830192602092919082900301818787803b158015611c9557600080fd5b505af1158015611ca9573d6000803e3d6000fd5b505050506040513d6020811015611cbf57600080fd5b505190508015611cd457611cd4816000613410565b505050565b611ce1613150565b6001600160a01b0316611cf26119a2565b6001600160a01b031614611d3b576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b612710611d59601154611b6160105485612a5690919063ffffffff16565b1115611d6457600080fd5b600f54604080519182526020820183905280517fe7f97d51d307dc44045597c9978bec0f842e6bb40d19b9444084cfa30d9ed4f29281900390910190a1600f55565b6000610db7338484612c66565b60026012541415611e0b576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002601255611e1a813461365b565b506001601255565b611e2a613150565b6001600160a01b0316611e3b6119a2565b6001600160a01b031614611e84576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b600954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611ecf57600080fd5b505afa158015611ee3573d6000803e3d6000fd5b505050506040513d6020811015611ef957600080fd5b50519050611f056131a1565b60145460408051633af9e66960e01b815230600482015290516001600160a01b039092169163852a12e3918391633af9e669916024808201926020929091908290030181600087803b158015611f5a57600080fd5b505af1158015611f6e573d6000803e3d6000fd5b505050506040513d6020811015611f8457600080fd5b5051604080517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092525160248083019260209291908290030181600087803b158015611fdd57600080fd5b505af1158015611ff1573d6000803e3d6000fd5b505050506040513d602081101561200757600080fd5b5050600954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561205457600080fd5b505afa158015612068573d6000803e3d6000fd5b505050506040513d602081101561207e57600080fd5b505190508361208d8284613154565b10156120ca5760405162461bcd60e51b8152600401808060200182810382526024815260200180614bd76024913960400191505060405180910390fd5b7fc7606d21ac05cd309191543e409f0845c016120563783d70e4f41419dc0ef2346120f361156f565b6002546040805192835260208301919091528051918290030190a1600e5460ff161515600114801561212757506001831515145b156121365761213660006111fd565b50505050565b600e5460ff1681565b60008061215061218c565b9050600c54811061217e57612176612710610f94600f5484612e8190919063ffffffff16565b915050610dce565b600091505090565b600c5481565b6000806116236137e4565b6009546001600160a01b031681565b6121ae613150565b6001600160a01b03166121bf6119a2565b6001600160a01b031614612208576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b612710612226600f54611b6160115485612a5690919063ffffffff16565b111561223157600080fd5b601054604080519182526020820183905280517f3cc372f330f95ac9540626dc8a25f5bf21ba607215a5d58304cb804d446f104a9281900390910190a1601055565b600260125414156122cb576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026012556122da333461365b565b6001601255565b42841015612336576040805162461bcd60e51b815260206004820152600f60248201527f7065726d69743a3a657870697265640000000000000000000000000000000000604482015290519081900360640190fd5b6001600160a01b0380881660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938a1660608401526080830189905260a083019390935260c08083018890528151808403909101815260e0909201905280519101206123cc888286868661385a565b6123d7888888612ab7565b5050505050505050565b600b546001600160a01b031681565b601454604080516361bfb47160e11b815230600482015290516000928392839283926001600160a01b03169163c37f68e2916024808301926080929190829003018186803b15801561244157600080fd5b505afa158015612455573d6000803e3d6000fd5b505050506040513d608081101561246b57600080fd5b50602081015160408201516060909201519094509092509050600061249c670de0b6b3a7640000610f948685612e81565b90506124bd6124ab8285613154565b610f9483670de0b6b3a7640000612e81565b94505050505090565b6124ce613150565b6001600160a01b03166124df6119a2565b6001600160a01b031614612528576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b601454604080517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b039092166004830181905260001960248401529051909163095ea7b39160448083019260209291908290030181600087803b15801561259757600080fd5b505af11580156125ab573d6000803e3d6000fd5b505050506040513d602081101561156b57600080fd5b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b60006126026125f961156f565b60025490612e81565b61260d5750806113b8565b610dbb61261861156f565b600254610f94908590612e81565b61262e613150565b6001600160a01b031661263f6119a2565b6001600160a01b031614612688576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b600d54604080519182526020820183905280517fa5dae50539d56dfe1fb5273d883b0c39bc76750a25d036fc5fbd09ad8fd5f57f9281900390910190a1600d55565b60006126d76125f961156f565b6126e3575060006113b8565b610dbb600254610f946126f461156f565b8590612e81565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60001b6000604051808280546001816001161561010002031660029004801561277e5780601f1061275c57610100808354040283529182019161277e565b820191906000526020600020905b81548152906001019060200180831161276a575b505091505060405180910390207fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660001b6127b7613989565b3060405160200180868152602001858152602001848152602001838152602001826001600160a01b031681526020019550505050505060405160208183030381529060405280519060200120905090565b612810613150565b6001600160a01b03166128216119a2565b6001600160a01b03161461286a576040805162461bcd60e51b81526020600482018190526024820152600080516020614b5f833981519152604482015290519081900360640190fd5b6001600160a01b0381166128af5760405162461bcd60e51b81526004018080602001828103825260268152602001806149d06026913960400191505060405180910390fd5b6006546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36006805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b600a546001600160a01b031681565b32331461297b576040805162461bcd60e51b815260206004820152601460248201527f59616b53747261746567793a3a6f6e6c79454f41000000000000000000000000604482015290519081900360640190fd5b600260125414156129d3576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002601255600080806129e46137e4565b925092509250600c54811015612a41576040805162461bcd60e51b815260206004820152601960248201527f42656e7169537472617465677956313a3a7265696e7665737400000000000000604482015290519081900360640190fd5b612a4c83838361398d565b5050600160125550565b600082820183811015612ab0576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038316612b12576040805162461bcd60e51b815260206004820152601c60248201527f5f617070726f76653a3a6f776e6572207a65726f206164647265737300000000604482015290519081900360640190fd5b6001600160a01b038216612b6d576040805162461bcd60e51b815260206004820152601e60248201527f5f617070726f76653a3a7370656e646572207a65726f20616464726573730000604482015290519081900360640190fd5b6001600160a01b03808416600081815260036020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b60008184841115612c5e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612c23578181015183820152602001612c0b565b50505050905090810190601f168015612c505780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6001600160a01b038216612cab5760405162461bcd60e51b8152600401808060200182810382526034815260200180614ba36034913960400191505060405180910390fd5b612ce8816040518060600160405280602e8152602001614c97602e91396001600160a01b0386166000908152600460205260409020549190612bcf565b6001600160a01b038085166000908152600460205260408082209390935590841681522054612d179082612a56565b6001600160a01b0380841660008181526004602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b601454604080516305eff7ef60e21b8152306004820152905160009283926001600160a01b03909116916317bfdfbc9160248082019260209290919082900301818787803b158015612dc457600080fd5b505af1158015612dd8573d6000803e3d6000fd5b505050506040513d6020811015612dee57600080fd5b505160145460408051633af9e66960e01b815230600482015290519293506000926001600160a01b0390921691633af9e6699160248082019260209290919082900301818787803b158015612e4257600080fd5b505af1158015612e56573d6000803e3d6000fd5b505050506040513d6020811015612e6c57600080fd5b50519050612e7a8183613154565b9250505090565b600082612e9057506000610dbb565b82820282848281612e9d57fe5b0414612ab05760405162461bcd60e51b8152600401808060200182810382526021815260200180614b3e6021913960400191505060405180910390fd5b6000612ab083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613caf565b612f5981604051806060016040528060278152602001614c4b602791396001600160a01b0385166000908152600460205260409020549190612bcf565b60046000846001600160a01b03166001600160a01b0316815260200190815260200160002081905550612fa981604051806060016040528060278152602001614acd602791396002549190612bcf565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b612ff96131a1565b6014546040805163852a12e360e01b81526004810184905290516001600160a01b039092169163852a12e3916024808201926020929091908290030181600087803b15801561304757600080fd5b505af115801561305b573d6000803e3d6000fd5b505050506040513d602081101561307157600080fd5b5051156130c5576040805162461bcd60e51b815260206004820152601e60248201527f42656e7169537472617465677956313a3a72656465656d206661696c65640000604482015290519081900360640190fd5b60145460408051633af9e66960e01b815230600482015290516000926001600160a01b031691633af9e66991602480830192602092919082900301818787803b15801561311157600080fd5b505af1158015613125573d6000803e3d6000fd5b505050506040513d602081101561313b57600080fd5b50519050801561156b5761156b816000613410565b3390565b6000612ab083836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f7700815250612bcf565b601791909155601855565b601454604080516305eff7ef60e21b815230600482015290516000926001600160a01b0316916317bfdfbc91602480830192602092919082900301818787803b1580156131ed57600080fd5b505af1158015613201573d6000803e3d6000fd5b505050506040513d602081101561321757600080fd5b505160145460408051633af9e66960e01b815230600482015290519293506000926001600160a01b0390921691633af9e6699160248082019260209290919082900301818787803b15801561326b57600080fd5b505af115801561327f573d6000803e3d6000fd5b505050506040513d602081101561329557600080fd5b505190506000806132a4613d14565b915091505b83156121365760006132bd84868585613dbe565b9050848111156132ca5750835b6014546040805163852a12e360e01b81526004810184905290516001600160a01b039092169163852a12e3916024808201926020929091908290030181600087803b15801561331857600080fd5b505af115801561332c573d6000803e3d6000fd5b505050506040513d602081101561334257600080fd5b5051156133805760405162461bcd60e51b8152600401808060200182810382526021815260200180614c2a6021913960400191505060405180910390fd5b601460009054906101000a90046001600160a01b03166001600160a01b0316634e4d9fea826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156133d057600080fd5b505af11580156133e4573d6000803e3d6000fd5b50505050506133fc818561315490919063ffffffff16565b93506134088582613154565b9450506132a9565b60008061341b613d14565b9150915060008490506000613445601854610f94601754610f8e898b61315490919063ffffffff16565b9050845b8183101561365257600061345f84838888613de1565b90508261346c8583612a56565b111561347f5761347c8385613154565b90505b60195481101561348f5750613652565b601454604080517fc5ebeaec0000000000000000000000000000000000000000000000000000000081526004810184905290516001600160a01b039092169163c5ebeaec916024808201926020929091908290030181600087803b1580156134f657600080fd5b505af115801561350a573d6000803e3d6000fd5b505050506040513d602081101561352057600080fd5b50511561355e5760405162461bcd60e51b8152600401808060200182810382526021815260200180614af46021913960400191505060405180910390fd5b601460009054906101000a90046001600160a01b03166001600160a01b0316631249c58b826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156135ae57600080fd5b505af11580156135c2573d6000803e3d6000fd5b505060145460408051633af9e66960e01b815230600482015290516001600160a01b039092169450633af9e669935060248082019350602092918290030181600087803b15801561361257600080fd5b505af1158015613626573d6000803e3d6000fd5b505050506040513d602081101561363c57600080fd5b5051935061364a8282612a56565b915050613449565b50505050505050565b600754156136b6573360009081526008602052604090205460ff1615156001146136b65760405162461bcd60e51b815260040180806020018281038252602e815260200180614a1d602e913960400191505060405180910390fd5b600e5460ff161515600114613712576040805162461bcd60e51b815260206004820152601960248201527f42656e7169537472617465677956313a3a5f6465706f73697400000000000000604482015290519081900360640190fd5b600d54156137465760008060006137276137e4565b925092509250600d548111156137425761374283838361398d565b5050505b806000613751612d73565b9050600061376a82600254612e8190919063ffffffff16565b111561378c5761378981610f9460025486612e8190919063ffffffff16565b91505b6137968483613df5565b61379f83613e80565b6040805184815290516001600160a01b038616917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a250505050565b6000806000806137f560003061402d565b9050600061380460013061402d565b60155460165491925060009161383e9185916001600160a01b039182169173b31f66aa3c1e785363f0875a1b74e27b85fd66c791166144bf565b9050828261384c8184612a56565b955095509550505050909192565b60006138646126fb565b8560405160200180807f190100000000000000000000000000000000000000000000000000000000000081525060020183815260200182815260200192505050604051602081830303815290604052805190602001209050600060018286868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015613918573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381161580159061394e5750866001600160a01b0316816001600160a01b0316145b6136525760405162461bcd60e51b8152600401808060200182810382526024815260200180614a7f6024913960400191505060405180910390fd5b4690565b60135460408051630952c56360e01b815260006004820181905230602483015291516001600160a01b0390931692630952c5639260448084019391929182900301818387803b1580156139df57600080fd5b505af11580156139f3573d6000803e3d6000fd5b505060135460408051630952c56360e01b81526001600482015230602482015290516001600160a01b039092169350630952c563925060448082019260009290919082900301818387803b158015613a4a57600080fd5b505af1158015613a5e573d6000803e3d6000fd5b505050506000831115613b1857601554601654600091613aa29186916001600160a01b039081169173b31f66aa3c1e785363f0875a1b74e27b85fd66c7911661458f565b905073b31f66aa3c1e785363f0875a1b74e27b85fd66c76001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015613afe57600080fd5b505af1158015613b12573d6000803e3d6000fd5b50505050505b4790506000613b38612710610f9460115485612e8190919063ffffffff16565b90506000613b57612710610f9460105486612e8190919063ffffffff16565b90506000613b76612710610f94600f5487612e8190919063ffffffff16565b905073b31f66aa3c1e785363f0875a1b74e27b85fd66c763d0e30db0613ba083611b618787612a56565b6040518263ffffffff1660e01b81526004016000604051808303818588803b158015613bcb57600080fd5b505af1158015613bdf573d6000803e3d6000fd5b50505050506000831115613c0a57600a54600b54613c0a916001600160a01b0390811691168561479f565b8115613c2e57600a54613c2e906001600160a01b0316613c286119a2565b8461479f565b8015613c4b57600a54613c4b906001600160a01b0316338361479f565b613c63613c5e8261161d85818989613154565b613e80565b7fc7606d21ac05cd309191543e409f0845c016120563783d70e4f41419dc0ef234613c8c61156f565b6002546040805192835260208301919091528051918290030190a1505050505050565b60008183613cfe5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612c23578181015183820152602001612c0b565b506000838581613d0a57fe5b0495945050505050565b601354601454604080517f8e8f294b0000000000000000000000000000000000000000000000000000000081526001600160a01b039283166004820152815160009485948594911692638e8f294b9260248083019392829003018186803b158015613d7e57600080fd5b505afa158015613d92573d6000803e3d6000fd5b505050506040513d6040811015613da857600080fd5b506020015193670de0b6b3a76400009350915050565b6000613dd8613dd184610f948786612e81565b8690613154565b95945050505050565b6000613dd88461161d84610f948988612e81565b600254613e029082612a56565b6002556001600160a01b038216600090815260046020526040902054613e289082612a56565b6001600160a01b03831660008181526004602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b60008111613ebf5760405162461bcd60e51b8152600401808060200182810382526024815260200180614b7f6024913960400191505060405180910390fd5b601460009054906101000a90046001600160a01b03166001600160a01b0316631249c58b826040518263ffffffff1660e01b81526004016000604051808303818588803b158015613f0f57600080fd5b505af1158015613f23573d6000803e3d6000fd5b5050601454604080516305eff7ef60e21b81523060048201529051600095506001600160a01b0390921693506317bfdfbc925060248082019260209290919082900301818787803b158015613f7757600080fd5b505af1158015613f8b573d6000803e3d6000fd5b505050506040513d6020811015613fa157600080fd5b505160145460408051633af9e66960e01b815230600482015290519293506000926001600160a01b0390921691633af9e6699160248082019260209290919082900301818787803b158015613ff557600080fd5b505af1158015614009573d6000803e3d6000fd5b505050506040513d602081101561401f57600080fd5b50519050611cd48183613410565b601354604080517f05b9783d00000000000000000000000000000000000000000000000000000000815260ff851660048201526001600160a01b0384811660248301529151600093849316916305b9783d916044808301926020929190829003018186803b15801561409e57600080fd5b505afa1580156140b2573d6000803e3d6000fd5b505050506040513d60208110156140c857600080fd5b5051601354604080517fd81c5e4500000000000000000000000000000000000000000000000000000000815260ff881660048201526001600160a01b038781166024830152825194955060009493169263d81c5e4592604480840193919291829003018186803b15801561413b57600080fd5b505afa15801561414f573d6000803e3d6000fd5b505050506040513d604081101561416557600080fd5b5051601354601454604080517f88e972b800000000000000000000000000000000000000000000000000000000815260ff8a1660048201526001600160a01b0392831660248201528883166044820152905193945060009391909216916388e972b8916064808301926020929190829003018186803b1580156141e757600080fd5b505afa1580156141fb573d6000803e3d6000fd5b505050506040513d602081101561421157600080fd5b5051905060006001600160e01b0383168210156142375781836001600160e01b03160390505b601454604080516370a0823160e01b81526001600160a01b03898116600483015291516000936142be9386939116916370a0823191602480820192602092909190829003018186803b15801561428c57600080fd5b505afa1580156142a0573d6000803e3d6000fd5b505050506040513d60208110156142b657600080fd5b505190612e81565b601354604080517f4b3a0a7400000000000000000000000000000000000000000000000000000000815260ff8c1660048201526001600160a01b038b811660248301528251949550600094931692634b3a0a7492604480840193919291829003018186803b15801561432f57600080fd5b505afa158015614343573d6000803e3d6000fd5b505050506040513d604081101561435957600080fd5b5051601354601454604080517f7937969d00000000000000000000000000000000000000000000000000000000815260ff8e1660048201526001600160a01b0392831660248201528c8316604482015290519394506000939190921691637937969d916064808301926020929190829003018186803b1580156143db57600080fd5b505afa1580156143ef573d6000803e3d6000fd5b505050506040513d602081101561440557600080fd5b5051905060006001600160e01b03831682101561442b5781836001600160e01b03160390505b601454604080517f95dd91930000000000000000000000000000000000000000000000000000000081526001600160a01b038d8116600483015291516000936144999386939116916395dd919391602480820192602092909190829003018186803b15801561428c57600080fd5b90506144af6144a88683613154565b8a90612a56565b9c9b505050505050505050505050565b6000806144cc858561485d565b509050600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561450b57600080fd5b505afa15801561451f573d6000803e3d6000fd5b505050506040513d606081101561453557600080fd5b50805160209091015190925090506001600160a01b038381169088161461455857905b61458388836dffffffffffffffffffffffffffff16836dffffffffffffffffffffffffffff1661488e565b98975050505050505050565b60008061459c858561485d565b509050600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156145db57600080fd5b505afa1580156145ef573d6000803e3d6000fd5b505050506040513d606081101561460557600080fd5b50805160209091015190925090506001600160a01b038381169088161461462857905b6000806146568a856dffffffffffffffffffffffffffff16856dffffffffffffffffffffffffffff1661488e565b9050886001600160a01b0316856001600160a01b03161461467357905b61467e89888c6148d6565b60408051600080825260208201928390527f022c0d9f00000000000000000000000000000000000000000000000000000000835260248201858152604483018590523060648401819052608060848501908152845160a486018190526001600160a01b038e169663022c0d9f968a968a9691949193919260c486019290918190849084905b8381101561471b578181015183820152602001614703565b50505050905090810190601f1680156147485780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b15801561476a57600080fd5b505af115801561477e573d6000803e3d6000fd5b5050505081811161478f5781614791565b805b9a9950505050505050505050565b826001600160a01b031663a9059cbb83836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156147f657600080fd5b505af115801561480a573d6000803e3d6000fd5b505050506040513d602081101561482057600080fd5b5051611cd45760405162461bcd60e51b8152600401808060200182810382526025815260200180614c726025913960400191505060405180910390fd5b600080826001600160a01b0316846001600160a01b031610614880578284614883565b83835b915091509250929050565b60008061489d856103e5612e81565b905060006148ab8285612e81565b905060006148bf83611b61886103e8612e81565b90506148cb8282612eda565b979650505050505050565b826001600160a01b031663a9059cbb83836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561492d57600080fd5b505af1158015614941573d6000803e3d6000fd5b505050506040513d602081101561495757600080fd5b5051611cd4576040805162461bcd60e51b815260206004820181905260248201527f4465784c6962726172793a3a5452414e534645525f46524f4d5f4641494c4544604482015290519081900360640190fdfe42656e7169537472617465677956313a3a7061796d656e7473206e6f7420616c6c6f7765644f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737342656e7169537472617465677956313a3a62656c6f77206d696e696d756d2077697468647261775065726d697373696f6e65643a3a6f6e6c79416c6c6f7765644465706f736974732c206e6f7420616c6c6f7765645065726d697373696f6e65643a3a72656d6f76654465706f7369746f722c206e6f20616c6c6f776564206465706f7369746f7273417263683a3a76616c69646174655369673a20696e76616c6964207369676e61747572655065726d697373696f6e65643a3a72656d6f76654465706f7369746f722c206e6f7420616c6c6f7765645f6275726e3a206275726e20616d6f756e74206578636565647320746f74616c20737570706c7942656e7169537472617465677956313a3a626f72726f77696e67206661696c656442656e7169537472617465677956313a3a7769746864726177207472616e73666572206661696c6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657242656e7169537472617465677956313a3a5f7374616b654465706f736974546f6b656e735f7472616e73666572546f6b656e733a2063616e6e6f74207472616e7366657220746f20746865207a65726f206164647265737342656e7169537472617465677956313a3a7265736375654465706c6f79656446756e64737472616e7366657246726f6d3a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636542656e7169537472617465677956313a3a6661696c656420746f2072656465656d5f6275726e3a206275726e20616d6f756e7420657863656564732066726f6d2062616c616e636542656e7169537472617465677956313a3a5452414e534645525f46524f4d5f4641494c45445f7472616e73666572546f6b656e733a207472616e7366657220657863656564732066726f6d2062616c616e6365a26469706673582212201952876c8b3ea7622fb6a9b296dffe22b10ad28b548b4033c79c8a4965598a8964736f6c63430007030033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000486af39519b4dc9a7fccd318217352830e8ad9b40000000000000000000000005c0401e81bc07ca70fad469b451682c0d747ef1c0000000000000000000000008729438eb15e2c8b576fcc6aecda6a148776c0f5000000000000000000000000e530dc2095ef5653205cf5ea79f8979a7028065c0000000000000000000000008d36c5c6947adccd25ef49ea1aac2ceacfff0bd7000000000000000000000000000000000000000000000000000000e8d4a510000000000000000000000000000000000000000000000000000000000000003f700000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000e8d4a510000000000000000000000000000000000000000000000000000000000000000258000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000155969656c642059616b3a2042656e716920415641580000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): Yield Yak: Benqi AVAX
Arg [1] : _rewardController (address): 0x486Af39519B4Dc9a7fCcd318217352830E8AD9b4
Arg [2] : _tokenDelegator (address): 0x5C0401e81Bc07Ca70fAD469b451682c0d747Ef1c
Arg [3] : _rewardToken0 (address): 0x8729438EB15e2C8B576fCc6AeCdA6A148776C0F5
Arg [4] : _swapPairToken0 (address): 0xE530dC2095Ef5653205CF5ea79F8979a7028065c
Arg [5] : _timelock (address): 0x8d36C5c6947ADCcd25Ef49Ea1aAC2ceACFff0bD7
Arg [6] : _minMinting (uint256): 1000000000000
Arg [7] : _leverageLevel (uint256): 16240
Arg [8] : _leverageBips (uint256): 10000
Arg [9] : _minTokensToReinvest (uint256): 1000000000000
Arg [10] : _adminFeeBips (uint256): 600
Arg [11] : _devFeeBips (uint256): 0
Arg [12] : _reinvestRewardBips (uint256): 200
-----Encoded View---------------
15 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [1] : 000000000000000000000000486af39519b4dc9a7fccd318217352830e8ad9b4
Arg [2] : 0000000000000000000000005c0401e81bc07ca70fad469b451682c0d747ef1c
Arg [3] : 0000000000000000000000008729438eb15e2c8b576fcc6aecda6a148776c0f5
Arg [4] : 000000000000000000000000e530dc2095ef5653205cf5ea79f8979a7028065c
Arg [5] : 0000000000000000000000008d36c5c6947adccd25ef49ea1aac2ceacfff0bd7
Arg [6] : 000000000000000000000000000000000000000000000000000000e8d4a51000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000003f70
Arg [8] : 0000000000000000000000000000000000000000000000000000000000002710
Arg [9] : 000000000000000000000000000000000000000000000000000000e8d4a51000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000258
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [12] : 00000000000000000000000000000000000000000000000000000000000000c8
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000015
Arg [14] : 5969656c642059616b3a2042656e716920415641580000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
AVAX | 100.00% | $0.009077 | 280,617.307 | $2,547.25 |
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.