More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 967 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Request Claim | 19907418 | 68 days ago | IN | 0 ETH | 0.00061461 | ||||
Deposit | 19815192 | 81 days ago | IN | 0 ETH | 0.00066176 | ||||
Request Claim | 19563510 | 116 days ago | IN | 0 ETH | 0.00451423 | ||||
Request Claim | 19492763 | 126 days ago | IN | 0 ETH | 0.00453663 | ||||
Request Claim | 19491887 | 126 days ago | IN | 0 ETH | 0.00438037 | ||||
Withdraw | 19491724 | 126 days ago | IN | 0 ETH | 0.00403553 | ||||
Request Claim | 19138236 | 176 days ago | IN | 0 ETH | 0.00360705 | ||||
Request Claim | 19058066 | 187 days ago | IN | 0 ETH | 0.0022135 | ||||
Request Claim | 18576873 | 255 days ago | IN | 0 ETH | 0.0056195 | ||||
Request Claim | 18558643 | 257 days ago | IN | 0 ETH | 0.00582099 | ||||
Request Claim | 18558640 | 257 days ago | IN | 0 ETH | 0.00601394 | ||||
Request Claim | 18553739 | 258 days ago | IN | 0 ETH | 0.00427459 | ||||
Compound Smol | 18499238 | 266 days ago | IN | 0 ETH | 0.0035727 | ||||
Withdraw | 18409180 | 278 days ago | IN | 0 ETH | 0.00123465 | ||||
Request Claim | 18402091 | 279 days ago | IN | 0 ETH | 0.00122438 | ||||
Request Claim | 18399447 | 280 days ago | IN | 0 ETH | 0.00304258 | ||||
Request Claim | 18369330 | 284 days ago | IN | 0 ETH | 0.00114871 | ||||
Compound Smol | 18369326 | 284 days ago | IN | 0 ETH | 0.00142994 | ||||
Request Claim | 18361606 | 285 days ago | IN | 0 ETH | 0.00152073 | ||||
Request Claim | 18356353 | 286 days ago | IN | 0 ETH | 0.00102375 | ||||
Request Claim | 18356351 | 286 days ago | IN | 0 ETH | 0.00108053 | ||||
Deposit | 18353737 | 286 days ago | IN | 0 ETH | 0.00072046 | ||||
Compound Smol | 18348046 | 287 days ago | IN | 0 ETH | 0.00143005 | ||||
Request Claim | 18336185 | 288 days ago | IN | 0 ETH | 0.00155975 | ||||
Request Claim | 18336180 | 288 days ago | IN | 0 ETH | 0.00167545 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
KarrotChefV3
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: MIT pragma solidity ^0.8.19; /** ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣤⣤⣾⣿⣿⣿⣿⣷⣶⣶⣦⡄⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠙⠛⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⡿⠿⠿⠿⠿⠿⠿⢿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣤⣴⣶⣶⣶⣶⣦⣤⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⢿⣿⣿⡿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣤⣶⣶⣤⣤⣤⣤⣶⣶⣤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⣿⡉⣿⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣿⡇⢻⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣥⣽⡇⢸⣿⣿⣿⣿⡄⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠈⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠁⠈⠉⠉⠉⠉⠁⠀⠀⠀⠀⠀ _ _ __ ___ ____________ _____ _____ _____ _ _ ___________ | || | / / / _ \ | ___ \ ___ \ _ |_ _| / __ \| | | || ___| ___| / __) |/ / / /_\ \| |_/ / |_/ / | | | | | | / \/| |_| || |__ | |_ \__ \ \ | _ || /| /| | | | | | | | | _ || __|| _| ( / |\ \| | | || |\ \| |\ \\ \_/ / | | | \__/\| | | || |___| | |_|\_| \_/\_| |_/\_| \_\_| \_|\___/ \_/ \____/\_| |_/\____/\_| V2 https://twitter.com/Karrot_gg */ import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/utils/math/Math.sol"; import "./interfaces/IRandomizer.sol"; import "./interfaces/IConfig.sol"; import "./interfaces/IKarrotsToken.sol"; import "./interfaces/IFullProtec.sol"; import "./interfaces/IStolenPool.sol"; import "./interfaces/IUniswapV2Router02.sol"; import "./interfaces/IUniswapV2Pair.sol"; contract KarrotChefV3 is Ownable, ReentrancyGuard { //========================================================================= // SETUP //========================================================================= using SafeERC20 for IERC20; using Address for address; uint256 public constant taxFreeRequestId = uint256(keccak256(abi.encodePacked("KARROT TAX EXEMPT (FOR COMPOUNDING)"))); //kek uint256 public constant REWARD_SCALING_FACTOR = 1e12; uint256 public constant KARROTS_DECIMALS = 1e18; struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint224 rewardDebt; // Reward debt. See explanation below. uint32 lockEndedTimestamp; // // pending reward = (user.amount * pool.accRewardPerShare) - user.rewardDebt // // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens: // 1. The pool's `accRewardPerShare` (and `lastRewardBlock`) gets updated. // 2. User receives the pending reward sent to his/her address. // 3. User's `amount` gets updated. // 4. User's `rewardDebt` gets updated. } struct PoolInfo { IERC20 lpToken; // Address of LP token contract. uint128 allocPoint; // How many allocation points assigned to this pool. Rewards to distribute per block. uint32 lastRewardBlock; // Last block number that Rewards distribution occurs. uint96 accRewardPerShare; // Accumulated Rewards per share. } IConfig public config; uint16 public karrotClaimTaxRate = 2500; // 25% uint16 public fullProtecProtocolLiqProportion = 3200; // "33"% uint24 public requestNonce; uint40 public startBlock; /** * @dev scales debase linearly, * s.t. 1e13 = 0.001% (~6.7%/day) debase per block, * 113 * 1e11 = 0.00113% (~7.5%/day) debase per block * 138 * 1e11 = 0.00138% (~9%/day) debase per block */ uint48 public debaseMultiplier = 138 * 1e11; uint64 public lastBlock; uint16 public constant PERCENTAGE_DENOMINATOR = 10000; uint8 public constant blockOffset = 1; //just to keep math safer maybe, so that user cant deposit on "block 0" uint88 public karrotRewardPerBlock = uint88(13_000_000 * KARROTS_DECIMALS); //13M karrots/block uint128 public totalAllocPoint = 0; bool public vaultDepositsAreOpen = false; //all vaults closed. (big/smol) bool public depositsPaused = false; //for pausing without resetting startblock /// @dev Info of each pool. PoolInfo[] public poolInfo; /// @dev Info of each user. mapping(uint256 => mapping(address => UserInfo)) public userInfo; /// @dev user's withdrawable rewards mapping(uint256 => mapping(address => uint256)) private userRewards; /// @dev Lock duration in seconds mapping(uint256 => uint256) public lockDurations; // Events event SetDepositsEnabled(bool enabled); event Deposit(address indexed user, uint256 indexed pid, uint256 amount); event Withdraw(address indexed user, uint256 indexed pid, uint256 amount); event RewardPaid(address indexed user, uint256 indexed pid, uint256 amount); event TaxPaid(address indexed user, uint256 indexed pid, uint256 amount); event SetRewardPerBlock(uint88 amount); event LogPoolAddition(uint256 indexed pid, uint256 allocPoint, IERC20 indexed lpToken); event SetAllocationPoint(uint256 indexed pid, uint256 allocPoint); event PoolUpdated(uint256 indexed pid, uint256 lastRewardBlock, uint256 lpSupply, uint256 accRewardPerShare); event SetLockDuration(uint256 indexed pid, uint256 lockDuration); event Claim(address indexed user, uint256 indexed pid, uint256 amount, uint256 tax); event RewardQueued(address _account, uint256 _pid, uint256 pending); event Compound(address indexed user, uint256 amountKarrot, uint256 poolId); event TaxRatioUpdate(address indexed user, uint256 indexed newUserTaxRatio); error InvalidAllowance(); error EOAsOnly(); error RabbitsPerWalletLimitReached(); error NoPendingRewards(address user); error ForwardFailed(); error CallerIsNotConfig(); error VaultsDepositsAreClosed(); error CallerIsNotAccountOrThisContract(); error PoolExists(); error InvalidAmount(); error StillLocked(); constructor(address _configManager) Ownable() ReentrancyGuard() { config = IConfig(_configManager); IERC20(config.karrotsAddress()).safeApprove(config.karrotStolenPoolAddress(), type(uint).max); //default lockDurations lockDurations[0] = 1 days; lockDurations[1] = 1 days; } modifier onlyConfig() { if (msg.sender != address(config)) { revert CallerIsNotConfig(); } _; } //========================================================================= // ADMIN POOL ACTIONS //========================================================================= // Add a new lp to the pool. Can only be called by the owner. function addPool(uint128 _allocPoint, address _lpToken, bool _withUpdatePools) external onlyOwner { if(!lpTokenIsNotAlreadyAdded(_lpToken)){ revert PoolExists(); } if (_withUpdatePools) { massUpdatePools(); } uint256 lastRewardBlock = block.number > startBlock ? block.number : startBlock; totalAllocPoint = totalAllocPoint + _allocPoint; poolInfo.push( PoolInfo({ lpToken: IERC20(_lpToken), allocPoint: _allocPoint, lastRewardBlock: uint32(lastRewardBlock), accRewardPerShare: 0 }) ); emit LogPoolAddition(poolInfo.length - 1, _allocPoint, IERC20(_lpToken)); } // Update reward vairables for all pools. Be careful of gas spending! function massUpdatePools() public { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { updatePool(pid); } } function lpTokenIsNotAlreadyAdded(address _lpToken) internal view returns (bool) { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { if (address(poolInfo[pid].lpToken) == _lpToken) { return false; } } return true; } // Update reward variables of the given pool to be up-to-date. function updatePool(uint256 _pid) public { PoolInfo storage pool = poolInfo[_pid]; uint256 lpSupply; if(address(pool.lpToken) == address(0)){ return; } if (block.number <= pool.lastRewardBlock) { return; } if (address(pool.lpToken) == config.karrotsAddress()) { lpSupply = IKarrotsToken(config.karrotsAddress()).balanceOfUnderlying(address(this)); } else { lpSupply = pool.lpToken.balanceOf(address(this)); } if (lpSupply == 0) { pool.lastRewardBlock = uint32(block.number); return; } uint256 karrotsReward = Math.mulDiv( block.number - pool.lastRewardBlock, karrotRewardPerBlock * pool.allocPoint, totalAllocPoint ); pool.accRewardPerShare += uint96(Math.mulDiv(karrotsReward, REWARD_SCALING_FACTOR, lpSupply)); pool.lastRewardBlock = uint32(block.number); emit PoolUpdated(_pid, pool.lastRewardBlock, lpSupply, pool.accRewardPerShare); } //========================================================================= // USER ACTIONS //========================================================================= /// @dev Deposit tokens to KarrotsChef for Karrots allocation. /// @dev 1e18 in 1e24 out function deposit(uint256 _pid, uint256 _amount) public nonReentrant { if (!vaultDepositsAreOpen || depositsPaused) { revert VaultsDepositsAreClosed(); } if(_amount == 0){ revert InvalidAmount(); } PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; if(pool.lpToken.allowance(msg.sender, address(this)) < _amount){ revert InvalidAllowance(); } user.lockEndedTimestamp = uint32(block.timestamp + lockDurations[_pid]); updatePool(_pid); _queueRewards(_pid, msg.sender); pool.lpToken.safeTransferFrom(msg.sender, address(this), _amount); /// @dev 1e18-->1e24 if (address(pool.lpToken) == config.karrotsAddress()) { _amount = IKarrotsToken(config.karrotsAddress()).fragmentToKarrots(_amount); } /// @dev +n*1e24 user.amount += _amount; user.rewardDebt = uint224(Math.mulDiv(user.amount, pool.accRewardPerShare, REWARD_SCALING_FACTOR)); emit Deposit(msg.sender, _pid, _amount); emit TaxRatioUpdate(msg.sender, getFullToChefRatio(msg.sender)); } /// @dev Withdraw tokens from KarrotChef. /// @dev 1e24 in 1e18 out function withdraw(uint256 _pid, uint256 _amount) external nonReentrant { if(_amount == 0){ revert InvalidAmount(); } PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; if(user.lockEndedTimestamp > block.timestamp){ revert StillLocked(); } if(_amount > user.amount){ revert InvalidAmount(); } updatePool(_pid); _queueRewards(_pid, msg.sender); //expects 1e24 value user.amount -= _amount; //-n*1e24 user.rewardDebt = uint224((user.amount * pool.accRewardPerShare) / REWARD_SCALING_FACTOR); user.lockEndedTimestamp = uint32(block.timestamp) + uint32(lockDurations[_pid]); //1e24-->1e18 if (address(pool.lpToken) == config.karrotsAddress()) { _amount = IKarrotsToken(config.karrotsAddress()).karrotsToFragment(_amount); } pool.lpToken.safeTransfer(address(msg.sender), _amount); emit Withdraw(msg.sender, _pid, _amount); emit TaxRatioUpdate(msg.sender, getFullToChefRatio(msg.sender)); } function requestClaim(uint256 _pid) external payable nonReentrant { address sender = msg.sender; if (sender != tx.origin) { revert EOAsOnly(); } updatePool(_pid); _queueRewards(_pid, sender); if (userRewards[_pid][sender] == 0) { revert NoPendingRewards(sender); } uint256 randomNumber = IRandomizer(config.randomizerAddress()).getRandomNumber( sender, block.timestamp, requestNonce ); (uint256 rewards, uint256 tax) = _claim(_pid, sender, randomNumber, requestNonce, false); ++requestNonce; emit Claim(sender, _pid, rewards, tax); } /// @dev claims pending karrot rewards in smol protec vault tax-free, then immediately deposits back into smol protec vault function compoundSmol() external { uint256 _randomNumber = 0; (uint256 rewards, ) = _claim(1, msg.sender, _randomNumber, taxFreeRequestId, true); deposit(1, rewards); emit Compound(msg.sender, rewards, 1); } //========================================================================= // INTERNAL WRITE FUNCTIONS //========================================================================= /// @dev Claim Karrots from KarrotChef function _claim( uint256 _pid, address _account, uint256 _randomNumber, uint256 _requestId, bool callerIsCompounder ) internal returns ( uint256, uint256 ) { uint256 tax = 0; //to avoid double queueing when calls are made through requestClaim if(_requestId == taxFreeRequestId){ updatePool(_pid); _queueRewards(_pid, _account); } uint256 pendingRewards = userRewards[_pid][_account]; if (pendingRewards == 0) { revert NoPendingRewards(_account); } IKarrotsToken karrots = IKarrotsToken(config.karrotsAddress()); UserInfo storage user = userInfo[_pid][_account]; user.lockEndedTimestamp = uint32(block.timestamp) + uint32(lockDurations[_pid]); userRewards[_pid][_account] = 0; userInfo[_pid][_account].rewardDebt = uint224( (userInfo[_pid][_account].amount * poolInfo[_pid].accRewardPerShare) / (REWARD_SCALING_FACTOR)); if (lastBlock != block.number) { uint256 debaseIndexDelta = Math.mulDiv(block.number - lastBlock, debaseMultiplier, 1); karrots.rebase(block.number, debaseIndexDelta, false); lastBlock = uint64(block.number); IUniswapV2Pair(config.karrotsPoolAddress()).sync(); } //[!] if user has enough deposited into the Full Protec Pool, no withdrawal tax //if they don't, there will be a 33% tax on their claim //the taxed amount will be sent to the stolen pool if (userIsExemptFromClaimTax(_account) || _requestId == taxFreeRequestId) { karrots.mint(_account, pendingRewards); emit RewardPaid(_account, _pid, pendingRewards); } else { tax = Math.mulDiv(pendingRewards, karrotClaimTaxRate, PERCENTAGE_DENOMINATOR); karrots.mint(_account, pendingRewards - tax); IStolenPool(config.karrotStolenPoolAddress()).virtualDeposit(tax); emit TaxPaid(config.karrotStolenPoolAddress(), _pid, tax); emit RewardPaid(_account, _pid, pendingRewards - tax); } return (pendingRewards, tax); } function _queueRewards(uint256 _pid, address _account) private { UserInfo storage user = userInfo[_pid][_account]; uint256 pendingRewards = Math.mulDiv(user.amount, poolInfo[_pid].accRewardPerShare, REWARD_SCALING_FACTOR) - user.rewardDebt; if (pendingRewards > 0) { userRewards[_pid][_account] += pendingRewards; } emit RewardQueued(_account, _pid, pendingRewards); } //========================================================================= // GETTERS //========================================================================= function poolLength() external view returns (uint256) { return poolInfo.length; } // View function to see pending Karrots on frontend. function pendingReward(uint256 _pid, address _user) external view returns (uint256) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accRewardPerShare = pool.accRewardPerShare; uint256 lpSupply = pool.lpToken.balanceOf(address(this)); if (address(pool.lpToken) == config.karrotsAddress()) { lpSupply = IKarrotsToken(config.karrotsAddress()).balanceOfUnderlying(address(this)); } if (block.number > pool.lastRewardBlock && lpSupply != 0) { uint256 karrotsReward = (block.number - pool.lastRewardBlock) * Math.mulDiv(karrotRewardPerBlock, pool.allocPoint, totalAllocPoint); accRewardPerShare += (karrotsReward * REWARD_SCALING_FACTOR) / lpSupply; } return userRewards[_pid][_user] + (user.amount * accRewardPerShare / REWARD_SCALING_FACTOR) - user.rewardDebt; } ///@dev check both threshold karrot amount in full protec, and % of total karrots in all vaults in full protec to be above 33% (or n%) function userIsExemptFromClaimTax(address _user) public view returns (bool) { IFullProtec fullProtec = IFullProtec(config.karrotFullProtecAddress()); bool thresholdCheck = fullProtec.getIsUserAboveThresholdToAvoidClaimTax(_user); uint256 karrotsInFullProtec = fullProtec.getUserStakedAmount(_user); uint256 karrotsInBigAndSmol = getBigAndSmolKarrotEquivalent(_user); if(karrotsInBigAndSmol == 0) return thresholdCheck; uint256 karrotsInFullProtecRatio = Math.mulDiv(karrotsInFullProtec, PERCENTAGE_DENOMINATOR, karrotsInBigAndSmol); bool ratioCheck = karrotsInFullProtecRatio > fullProtecProtocolLiqProportion; if(thresholdCheck && ratioCheck) { return true; } return false; } /// @dev for UI - output the ratio of full / smol+big(equivalent) which determines whether user is exempt function getFullToChefRatio(address _user) public view returns (uint256) { IFullProtec fullProtec = IFullProtec(config.karrotFullProtecAddress()); uint256 karrotsInFullProtec = fullProtec.getUserStakedAmount(_user); uint256 karrotsInBigAndSmol = getBigAndSmolKarrotEquivalent(_user); if(karrotsInBigAndSmol == 0) return karrotsInFullProtec; return Math.mulDiv(karrotsInFullProtec, PERCENTAGE_DENOMINATOR, karrotsInBigAndSmol); } function getBigAndSmolKarrotEquivalent(address _user) public view returns (uint256) { uint256 bigProtecKarrotEquivalentAmount = getKarrotEquivalent(getTotalAmountStakedInPoolByUser(0, _user)); uint256 smolProtecAmount = getTotalAmountStakedInPoolByUser(1, _user); return bigProtecKarrotEquivalentAmount + smolProtecAmount; } /** * @dev returns the amount of karrots corresponding to the given amount of LP tokens * @param _amount the amount of LP tokens to convert to karrots */ function getKarrotEquivalent(uint256 _amount) public view returns (uint256) { if(_amount == 0) return 0; IUniswapV2Pair karrotsEthPool = IUniswapV2Pair(config.karrotsPoolAddress()); uint256 totalLpTokenSupply = karrotsEthPool.totalSupply(); (uint112 _reserve0, uint112 _reserve1, ) = karrotsEthPool.getReserves(); address token0 = karrotsEthPool.token0(); address token1 = karrotsEthPool.token1(); uint256 tokenReserve = 0; if(token0 == config.karrotsAddress()){ tokenReserve = uint256(_reserve0); } else if(token1 == config.karrotsAddress()){ tokenReserve = uint256(_reserve1); } // Calculate the ERC20 token equivalent for the given _amount of LP tokens return Math.mulDiv(_amount, tokenReserve, totalLpTokenSupply); } /** * @dev gets converted (wallet-visible, 10^18 units) amounts for each pool * @param _user the user to get the amounts for * @param _pid the pool id to get the amounts for */ function getTotalAmountStakedInPoolByUser(uint256 _pid, address _user) public view returns (uint256) { if(_pid == 1){ return IKarrotsToken(config.karrotsAddress()).karrotsToFragment(userInfo[_pid][_user].amount); } else { return userInfo[_pid][_user].amount; } } /// @dev get the address of the token corresponding to each pool, so karrot-ETH LP (0), karrot (1) function poolIdToToken(uint256 _pid) external view returns (address) { return address(poolInfo[_pid].lpToken); } /// @dev get 10^24 units of the total amount of karrots staked in the given pool function getUserInfoAmount(address _user, uint256 _pid) external view returns (uint256) { return userInfo[_pid][_user].amount; } //========================================================================= // SETTERS (CONFIG MANAGER CONTROLLED) //========================================================================= // Update the given pool's Karrots allocation point. Can only be called by the config manager. function setAllocationPoint(uint256 _pid, uint128 _allocPoint, bool _withUpdatePools) external onlyConfig { if (_withUpdatePools) { massUpdatePools(); } totalAllocPoint = totalAllocPoint - uint128(poolInfo[_pid].allocPoint) + _allocPoint; poolInfo[_pid].allocPoint = _allocPoint; emit SetAllocationPoint(_pid, _allocPoint); } function setLockDuration(uint256 _pid, uint256 _lockDuration) external onlyConfig { lockDurations[_pid] = _lockDuration; emit SetLockDuration(_pid, _lockDuration); } function updateRewardPerBlock(uint88 _rewardPerBlock) external onlyConfig { massUpdatePools(); karrotRewardPerBlock = _rewardPerBlock; emit SetRewardPerBlock(_rewardPerBlock); } function setDebaseMultiplier(uint48 _debaseMultiplier) external onlyConfig { debaseMultiplier = _debaseMultiplier; } function openKarrotChefDeposits() external onlyConfig { startBlock = uint40(block.number - blockOffset); lastBlock = startBlock; vaultDepositsAreOpen = true; emit SetDepositsEnabled(true); } function setDepositIsPaused(bool _isPaused) external onlyConfig { depositsPaused = _isPaused; emit SetDepositsEnabled(_isPaused); } function setClaimTaxRate(uint16 _maxTaxRate) external onlyConfig { karrotClaimTaxRate = _maxTaxRate; } function setFullProtecLiquidityProportion(uint16 _fullProtecLiquidityProportion) external onlyConfig { fullProtecProtocolLiqProportion = _fullProtecLiquidityProportion; } function setConfigManagerAddress(address _configManagerAddress) external onlyOwner { config = IConfig(_configManagerAddress); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to * 0 before setting it to a non-zero value. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/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() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(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"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^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() { _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 making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.19; interface IRandomizer { function getRandomNumber(address input0, uint256 input1, uint256 input2) external returns (uint256 result); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; interface IConfig { function dexInterfacerAddress() external view returns (address); function karrotsAddress() external view returns (address); function karrotChefAddress() external view returns (address); function karrotStolenPoolAddress() external view returns (address); function karrotFullProtecAddress() external view returns (address); function karrotsPoolAddress() external view returns (address); function rabbitAddress() external view returns (address); function randomizerAddress() external view returns (address); function uniswapRouterAddress() external view returns (address); function uniswapFactoryAddress() external view returns (address); function treasuryAddress() external view returns (address); function treasuryBAddress() external view returns (address); function teamSplitterAddress() external view returns (address); function presaleDistributorAddress() external view returns (address); function airdropDistributorAddress() external view returns (address); function attackRewardCalculatorAddress() external view returns (address); }
//SPDX-License-Identifier: MIT pragma solidity 0.8.19; interface IKarrotsToken { function approve(address spender, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function addDexAddress(address _dexAddress) external; function removeDexAddress(address _dexAddress) external; function mint(address to, uint256 amount) external; function burn(uint256 amount) external; function burnFrom(address account, uint256 amount) external; function rebase(uint256 epoch, uint256 indexDelta, bool positive) external returns (uint256); function balanceOf(address account) external view returns (uint256); function totalSupply() external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); function transferUnderlying(address to, uint256 value) external returns (bool); function fragmentToKarrots(uint256 value) external view returns (uint256); function karrotsToFragment(uint256 karrots) external view returns (uint256); function balanceOfUnderlying(address who) external view returns (uint256); function setSellTaxRate(uint16 _sellTaxRate) external; function setBuyTaxRate(uint16 _buyTaxRate) external; function setMaxScaleFactorDecreasePercentagePerDebase(uint256 _maxScaleFactorDecreasePercentagePerDebase) external; function setTaxSwapAmountThreshold(uint256 _taxSwapAmountThreshold) external; function setDivertTaxToStolenPoolRate(uint256 _divertRate) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; interface IFullProtec { function getUserStakedAmount(address _user) external view returns (uint256); function getTotalStakedAmount() external view returns (uint256); function getIsUserAboveThresholdToAvoidClaimTax(address _user) external view returns (bool); function updateConfig() external; function openFullProtecDeposits() external; function setFullProtecLockDuration(uint32 _lockDuration) external; function setThresholdFullProtecKarrotBalance(uint224 _thresholdFullProtecKarrotBalance) external; }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.19; interface IStolenPool { function virtualDeposit(uint256 _amount) external; function attack(address _sender, uint256 _rabbitTier, uint256 _rabbitId) external; function updateConfig() external; function setStolenPoolOpenTimestamp() external; function setStolenPoolAttackIsOpen(bool _isOpen) external; function setAttackBurnPercentage(uint16 _attackBurnPercentage) external; function setIsApprovedDepositor(address _depositor, bool _isApproved) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; import "./IUniswapV2Router01.sol"; interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.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 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) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable returns (uint[] memory amounts); function swapTokensForExactETH( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactTokensForETH( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapETHForExactTokens( uint amountOut, address[] calldata path, address to, uint deadline ) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); }
{ "remappings": [ "@chainlink/contracts/=lib/chainlink/contracts/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "foundry-devops/=lib/foundry-devops/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "openzeppelin/=lib/openzeppelin-contracts/contracts/" ], "optimizer": { "enabled": true, "runs": 200, "details": { "constantOptimizer": true, "yul": true, "yulDetails": { "stackAllocation": true, "optimizerSteps": "dhfoDgvulfnTUtnIf" } } }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": { "lib/foundry-devops/src/DevOpsTools.sol": { "DevOpsTools": "0x3fd2b64a587cc58117db334fbd51c58d256adac5" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_configManager","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CallerIsNotAccountOrThisContract","type":"error"},{"inputs":[],"name":"CallerIsNotConfig","type":"error"},{"inputs":[],"name":"EOAsOnly","type":"error"},{"inputs":[],"name":"ForwardFailed","type":"error"},{"inputs":[],"name":"InvalidAllowance","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"NoPendingRewards","type":"error"},{"inputs":[],"name":"PoolExists","type":"error"},{"inputs":[],"name":"RabbitsPerWalletLimitReached","type":"error"},{"inputs":[],"name":"StillLocked","type":"error"},{"inputs":[],"name":"VaultsDepositsAreClosed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tax","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountKarrot","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"poolId","type":"uint256"}],"name":"Compound","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"},{"indexed":true,"internalType":"contract IERC20","name":"lpToken","type":"address"}],"name":"LogPoolAddition","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":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lpSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"accRewardPerShare","type":"uint256"}],"name":"PoolUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_account","type":"address"},{"indexed":false,"internalType":"uint256","name":"_pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pending","type":"uint256"}],"name":"RewardQueued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"}],"name":"SetAllocationPoint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"SetDepositsEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lockDuration","type":"uint256"}],"name":"SetLockDuration","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint88","name":"amount","type":"uint88"}],"name":"SetRewardPerBlock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TaxPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"newUserTaxRatio","type":"uint256"}],"name":"TaxRatioUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"KARROTS_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERCENTAGE_DENOMINATOR","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_SCALING_FACTOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"_allocPoint","type":"uint128"},{"internalType":"address","name":"_lpToken","type":"address"},{"internalType":"bool","name":"_withUpdatePools","type":"bool"}],"name":"addPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"blockOffset","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"compoundSmol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"config","outputs":[{"internalType":"contract IConfig","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"debaseMultiplier","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositsPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fullProtecProtocolLiqProportion","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getBigAndSmolKarrotEquivalent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getFullToChefRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"getKarrotEquivalent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"getTotalAmountStakedInPoolByUser","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"getUserInfoAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"karrotClaimTaxRate","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"karrotRewardPerBlock","outputs":[{"internalType":"uint88","name":"","type":"uint88"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastBlock","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lockDurations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"openKarrotChefDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"poolIdToToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IERC20","name":"lpToken","type":"address"},{"internalType":"uint128","name":"allocPoint","type":"uint128"},{"internalType":"uint32","name":"lastRewardBlock","type":"uint32"},{"internalType":"uint96","name":"accRewardPerShare","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"requestClaim","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestNonce","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint128","name":"_allocPoint","type":"uint128"},{"internalType":"bool","name":"_withUpdatePools","type":"bool"}],"name":"setAllocationPoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_maxTaxRate","type":"uint16"}],"name":"setClaimTaxRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_configManagerAddress","type":"address"}],"name":"setConfigManagerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"_debaseMultiplier","type":"uint48"}],"name":"setDebaseMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isPaused","type":"bool"}],"name":"setDepositIsPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_fullProtecLiquidityProportion","type":"uint16"}],"name":"setFullProtecLiquidityProportion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_lockDuration","type":"uint256"}],"name":"setLockDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startBlock","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxFreeRequestId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint88","name":"_rewardPerBlock","type":"uint88"}],"name":"updateRewardPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint224","name":"rewardDebt","type":"uint224"},{"internalType":"uint32","name":"lockEndedTimestamp","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"userIsExemptFromClaimTax","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultDepositsAreOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405260028054630320027160a21b63ffffffff60a01b199091161790556003805465ffffffffffff1916650c8d101910001790556200004d670de0b6b3a764000062c65d4062000564565b600380546001600160581b0392909216600160701b02600160701b600160c81b0319909216919091179055600480546001600160901b03191690553480156200009557600080fd5b50604051620049c5380380620049c5833981016040819052620000b891620005bd565b620000c3336200022a565b60018055600280546001600160a01b0319166001600160a01b03831690811790915560408051631b90185960e31b81529051620001cf929163dc80c2c89160048083019260209291908290030181865afa15801562000126573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200014c9190620005bd565b60025460408051630a15a2e160e41b81529051600019926001600160a01b03169163a15a2e109160048083019260209291908290030181865afa15801562000198573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001be9190620005bd565b6001600160a01b031691906200027a565b506008602052620151807f5eff886ea0ce6ca488a3d6e336d6c0f75f46d19b42c06ce5ee98e42c96d256c781905560016000527fad67d757c34507f157cacfa2e3153e9f260a2244f30428821be7be64587ac55f556200089f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b801580620002f95750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90620002b39030908690600401620005f3565b602060405180830381865afa158015620002d1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f7919062000626565b155b620003215760405162461bcd60e51b81526004016200031890620006a5565b60405180910390fd5b6200037c8363095ea7b360e01b848460405160240162000343929190620006be565b60408051808303601f190181529190526020810180516001600160e01b0319939093166001600160e01b03938416179052906200038116565b505050565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620003d0906001600160a01b03851690849062000413565b9050805160001480620003f4575080806020019051810190620003f49190620006f3565b6200037c5760405162461bcd60e51b815260040162000318906200075e565b60606200042484846000856200042e565b90505b9392505050565b606082471015620004535760405162461bcd60e51b81526004016200031890620007b2565b600080866001600160a01b031685876040516200047191906200080f565b60006040518083038185875af1925050503d8060008114620004b0576040519150601f19603f3d011682016040523d82523d6000602084013e620004b5565b606091505b509092509050620004c987838387620004d6565b925050505b949350505050565b606083156200051b57825160000362000513576001600160a01b0385163b620005135760405162461bcd60e51b815260040162000318906200081b565b5081620004ce565b620004ce8383815115620005325781518083602001fd5b8060405162461bcd60e51b81526004016200031891906200088c565b634e487b7160e01b600052601160045260246000fd5b81810281158282048414176200057e576200057e6200054e565b92915050565b60006001600160a01b0382166200057e565b620005a18162000584565b8114620005ad57600080fd5b50565b80516200057e8162000596565b600060208284031215620005d457620005d4600080fd5b6000620004ce8484620005b0565b620005ed8162000584565b82525050565b60408101620006038285620005e2565b620004276020830184620005e2565b80620005a1565b80516200057e8162000612565b6000602082840312156200063d576200063d600080fd5b6000620004ce848462000619565b60368152602081017f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f81527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000602082015290505b60400190565b602080825281016200057e816200064b565b80620005ed565b60408101620006ce8285620005e2565b620004276020830184620006b7565b801515620005a1565b80516200057e81620006dd565b6000602082840312156200070a576200070a600080fd5b6000620004ce8484620006e6565b602a8152602081017f5361666545524332303a204552433230206f7065726174696f6e20646964206e8152691bdd081cdd58d8d9595960b21b602082015290506200069f565b602080825281016200057e8162000718565b60268152602081017f416464726573733a20696e73756666696369656e742062616c616e636520666f8152651c8818d85b1b60d21b602082015290506200069f565b602080825281016200057e8162000770565b60005b83811015620007e1578181015183820152602001620007c7565b50506000910152565b6000620007f5825190565b62000805818560208601620007c4565b9290920192915050565b6200057e8183620007ea565b602080825281016200057e81601d81527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000602082015260400190565b600062000862825190565b8084526020840193506200087b818560208601620007c4565b601f01601f19169290920192915050565b6020808252810162000427818462000857565b61411680620008af6000396000f3fe6080604052600436106102885760003560e01c8063792764401161015a578063b3cd4254116100c1578063e0188de81161007a578063e0188de81461084e578063e2bbb1581461086e578063e7a647651461088e578063f251b75c146108ba578063f2fde38b146108da578063fac1ab30146108fa57600080fd5b8063b3cd4254146107a5578063b8bfd029146107bb578063c9cc52d9146107db578063d8b63f31146107fb578063dd8dc5de1461081b578063e00b288a1461083b57600080fd5b806391f143331161011357806391f143331461069057806393f1a40b146106b057806398969e82146107165780639aca5176146107365780639dce9f9c14610758578063a6a80a901461078c57600080fd5b8063792764401461058857806379502c55146105a85780637c1a0302146105d55780637e2c3c4114610605578063806b984f146106345780638da5cb5b1461066957600080fd5b8063441a3e70116101fe578063538fb492116101b7578063538fb492146104f357806360da3e8314610508578063630b5ba1146105295780636a3578051461053e5780636bb35dd01461055e578063715018a61461057357600080fd5b8063441a3e701461041f57806346bf6a551461043f57806348cd4cb1146104615780634a3b934b1461049357806351eb05a6146104b35780635318bea3146104d357600080fd5b806318424eb51161025057806318424eb51461035357806324d0cec71461036f57806332298be114610384578063345c8b4d146103b15780633d792125146103df57806340f7f836146103ff57600080fd5b8063081e3eda1461028d57806309fae4b9146102b4578063126796dd146102d65780631526fe27146102f657806317caf6f114610326575b600080fd5b34801561029957600080fd5b506005545b6040516102ab91906135d3565b60405180910390f35b3480156102c057600080fd5b506102d46102cf3660046135fd565b61091a565b005b3480156102e257600080fd5b506102d46102f136600461362f565b610967565b34801561030257600080fd5b5061031661031136600461366c565b6109e1565b6040516102ab94939291906136f9565b34801561033257600080fd5b50600454610346906001600160801b031681565b6040516102ab919061372e565b34801561035f57600080fd5b5061029e670de0b6b3a764000081565b34801561037b57600080fd5b5061029e610a42565b34801561039057600080fd5b5061029e61039f36600461366c565b60086020526000908152604090205481565b3480156103bd57600080fd5b506004546103d290600160801b900460ff1681565b6040516102ab9190613744565b3480156103eb57600080fd5b5061029e6103fa366004613777565b610a6d565b34801561040b57600080fd5b506102d461041a3660046137ac565b610a97565b34801561042b57600080fd5b506102d461043a36600461362f565b610b14565b34801561044b57600080fd5b50610454600181565b6040516102ab91906137d6565b34801561046d57600080fd5b5060025461048690600160d81b900464ffffffffff1681565b6040516102ab91906137f1565b34801561049f57600080fd5b506102d46104ae366004613819565b610e98565b3480156104bf57600080fd5b506102d46104ce36600461366c565b610fc8565b3480156104df57600080fd5b506102d46104ee366004613882565b611365565b3480156104ff57600080fd5b506102d46113b0565b34801561051457600080fd5b506004546103d290600160881b900460ff1681565b34801561053557600080fd5b506102d4611433565b34801561054a57600080fd5b506103d26105593660046138a3565b61145a565b34801561056a57600080fd5b506102d4611624565b34801561057f57600080fd5b506102d46116f7565b34801561059457600080fd5b506102d46105a33660046138de565b61170b565b3480156105b457600080fd5b506002546105c8906001600160a01b031681565b6040516102ab91906138ff565b3480156105e157600080fd5b506002546105f890600160c01b900462ffffff1681565b6040516102ab9190613918565b34801561061157600080fd5b5060025461062790600160b01b900461ffff1681565b6040516102ab9190613930565b34801561064057600080fd5b5060035461065c90600160301b900467ffffffffffffffff1681565b6040516102ab919061394e565b34801561067557600080fd5b506000546001600160a01b03165b6040516102ab9190613965565b34801561069c57600080fd5b506102d46106ab3660046135fd565b611796565b3480156106bc57600080fd5b506107076106cb366004613973565b6006602090815260009283526040808420909152908252902080546001909101546001600160e01b03811690600160e01b900463ffffffff1683565b6040516102ab939291906139b5565b34801561072257600080fd5b5061029e610731366004613973565b6117e3565b34801561074257600080fd5b5060025461062790600160a01b900461ffff1681565b34801561076457600080fd5b5060035461077f90600160701b90046001600160581b031681565b6040516102ab91906139ec565b34801561079857600080fd5b5061029e64e8d4a5100081565b3480156107b157600080fd5b5061062761271081565b3480156107c757600080fd5b5061029e6107d63660046138a3565b611b3d565b3480156107e757600080fd5b506106836107f636600461366c565b611b71565b34801561080757600080fd5b5061029e6108163660046138a3565b611ba6565b34801561082757600080fd5b506102d46108363660046138a3565b611cc6565b6102d461084936600461366c565b611cf0565b34801561085a57600080fd5b506102d46108693660046139fa565b611f24565b34801561087a57600080fd5b506102d461088936600461362f565b612100565b34801561089a57600080fd5b506003546108ad9065ffffffffffff1681565b6040516102ab9190613a3d565b3480156108c657600080fd5b5061029e6108d536600461366c565b6124a7565b3480156108e657600080fd5b506102d46108f53660046138a3565b612819565b34801561090657600080fd5b5061029e610915366004613973565b612850565b6002546001600160a01b03163314610945576040516340e2203b60e01b815260040160405180910390fd5b6002805461ffff909216600160b01b0261ffff60b01b19909216919091179055565b6002546001600160a01b03163314610992576040516340e2203b60e01b815260040160405180910390fd5b600082815260086020526040908190208290555182907f84335b44fa6b10da53c37ff36b055274c2cddf15beac71eaff143f8ce17c7264906109d59084906135d3565b60405180910390a25050565b600581815481106109f157600080fd5b6000918252602090912060029091020180546001909101546001600160a01b0390911691506001600160801b03811690600160801b810463ffffffff1690600160a01b90046001600160601b031684565b604051602001610a5190613a4b565b6040516020818303038152906040528051906020012060001c81565b60008181526006602090815260408083206001600160a01b03861684529091529020545b92915050565b6002546001600160a01b03163314610ac2576040516340e2203b60e01b815260040160405180910390fd5b6004805460ff60881b1916600160881b831515021790556040517f5b00cce3d56020349f502ff1cae2758ad29977252c146a4177392ea2a145183c90610b09908390613744565b60405180910390a150565b610b1c612988565b80600003610b3d5760405163162908e360e11b815260040160405180910390fd5b600060058381548110610b5257610b52613a80565b6000918252602080832086845260068252604080852033865290925292206001810154600292909202909201925042600160e01b90910463ffffffff161115610bae57604051636100d92960e11b815260040160405180910390fd5b8054831115610bd05760405163162908e360e11b815260040160405180910390fd5b610bd984610fc8565b610be384336129b1565b82816000016000828254610bf79190613aac565b90915550506001820154815464e8d4a5100091610c2591600160a01b9091046001600160601b031690613abf565b610c2f9190613aec565b6001820180546001600160e01b0319166001600160e01b0392909216919091179055600084815260086020526040902054610c6a9042613b00565b81600101601c6101000a81548163ffffffff021916908363ffffffff160217905550600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d039190613b2b565b82546001600160a01b03918216911603610dfd57600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8e9190613b2b565b6001600160a01b031663b15587df846040518263ffffffff1660e01b8152600401610db991906135d3565b602060405180830381865afa158015610dd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfa9190613b57565b92505b8154610e13906001600160a01b03163385612abd565b83336001600160a01b03167ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b56885604051610e4d91906135d3565b60405180910390a3610e5e33611ba6565b60405133907fbc2cf4e8ce91f01aed81a9be00bcc8c01f8510820e7c5b9ec3c1eb919a4c2f5490600090a35050610e9460018055565b5050565b6002546001600160a01b03163314610ec3576040516340e2203b60e01b815260040160405180910390fd5b8015610ed157610ed1611433565b8160058481548110610ee557610ee5613a80565b6000918252602090912060016002909202010154600454610f12916001600160801b039081169116613b78565b610f1c9190613b9b565b600460006101000a8154816001600160801b0302191690836001600160801b031602179055508160058481548110610f5657610f56613a80565b906000526020600020906002020160010160006101000a8154816001600160801b0302191690836001600160801b03160217905550827f67032c5b22da4ed0669c2ae3261730d3ac9176e7de1b22d495b32ded5ccf3e2383604051610fbb9190613bdc565b60405180910390a2505050565b600060058281548110610fdd57610fdd613a80565b60009182526020822060029091020180549092506001600160a01b031661100357505050565b6001820154600160801b900463ffffffff16431161102057505050565b600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa158015611073573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110979190613b2b565b82546001600160a01b0391821691160361119557600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111229190613b2b565b6001600160a01b0316633af9e669306040518263ffffffff1660e01b815260040161114d9190613965565b602060405180830381865afa15801561116a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118e9190613b57565b9050611208565b81546040516370a0823160e01b81526001600160a01b03909116906370a08231906111c4903090600401613965565b602060405180830381865afa1580156111e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112059190613b57565b90505b806000036112335750600101805463ffffffff60801b1916600160801b4363ffffffff160217905550565b60018201546000906112969061125690600160801b900463ffffffff1643613aac565b6001850154600354611281916001600160801b031690600160701b90046001600160581b0316613bea565b6004546001600160801b039182169116612b18565b90506112a88164e8d4a5100084612b18565b6001840180546014906112cc908490600160a01b90046001600160601b0316613c17565b82546101009290920a6001600160601b0381810219909316918316021790915560018501805463ffffffff60801b1916600160801b4363ffffffff908116820292909217928390556040518995507fb0a2ded49817748754bcca0474b24011f01d4574dd5c40e14197ffa2e6540fef9461135794928304909316928892600160a01b90041690613c73565b60405180910390a250505050565b6002546001600160a01b03163314611390576040516340e2203b60e01b815260040160405180910390fd5b6003805465ffffffffffff191665ffffffffffff92909216919091179055565b6000806113e9600133846040516020016113c990613a4b565b6040516020818303038152906040528051906020012060001c6001612be0565b5090506113f7600182612100565b336001600160a01b03167f0e311a2c6dbfb0153ec3a8a5bdca09070b3e5f60768fdc10a20453f38d1868738260016040516109d5929190613cb0565b60055460005b81811015610e945761144a81610fc8565b61145381613ccb565b9050611439565b600080600260009054906101000a90046001600160a01b03166001600160a01b03166366b168276040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d49190613b2b565b90506000816001600160a01b0316632251e9a9856040518263ffffffff1660e01b81526004016115049190613965565b602060405180830381865afa158015611521573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115459190613cef565b90506000826001600160a01b03166394465b21866040518263ffffffff1660e01b81526004016115759190613965565b602060405180830381865afa158015611592573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b69190613b57565b905060006115c386611b3d565b9050806000036115d7575090949350505050565b60006115e68361271084612b18565b600254909150600160b01b900461ffff1681118480156116035750805b1561161657506001979650505050505050565b506000979650505050505050565b6002546001600160a01b0316331461164f576040516340e2203b60e01b815260040160405180910390fd5b61165a600143613aac565b6002805464ffffffffff928316600160d81b9081026001600160d81b03909216919091179182905560038054600160301b92909304909316026dffffffffffffffff000000000000199091161790556004805460ff60801b1916600160801b1790556040517f5b00cce3d56020349f502ff1cae2758ad29977252c146a4177392ea2a145183c906116ed90600190613744565b60405180910390a1565b6116ff613345565b611709600061336f565b565b6002546001600160a01b03163314611736576040516340e2203b60e01b815260040160405180910390fd5b61173e611433565b600380546affffffffffffffffffffff60701b1916600160701b6001600160581b038416021790556040517f9eb86a16326fe9c3a30ac874ce6693689603381218c2f8c3897f9d879724e16c90610b099083906139ec565b6002546001600160a01b031633146117c1576040516340e2203b60e01b815260040160405180910390fd5b6002805461ffff909216600160a01b0261ffff60a01b19909216919091179055565b600080600584815481106117f9576117f9613a80565b600091825260208083208784526006825260408085206001600160a01b03898116875293528085206002949094029091016001810154815492516370a0823160e01b81529196509394600160a01b9094046001600160601b0316939291909116906370a082319061186e903090600401613965565b602060405180830381865afa15801561188b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118af9190613b57565b9050600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa158015611904573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119289190613b2b565b84546001600160a01b03918216911603611a2257600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa15801561198f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b39190613b2b565b6001600160a01b0316633af9e669306040518263ffffffff1660e01b81526004016119de9190613965565b602060405180830381865afa1580156119fb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1f9190613b57565b90505b6001840154600160801b900463ffffffff1643118015611a4157508015155b15611acc576003546001850154600454600092611a7c92600160701b9091046001600160581b0316916001600160801b039182169116612b18565b6001860154611a9890600160801b900463ffffffff1643613aac565b611aa29190613abf565b905081611ab464e8d4a5100083613abf565b611abe9190613aec565b611ac89084613d10565b9250505b600183015483546001600160e01b039091169064e8d4a5100090611af1908590613abf565b611afb9190613aec565b60008981526007602090815260408083206001600160a01b038c168452909152902054611b289190613d10565b611b329190613aac565b979650505050505050565b600080611b4e6108d5600085612850565b90506000611b5d600185612850565b9050611b698183613d10565b949350505050565b600060058281548110611b8657611b86613a80565b60009182526020909120600290910201546001600160a01b031692915050565b600080600260009054906101000a90046001600160a01b03166001600160a01b03166366b168276040518163ffffffff1660e01b8152600401602060405180830381865afa158015611bfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c209190613b2b565b90506000816001600160a01b03166394465b21856040518263ffffffff1660e01b8152600401611c509190613965565b602060405180830381865afa158015611c6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c919190613b57565b90506000611c9e85611b3d565b905080600003611cb057509392505050565b611cbd8261271083612b18565b95945050505050565b611cce613345565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b611cf8612988565b33328114611d1957604051636033c79d60e01b815260040160405180910390fd5b611d2282610fc8565b611d2c82826129b1565b60008281526007602090815260408083206001600160a01b03851684529091528120549003611d795780604051630ce8b4bd60e31b8152600401611d709190613965565b60405180910390fd5b600254604080516369b5c8f960e01b815290516000926001600160a01b0316916369b5c8f99160048083019260209291908290030181865afa158015611dc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de79190613b2b565b6001600160a01b031663db3b390c8342600260189054906101000a900462ffffff166040518463ffffffff1660e01b8152600401611e2793929190613d3d565b6020604051808303816000875af1158015611e46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e6a9190613b57565b9050600080611e93858585600260189054906101000a900462ffffff1662ffffff166000612be0565b915091506002601881819054906101000a900462ffffff16611eb490613d65565b91906101000a81548162ffffff021916908362ffffff16021790555084846001600160a01b03167f45c072aa05b9853b5a993de7a28bc332ee01404a628cec1a23ce0f659f842ef18484604051611f0c929190613d7f565b60405180910390a350505050611f2160018055565b50565b611f2c613345565b611f35826133bf565b611f5257604051637a471e1360e11b815260040160405180910390fd5b8015611f6057611f60611433565b600254600090600160d81b900464ffffffffff164311611f9057600254600160d81b900464ffffffffff16611f92565b435b600454909150611fac9085906001600160801b0316613b9b565b600480546001600160801b039283166fffffffffffffffffffffffffffffffff19909116179055604080516080810182526001600160a01b038087168083528885166020840190815263ffffffff808816958501958652600060608601818152600580546001818101835593829052975160029098027f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0810180549989166001600160a01b03199a8b1617905594517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db19095018054995192516001600160601b0316600160a01b0292909416600160801b029890971693909816929092179590951790921694909417909255546120c39190613aac565b7f4710feb78e3bce8d2e3ca2989a8eb2f8bcd32a6a55b4535942c180fc4d2e2952866040516120f29190613bdc565b60405180910390a350505050565b612108612988565b600454600160801b900460ff16158061212a5750600454600160881b900460ff165b156121485760405163ca337b7f60e01b815260040160405180910390fd5b806000036121695760405163162908e360e11b815260040160405180910390fd5b60006005838154811061217e5761217e613a80565b600091825260208083208684526006825260408085203380875293529384902060029093020180549351636eb1769f60e11b8152909450919285926001600160a01b03919091169163dd62ed3e916121db91903090600401613d9a565b602060405180830381865afa1580156121f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221c9190613b57565b101561223b576040516365ba6fc360e01b815260040160405180910390fd5b6000848152600860205260409020546122549042613d10565b81600101601c6101000a81548163ffffffff021916908363ffffffff16021790555061227f84610fc8565b61228984336129b1565b81546122a0906001600160a01b031633308661342f565b600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123179190613b2b565b82546001600160a01b0391821691160361241157600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a29190613b2b565b6001600160a01b0316632e687671846040518263ffffffff1660e01b81526004016123cd91906135d3565b602060405180830381865afa1580156123ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240e9190613b57565b92505b828160000160008282546124259190613d10565b9091555050805460018301546124519190600160a01b90046001600160601b031664e8d4a51000612b18565b6001820180546001600160e01b0319166001600160e01b0392909216919091179055604051849033907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a1590610e4d9087906135d3565b6000816000036124b957506000919050565b600254604080516307336a7960e41b815290516000926001600160a01b031691637336a7909160048083019260209291908290030181865afa158015612503573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125279190613b2b565b90506000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612569573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258d9190613b57565b9050600080836001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156125d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125f49190613de6565b50915091506000846001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015612639573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061265d9190613b2b565b90506000856001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561269f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c39190613b2b565b90506000600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa15801561271a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061273e9190613b2b565b6001600160a01b0316836001600160a01b03160361276657506001600160701b038416612801565b600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127dd9190613b2b565b6001600160a01b0316826001600160a01b03160361280157506001600160701b0383165b61280c898288612b18565b9998505050505050505050565b612821613345565b6001600160a01b0381166128475760405162461bcd60e51b8152600401611d7090613e6f565b611f218161336f565b60008260010361295f57600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128d19190613b2b565b60008481526006602090815260408083206001600160a01b03878116855292529182902054915163b15587df60e01b815292169163b15587df91612917916004016135d3565b602060405180830381865afa158015612934573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129589190613b57565b9050610a91565b5060008281526006602090815260408083206001600160a01b0385168452909152902054610a91565b6002600154036129aa5760405162461bcd60e51b8152600401611d7090613eb3565b6002600155565b60008281526006602090815260408083206001600160a01b0385168452909152812060018101548154600580549394936001600160e01b0390931692612a3292919088908110612a0357612a03613a80565b6000918252602090912060029091020160010154600160a01b90046001600160601b031664e8d4a51000612b18565b612a3c9190613aac565b90508015612a7c5760008481526007602090815260408083206001600160a01b038716845290915281208054839290612a76908490613d10565b90915550505b7f09a4f557033a56cbe70db5ccef9534cbb73cbfe724512852e36e86e36d7a93b4838583604051612aaf93929190613ec3565b60405180910390a150505050565b612b138363a9059cbb60e01b8484604051602401612adc929190613eeb565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613456565b505050565b6000808060001985870985870292508281108382030391505080600003612b5257838281612b4857612b48613ad6565b0492505050612bd9565b808411612b715760405162461bcd60e51b8152600401611d7090613f23565b600084868809851960019081018716968790049682860381900495909211909303600082900391909104909201919091029190911760038402600290811880860282030280860282030280860282030280860282030280860282030280860290910302029150505b9392505050565b6000806000604051602001612bf490613a4b565b6040516020818303038152906040528051906020012060001c8503612c2657612c1c88610fc8565b612c2688886129b1565b60008881526007602090815260408083206001600160a01b038b16845290915281205490819003612c6c5787604051630ce8b4bd60e31b8152600401611d709190613965565b60025460408051630a15a2e160e41b815290516000926001600160a01b03169163a15a2e109160048083019260209291908290030181865afa158015612cb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cda9190613b2b565b60008b81526006602090815260408083206001600160a01b038e16845282528083208e845260089092529091205491925090612d169042613b00565b60018201805463ffffffff92909216600160e01b026001600160e01b0390921691909117905560008b81526007602090815260408083206001600160a01b038e1684529091528120556005805464e8d4a5100091908d908110612d7b57612d7b613a80565b906000526020600020906002020160010160149054906101000a90046001600160601b03166001600160601b0316600660008e815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002060000154612ded9190613abf565b612df79190613aec565b60008c81526006602090815260408083206001600160a01b038f168452909152902060010180546001600160e01b0319166001600160e01b039290921691909117905560035443600160301b90910467ffffffffffffffff1614612fef57600354600090612e8c90612e7a90600160301b900467ffffffffffffffff1643613aac565b60035465ffffffffffff166001612b18565b604051637af548c160e01b81529091506001600160a01b03841690637af548c190612ec09043908590600090600401613f33565b6020604051808303816000875af1158015612edf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f039190613b57565b50600380546dffffffffffffffff0000000000001916600160301b4367ffffffffffffffff1602179055600254604080516307336a7960e41b815290516001600160a01b0390921691637336a790916004808201926020929091908290030181865afa158015612f77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f9b9190613b2b565b6001600160a01b031663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612fd557600080fd5b505af1158015612fe9573d6000803e3d6000fd5b50505050505b612ff88a61145a565b80613029575060405160200161300d90613a4b565b6040516020818303038152906040528051906020012060001c88145b156130d5576040516340c10f1960e01b81526001600160a01b038316906340c10f199061305c908d908790600401613eeb565b600060405180830381600087803b15801561307657600080fd5b505af115801561308a573d6000803e3d6000fd5b505050508a8a6001600160a01b03167fd6f2c8500df5b44f11e9e48b91ff9f1b9d81bc496d55570c2b1b75bf65243f51856040516130c891906135d3565b60405180910390a3613334565b6002546130f1908490600160a01b900461ffff16612710612b18565b93506001600160a01b0382166340c10f198b61310d8787613aac565b6040518363ffffffff1660e01b815260040161312a929190613eeb565b600060405180830381600087803b15801561314457600080fd5b505af1158015613158573d6000803e3d6000fd5b50505050600260009054906101000a90046001600160a01b03166001600160a01b031663dc80c2c86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131d39190613b2b565b6001600160a01b0316632278a902856040518263ffffffff1660e01b81526004016131fe91906135d3565b600060405180830381600087803b15801561321857600080fd5b505af115801561322c573d6000803e3d6000fd5b505050508a600260009054906101000a90046001600160a01b03166001600160a01b031663dc80c2c86040518163ffffffff1660e01b8152600401602060405180830381865afa158015613284573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132a89190613b2b565b6001600160a01b03167fb0a068ff9b2c6f72d5af72f3f94b79d10fe7995889678a9c0f6a33caa63cb4d2866040516132e091906135d3565b60405180910390a38a6001600160a01b038b167fd6f2c8500df5b44f11e9e48b91ff9f1b9d81bc496d55570c2b1b75bf65243f5161331e8787613aac565b60405161332b91906135d3565b60405180910390a35b509099919850909650505050505050565b6000546001600160a01b031633146117095760405162461bcd60e51b8152600401611d7090613f8b565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600554600090815b8181101561342557836001600160a01b0316600582815481106133ec576133ec613a80565b60009182526020909120600290910201546001600160a01b031603613415575060009392505050565b61341e81613ccb565b90506133c7565b5060019392505050565b613450846323b872dd60e01b858585604051602401612adc93929190613f9b565b50505050565b60006134ab826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134e89092919063ffffffff16565b90508051600014806134cc5750808060200190518101906134cc9190613cef565b612b135760405162461bcd60e51b8152600401611d7090613ffb565b6060611b69848460008585600080866001600160a01b0316858760405161350f9190614051565b60006040518083038185875af1925050503d806000811461354c576040519150601f19603f3d011682016040523d82523d6000602084013e613551565b606091505b5091509150611b32878383876060831561359c578251600003613595576001600160a01b0385163b6135955760405162461bcd60e51b8152600401611d709061408d565b5081611b69565b611b6983838151156135b15781518083602001fd5b8060405162461bcd60e51b8152600401611d7091906140cf565b805b82525050565b60208101610a9182846135cb565b61ffff81165b8114611f2157600080fd5b8035610a91816135e1565b60006020828403121561361257613612600080fd5b6000611b6984846135f2565b806135e7565b8035610a918161361e565b6000806040838503121561364557613645600080fd5b60006136518585613624565b925050602061366285828601613624565b9150509250929050565b60006020828403121561368157613681600080fd5b6000611b698484613624565b6000610a916001600160a01b0383166136a4565b90565b6001600160a01b031690565b6000610a918261368d565b6000610a91826136b0565b6135cd816136bb565b6001600160801b0381166135cd565b63ffffffff81166135cd565b6001600160601b0381166135cd565b6080810161370782876136c6565b61371460208301866136cf565b61372160408301856136de565b611cbd60608301846136ea565b60208101610a9182846136cf565b8015156135cd565b60208101610a91828461373c565b60006001600160a01b038216610a91565b6135e781613752565b8035610a9181613763565b6000806040838503121561378d5761378d600080fd5b6000613651858561376c565b8015156135e7565b8035610a9181613799565b6000602082840312156137c1576137c1600080fd5b6000611b6984846137a1565b60ff81166135cd565b60208101610a9182846137cd565b64ffffffffff81166135cd565b60208101610a9182846137e4565b6001600160801b0381166135e7565b8035610a91816137ff565b60008060006060848603121561383157613831600080fd5b600061383d8686613624565b935050602061384e8682870161380e565b925050604061385f868287016137a1565b9150509250925092565b65ffffffffffff81166135e7565b8035610a9181613869565b60006020828403121561389757613897600080fd5b6000611b698484613877565b6000602082840312156138b8576138b8600080fd5b6000611b69848461376c565b6001600160581b0381166135e7565b8035610a91816138c4565b6000602082840312156138f3576138f3600080fd5b6000611b6984846138d3565b60208101610a9182846136c6565b62ffffff81166135cd565b60208101610a91828461390d565b61ffff81166135cd565b60208101610a918284613926565b67ffffffffffffffff81166135cd565b60208101610a91828461393e565b6135cd81613752565b60208101610a91828461395c565b6000806040838503121561398957613989600080fd5b60006139958585613624565b92505060206136628582860161376c565b6001600160e01b0381166135cd565b606081016139c382866135cb565b6139d060208301856139a6565b611b6960408301846136de565b6001600160581b0381166135cd565b60208101610a9182846139dd565b600080600060608486031215613a1257613a12600080fd5b6000613a1e868661380e565b935050602061384e8682870161376c565b65ffffffffffff81166135cd565b60208101610a918284613a2f565b7f4b4152524f5420544158204558454d50542028464f5220434f4d504f554e44498152624e472960e81b602082015260230190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115610a9157610a91613a96565b8181028115828204841417610a9157610a91613a96565b634e487b7160e01b600052601260045260246000fd5b600082613afb57613afb613ad6565b500490565b63ffffffff918216919081169082820190811115610a9157610a91613a96565b8051610a9181613763565b600060208284031215613b4057613b40600080fd5b6000611b698484613b20565b8051610a918161361e565b600060208284031215613b6c57613b6c600080fd5b6000611b698484613b4c565b6001600160801b03918216919081169082820390811115610a9157610a91613a96565b6001600160801b03918216919081169082820190811115610a9157610a91613a96565b6000610a916136a16001600160801b03841681565b6135cd81613bbe565b60208101610a918284613bd3565b6001600160801b03918216919081169082820290811690818114613c1057613c10613a96565b5092915050565b6001600160601b03918216919081169082820190811115610a9157610a91613a96565b6000610a916136a163ffffffff841681565b6135cd81613c3a565b6000610a916136a16001600160601b03841681565b6135cd81613c55565b60608101613c818286613c4c565b613c8e60208301856135cb565b611b696040830184613c6a565b6000610a916136a18381565b6135cd81613c9b565b60408101613cbe82856135cb565b612bd96020830184613ca7565b600060018201613cdd57613cdd613a96565b5060010190565b8051610a9181613799565b600060208284031215613d0457613d04600080fd5b6000611b698484613ce4565b80820180821115610a9157610a91613a96565b6000610a916136a162ffffff841681565b6135cd81613d23565b60608101613d4b828661395c565b613d5860208301856135cb565b611b696040830184613d34565b62ffffff16600062fffffe198201613cdd57613cdd613a96565b60408101613d8d82856135cb565b612bd960208301846135cb565b60408101613da8828561395c565b612bd9602083018461395c565b6001600160701b0381166135e7565b8051610a9181613db5565b63ffffffff81166135e7565b8051610a9181613dcf565b600080600060608486031215613dfe57613dfe600080fd5b6000613e0a8686613dc4565b9350506020613e1b86828701613dc4565b925050604061385f86828701613ddb565b60268152602081017f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015290505b60400190565b60208082528101610a9181613e2c565b601f8152602081017f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00815290505b60200190565b60208082528101610a9181613e7f565b60608101613ed1828661395c565b613ede60208301856135cb565b611b6960408301846135cb565b60408101613d8d828561395c565b6015815260208101744d6174683a206d756c446976206f766572666c6f7760581b81529050613ead565b60208082528101610a9181613ef9565b60608101613f4182866135cb565b613f4e60208301856135cb565b611b69604083018461373c565b60208082527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65729101908152613ead565b60208082528101610a9181613f5b565b60608101613fa9828661395c565b613ede602083018561395c565b602a8152602081017f5361666545524332303a204552433230206f7065726174696f6e20646964206e8152691bdd081cdd58d8d9595960b21b60208201529050613e69565b60208082528101610a9181613fb6565b60005b8381101561402657818101518382015260200161400e565b50506000910152565b6000614039825190565b61404781856020860161400b565b9290920192915050565b610a91818361402f565b601d8152602081017f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081529050613ead565b60208082528101610a918161405b565b60006140a7825190565b8084526020840193506140be81856020860161400b565b601f01601f19169290920192915050565b60208082528101612bd9818461409d56fea2646970667358221220473c52c90f5250c5e7db3083ad36eb5410987b34fb295183c2981209b03487ec64736f6c634300081300330000000000000000000000001b7d040a501f19f1e28ed9fe58e307a9516ee733
Deployed Bytecode
0x6080604052600436106102885760003560e01c8063792764401161015a578063b3cd4254116100c1578063e0188de81161007a578063e0188de81461084e578063e2bbb1581461086e578063e7a647651461088e578063f251b75c146108ba578063f2fde38b146108da578063fac1ab30146108fa57600080fd5b8063b3cd4254146107a5578063b8bfd029146107bb578063c9cc52d9146107db578063d8b63f31146107fb578063dd8dc5de1461081b578063e00b288a1461083b57600080fd5b806391f143331161011357806391f143331461069057806393f1a40b146106b057806398969e82146107165780639aca5176146107365780639dce9f9c14610758578063a6a80a901461078c57600080fd5b8063792764401461058857806379502c55146105a85780637c1a0302146105d55780637e2c3c4114610605578063806b984f146106345780638da5cb5b1461066957600080fd5b8063441a3e70116101fe578063538fb492116101b7578063538fb492146104f357806360da3e8314610508578063630b5ba1146105295780636a3578051461053e5780636bb35dd01461055e578063715018a61461057357600080fd5b8063441a3e701461041f57806346bf6a551461043f57806348cd4cb1146104615780634a3b934b1461049357806351eb05a6146104b35780635318bea3146104d357600080fd5b806318424eb51161025057806318424eb51461035357806324d0cec71461036f57806332298be114610384578063345c8b4d146103b15780633d792125146103df57806340f7f836146103ff57600080fd5b8063081e3eda1461028d57806309fae4b9146102b4578063126796dd146102d65780631526fe27146102f657806317caf6f114610326575b600080fd5b34801561029957600080fd5b506005545b6040516102ab91906135d3565b60405180910390f35b3480156102c057600080fd5b506102d46102cf3660046135fd565b61091a565b005b3480156102e257600080fd5b506102d46102f136600461362f565b610967565b34801561030257600080fd5b5061031661031136600461366c565b6109e1565b6040516102ab94939291906136f9565b34801561033257600080fd5b50600454610346906001600160801b031681565b6040516102ab919061372e565b34801561035f57600080fd5b5061029e670de0b6b3a764000081565b34801561037b57600080fd5b5061029e610a42565b34801561039057600080fd5b5061029e61039f36600461366c565b60086020526000908152604090205481565b3480156103bd57600080fd5b506004546103d290600160801b900460ff1681565b6040516102ab9190613744565b3480156103eb57600080fd5b5061029e6103fa366004613777565b610a6d565b34801561040b57600080fd5b506102d461041a3660046137ac565b610a97565b34801561042b57600080fd5b506102d461043a36600461362f565b610b14565b34801561044b57600080fd5b50610454600181565b6040516102ab91906137d6565b34801561046d57600080fd5b5060025461048690600160d81b900464ffffffffff1681565b6040516102ab91906137f1565b34801561049f57600080fd5b506102d46104ae366004613819565b610e98565b3480156104bf57600080fd5b506102d46104ce36600461366c565b610fc8565b3480156104df57600080fd5b506102d46104ee366004613882565b611365565b3480156104ff57600080fd5b506102d46113b0565b34801561051457600080fd5b506004546103d290600160881b900460ff1681565b34801561053557600080fd5b506102d4611433565b34801561054a57600080fd5b506103d26105593660046138a3565b61145a565b34801561056a57600080fd5b506102d4611624565b34801561057f57600080fd5b506102d46116f7565b34801561059457600080fd5b506102d46105a33660046138de565b61170b565b3480156105b457600080fd5b506002546105c8906001600160a01b031681565b6040516102ab91906138ff565b3480156105e157600080fd5b506002546105f890600160c01b900462ffffff1681565b6040516102ab9190613918565b34801561061157600080fd5b5060025461062790600160b01b900461ffff1681565b6040516102ab9190613930565b34801561064057600080fd5b5060035461065c90600160301b900467ffffffffffffffff1681565b6040516102ab919061394e565b34801561067557600080fd5b506000546001600160a01b03165b6040516102ab9190613965565b34801561069c57600080fd5b506102d46106ab3660046135fd565b611796565b3480156106bc57600080fd5b506107076106cb366004613973565b6006602090815260009283526040808420909152908252902080546001909101546001600160e01b03811690600160e01b900463ffffffff1683565b6040516102ab939291906139b5565b34801561072257600080fd5b5061029e610731366004613973565b6117e3565b34801561074257600080fd5b5060025461062790600160a01b900461ffff1681565b34801561076457600080fd5b5060035461077f90600160701b90046001600160581b031681565b6040516102ab91906139ec565b34801561079857600080fd5b5061029e64e8d4a5100081565b3480156107b157600080fd5b5061062761271081565b3480156107c757600080fd5b5061029e6107d63660046138a3565b611b3d565b3480156107e757600080fd5b506106836107f636600461366c565b611b71565b34801561080757600080fd5b5061029e6108163660046138a3565b611ba6565b34801561082757600080fd5b506102d46108363660046138a3565b611cc6565b6102d461084936600461366c565b611cf0565b34801561085a57600080fd5b506102d46108693660046139fa565b611f24565b34801561087a57600080fd5b506102d461088936600461362f565b612100565b34801561089a57600080fd5b506003546108ad9065ffffffffffff1681565b6040516102ab9190613a3d565b3480156108c657600080fd5b5061029e6108d536600461366c565b6124a7565b3480156108e657600080fd5b506102d46108f53660046138a3565b612819565b34801561090657600080fd5b5061029e610915366004613973565b612850565b6002546001600160a01b03163314610945576040516340e2203b60e01b815260040160405180910390fd5b6002805461ffff909216600160b01b0261ffff60b01b19909216919091179055565b6002546001600160a01b03163314610992576040516340e2203b60e01b815260040160405180910390fd5b600082815260086020526040908190208290555182907f84335b44fa6b10da53c37ff36b055274c2cddf15beac71eaff143f8ce17c7264906109d59084906135d3565b60405180910390a25050565b600581815481106109f157600080fd5b6000918252602090912060029091020180546001909101546001600160a01b0390911691506001600160801b03811690600160801b810463ffffffff1690600160a01b90046001600160601b031684565b604051602001610a5190613a4b565b6040516020818303038152906040528051906020012060001c81565b60008181526006602090815260408083206001600160a01b03861684529091529020545b92915050565b6002546001600160a01b03163314610ac2576040516340e2203b60e01b815260040160405180910390fd5b6004805460ff60881b1916600160881b831515021790556040517f5b00cce3d56020349f502ff1cae2758ad29977252c146a4177392ea2a145183c90610b09908390613744565b60405180910390a150565b610b1c612988565b80600003610b3d5760405163162908e360e11b815260040160405180910390fd5b600060058381548110610b5257610b52613a80565b6000918252602080832086845260068252604080852033865290925292206001810154600292909202909201925042600160e01b90910463ffffffff161115610bae57604051636100d92960e11b815260040160405180910390fd5b8054831115610bd05760405163162908e360e11b815260040160405180910390fd5b610bd984610fc8565b610be384336129b1565b82816000016000828254610bf79190613aac565b90915550506001820154815464e8d4a5100091610c2591600160a01b9091046001600160601b031690613abf565b610c2f9190613aec565b6001820180546001600160e01b0319166001600160e01b0392909216919091179055600084815260086020526040902054610c6a9042613b00565b81600101601c6101000a81548163ffffffff021916908363ffffffff160217905550600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d039190613b2b565b82546001600160a01b03918216911603610dfd57600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8e9190613b2b565b6001600160a01b031663b15587df846040518263ffffffff1660e01b8152600401610db991906135d3565b602060405180830381865afa158015610dd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfa9190613b57565b92505b8154610e13906001600160a01b03163385612abd565b83336001600160a01b03167ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b56885604051610e4d91906135d3565b60405180910390a3610e5e33611ba6565b60405133907fbc2cf4e8ce91f01aed81a9be00bcc8c01f8510820e7c5b9ec3c1eb919a4c2f5490600090a35050610e9460018055565b5050565b6002546001600160a01b03163314610ec3576040516340e2203b60e01b815260040160405180910390fd5b8015610ed157610ed1611433565b8160058481548110610ee557610ee5613a80565b6000918252602090912060016002909202010154600454610f12916001600160801b039081169116613b78565b610f1c9190613b9b565b600460006101000a8154816001600160801b0302191690836001600160801b031602179055508160058481548110610f5657610f56613a80565b906000526020600020906002020160010160006101000a8154816001600160801b0302191690836001600160801b03160217905550827f67032c5b22da4ed0669c2ae3261730d3ac9176e7de1b22d495b32ded5ccf3e2383604051610fbb9190613bdc565b60405180910390a2505050565b600060058281548110610fdd57610fdd613a80565b60009182526020822060029091020180549092506001600160a01b031661100357505050565b6001820154600160801b900463ffffffff16431161102057505050565b600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa158015611073573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110979190613b2b565b82546001600160a01b0391821691160361119557600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111229190613b2b565b6001600160a01b0316633af9e669306040518263ffffffff1660e01b815260040161114d9190613965565b602060405180830381865afa15801561116a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118e9190613b57565b9050611208565b81546040516370a0823160e01b81526001600160a01b03909116906370a08231906111c4903090600401613965565b602060405180830381865afa1580156111e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112059190613b57565b90505b806000036112335750600101805463ffffffff60801b1916600160801b4363ffffffff160217905550565b60018201546000906112969061125690600160801b900463ffffffff1643613aac565b6001850154600354611281916001600160801b031690600160701b90046001600160581b0316613bea565b6004546001600160801b039182169116612b18565b90506112a88164e8d4a5100084612b18565b6001840180546014906112cc908490600160a01b90046001600160601b0316613c17565b82546101009290920a6001600160601b0381810219909316918316021790915560018501805463ffffffff60801b1916600160801b4363ffffffff908116820292909217928390556040518995507fb0a2ded49817748754bcca0474b24011f01d4574dd5c40e14197ffa2e6540fef9461135794928304909316928892600160a01b90041690613c73565b60405180910390a250505050565b6002546001600160a01b03163314611390576040516340e2203b60e01b815260040160405180910390fd5b6003805465ffffffffffff191665ffffffffffff92909216919091179055565b6000806113e9600133846040516020016113c990613a4b565b6040516020818303038152906040528051906020012060001c6001612be0565b5090506113f7600182612100565b336001600160a01b03167f0e311a2c6dbfb0153ec3a8a5bdca09070b3e5f60768fdc10a20453f38d1868738260016040516109d5929190613cb0565b60055460005b81811015610e945761144a81610fc8565b61145381613ccb565b9050611439565b600080600260009054906101000a90046001600160a01b03166001600160a01b03166366b168276040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d49190613b2b565b90506000816001600160a01b0316632251e9a9856040518263ffffffff1660e01b81526004016115049190613965565b602060405180830381865afa158015611521573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115459190613cef565b90506000826001600160a01b03166394465b21866040518263ffffffff1660e01b81526004016115759190613965565b602060405180830381865afa158015611592573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b69190613b57565b905060006115c386611b3d565b9050806000036115d7575090949350505050565b60006115e68361271084612b18565b600254909150600160b01b900461ffff1681118480156116035750805b1561161657506001979650505050505050565b506000979650505050505050565b6002546001600160a01b0316331461164f576040516340e2203b60e01b815260040160405180910390fd5b61165a600143613aac565b6002805464ffffffffff928316600160d81b9081026001600160d81b03909216919091179182905560038054600160301b92909304909316026dffffffffffffffff000000000000199091161790556004805460ff60801b1916600160801b1790556040517f5b00cce3d56020349f502ff1cae2758ad29977252c146a4177392ea2a145183c906116ed90600190613744565b60405180910390a1565b6116ff613345565b611709600061336f565b565b6002546001600160a01b03163314611736576040516340e2203b60e01b815260040160405180910390fd5b61173e611433565b600380546affffffffffffffffffffff60701b1916600160701b6001600160581b038416021790556040517f9eb86a16326fe9c3a30ac874ce6693689603381218c2f8c3897f9d879724e16c90610b099083906139ec565b6002546001600160a01b031633146117c1576040516340e2203b60e01b815260040160405180910390fd5b6002805461ffff909216600160a01b0261ffff60a01b19909216919091179055565b600080600584815481106117f9576117f9613a80565b600091825260208083208784526006825260408085206001600160a01b03898116875293528085206002949094029091016001810154815492516370a0823160e01b81529196509394600160a01b9094046001600160601b0316939291909116906370a082319061186e903090600401613965565b602060405180830381865afa15801561188b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118af9190613b57565b9050600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa158015611904573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119289190613b2b565b84546001600160a01b03918216911603611a2257600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa15801561198f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b39190613b2b565b6001600160a01b0316633af9e669306040518263ffffffff1660e01b81526004016119de9190613965565b602060405180830381865afa1580156119fb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1f9190613b57565b90505b6001840154600160801b900463ffffffff1643118015611a4157508015155b15611acc576003546001850154600454600092611a7c92600160701b9091046001600160581b0316916001600160801b039182169116612b18565b6001860154611a9890600160801b900463ffffffff1643613aac565b611aa29190613abf565b905081611ab464e8d4a5100083613abf565b611abe9190613aec565b611ac89084613d10565b9250505b600183015483546001600160e01b039091169064e8d4a5100090611af1908590613abf565b611afb9190613aec565b60008981526007602090815260408083206001600160a01b038c168452909152902054611b289190613d10565b611b329190613aac565b979650505050505050565b600080611b4e6108d5600085612850565b90506000611b5d600185612850565b9050611b698183613d10565b949350505050565b600060058281548110611b8657611b86613a80565b60009182526020909120600290910201546001600160a01b031692915050565b600080600260009054906101000a90046001600160a01b03166001600160a01b03166366b168276040518163ffffffff1660e01b8152600401602060405180830381865afa158015611bfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c209190613b2b565b90506000816001600160a01b03166394465b21856040518263ffffffff1660e01b8152600401611c509190613965565b602060405180830381865afa158015611c6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c919190613b57565b90506000611c9e85611b3d565b905080600003611cb057509392505050565b611cbd8261271083612b18565b95945050505050565b611cce613345565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b611cf8612988565b33328114611d1957604051636033c79d60e01b815260040160405180910390fd5b611d2282610fc8565b611d2c82826129b1565b60008281526007602090815260408083206001600160a01b03851684529091528120549003611d795780604051630ce8b4bd60e31b8152600401611d709190613965565b60405180910390fd5b600254604080516369b5c8f960e01b815290516000926001600160a01b0316916369b5c8f99160048083019260209291908290030181865afa158015611dc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de79190613b2b565b6001600160a01b031663db3b390c8342600260189054906101000a900462ffffff166040518463ffffffff1660e01b8152600401611e2793929190613d3d565b6020604051808303816000875af1158015611e46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e6a9190613b57565b9050600080611e93858585600260189054906101000a900462ffffff1662ffffff166000612be0565b915091506002601881819054906101000a900462ffffff16611eb490613d65565b91906101000a81548162ffffff021916908362ffffff16021790555084846001600160a01b03167f45c072aa05b9853b5a993de7a28bc332ee01404a628cec1a23ce0f659f842ef18484604051611f0c929190613d7f565b60405180910390a350505050611f2160018055565b50565b611f2c613345565b611f35826133bf565b611f5257604051637a471e1360e11b815260040160405180910390fd5b8015611f6057611f60611433565b600254600090600160d81b900464ffffffffff164311611f9057600254600160d81b900464ffffffffff16611f92565b435b600454909150611fac9085906001600160801b0316613b9b565b600480546001600160801b039283166fffffffffffffffffffffffffffffffff19909116179055604080516080810182526001600160a01b038087168083528885166020840190815263ffffffff808816958501958652600060608601818152600580546001818101835593829052975160029098027f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0810180549989166001600160a01b03199a8b1617905594517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db19095018054995192516001600160601b0316600160a01b0292909416600160801b029890971693909816929092179590951790921694909417909255546120c39190613aac565b7f4710feb78e3bce8d2e3ca2989a8eb2f8bcd32a6a55b4535942c180fc4d2e2952866040516120f29190613bdc565b60405180910390a350505050565b612108612988565b600454600160801b900460ff16158061212a5750600454600160881b900460ff165b156121485760405163ca337b7f60e01b815260040160405180910390fd5b806000036121695760405163162908e360e11b815260040160405180910390fd5b60006005838154811061217e5761217e613a80565b600091825260208083208684526006825260408085203380875293529384902060029093020180549351636eb1769f60e11b8152909450919285926001600160a01b03919091169163dd62ed3e916121db91903090600401613d9a565b602060405180830381865afa1580156121f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221c9190613b57565b101561223b576040516365ba6fc360e01b815260040160405180910390fd5b6000848152600860205260409020546122549042613d10565b81600101601c6101000a81548163ffffffff021916908363ffffffff16021790555061227f84610fc8565b61228984336129b1565b81546122a0906001600160a01b031633308661342f565b600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123179190613b2b565b82546001600160a01b0391821691160361241157600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a29190613b2b565b6001600160a01b0316632e687671846040518263ffffffff1660e01b81526004016123cd91906135d3565b602060405180830381865afa1580156123ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240e9190613b57565b92505b828160000160008282546124259190613d10565b9091555050805460018301546124519190600160a01b90046001600160601b031664e8d4a51000612b18565b6001820180546001600160e01b0319166001600160e01b0392909216919091179055604051849033907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a1590610e4d9087906135d3565b6000816000036124b957506000919050565b600254604080516307336a7960e41b815290516000926001600160a01b031691637336a7909160048083019260209291908290030181865afa158015612503573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125279190613b2b565b90506000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612569573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258d9190613b57565b9050600080836001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156125d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125f49190613de6565b50915091506000846001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015612639573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061265d9190613b2b565b90506000856001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561269f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c39190613b2b565b90506000600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa15801561271a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061273e9190613b2b565b6001600160a01b0316836001600160a01b03160361276657506001600160701b038416612801565b600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127dd9190613b2b565b6001600160a01b0316826001600160a01b03160361280157506001600160701b0383165b61280c898288612b18565b9998505050505050505050565b612821613345565b6001600160a01b0381166128475760405162461bcd60e51b8152600401611d7090613e6f565b611f218161336f565b60008260010361295f57600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128d19190613b2b565b60008481526006602090815260408083206001600160a01b03878116855292529182902054915163b15587df60e01b815292169163b15587df91612917916004016135d3565b602060405180830381865afa158015612934573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129589190613b57565b9050610a91565b5060008281526006602090815260408083206001600160a01b0385168452909152902054610a91565b6002600154036129aa5760405162461bcd60e51b8152600401611d7090613eb3565b6002600155565b60008281526006602090815260408083206001600160a01b0385168452909152812060018101548154600580549394936001600160e01b0390931692612a3292919088908110612a0357612a03613a80565b6000918252602090912060029091020160010154600160a01b90046001600160601b031664e8d4a51000612b18565b612a3c9190613aac565b90508015612a7c5760008481526007602090815260408083206001600160a01b038716845290915281208054839290612a76908490613d10565b90915550505b7f09a4f557033a56cbe70db5ccef9534cbb73cbfe724512852e36e86e36d7a93b4838583604051612aaf93929190613ec3565b60405180910390a150505050565b612b138363a9059cbb60e01b8484604051602401612adc929190613eeb565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613456565b505050565b6000808060001985870985870292508281108382030391505080600003612b5257838281612b4857612b48613ad6565b0492505050612bd9565b808411612b715760405162461bcd60e51b8152600401611d7090613f23565b600084868809851960019081018716968790049682860381900495909211909303600082900391909104909201919091029190911760038402600290811880860282030280860282030280860282030280860282030280860282030280860290910302029150505b9392505050565b6000806000604051602001612bf490613a4b565b6040516020818303038152906040528051906020012060001c8503612c2657612c1c88610fc8565b612c2688886129b1565b60008881526007602090815260408083206001600160a01b038b16845290915281205490819003612c6c5787604051630ce8b4bd60e31b8152600401611d709190613965565b60025460408051630a15a2e160e41b815290516000926001600160a01b03169163a15a2e109160048083019260209291908290030181865afa158015612cb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cda9190613b2b565b60008b81526006602090815260408083206001600160a01b038e16845282528083208e845260089092529091205491925090612d169042613b00565b60018201805463ffffffff92909216600160e01b026001600160e01b0390921691909117905560008b81526007602090815260408083206001600160a01b038e1684529091528120556005805464e8d4a5100091908d908110612d7b57612d7b613a80565b906000526020600020906002020160010160149054906101000a90046001600160601b03166001600160601b0316600660008e815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002060000154612ded9190613abf565b612df79190613aec565b60008c81526006602090815260408083206001600160a01b038f168452909152902060010180546001600160e01b0319166001600160e01b039290921691909117905560035443600160301b90910467ffffffffffffffff1614612fef57600354600090612e8c90612e7a90600160301b900467ffffffffffffffff1643613aac565b60035465ffffffffffff166001612b18565b604051637af548c160e01b81529091506001600160a01b03841690637af548c190612ec09043908590600090600401613f33565b6020604051808303816000875af1158015612edf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f039190613b57565b50600380546dffffffffffffffff0000000000001916600160301b4367ffffffffffffffff1602179055600254604080516307336a7960e41b815290516001600160a01b0390921691637336a790916004808201926020929091908290030181865afa158015612f77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f9b9190613b2b565b6001600160a01b031663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612fd557600080fd5b505af1158015612fe9573d6000803e3d6000fd5b50505050505b612ff88a61145a565b80613029575060405160200161300d90613a4b565b6040516020818303038152906040528051906020012060001c88145b156130d5576040516340c10f1960e01b81526001600160a01b038316906340c10f199061305c908d908790600401613eeb565b600060405180830381600087803b15801561307657600080fd5b505af115801561308a573d6000803e3d6000fd5b505050508a8a6001600160a01b03167fd6f2c8500df5b44f11e9e48b91ff9f1b9d81bc496d55570c2b1b75bf65243f51856040516130c891906135d3565b60405180910390a3613334565b6002546130f1908490600160a01b900461ffff16612710612b18565b93506001600160a01b0382166340c10f198b61310d8787613aac565b6040518363ffffffff1660e01b815260040161312a929190613eeb565b600060405180830381600087803b15801561314457600080fd5b505af1158015613158573d6000803e3d6000fd5b50505050600260009054906101000a90046001600160a01b03166001600160a01b031663dc80c2c86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131d39190613b2b565b6001600160a01b0316632278a902856040518263ffffffff1660e01b81526004016131fe91906135d3565b600060405180830381600087803b15801561321857600080fd5b505af115801561322c573d6000803e3d6000fd5b505050508a600260009054906101000a90046001600160a01b03166001600160a01b031663dc80c2c86040518163ffffffff1660e01b8152600401602060405180830381865afa158015613284573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132a89190613b2b565b6001600160a01b03167fb0a068ff9b2c6f72d5af72f3f94b79d10fe7995889678a9c0f6a33caa63cb4d2866040516132e091906135d3565b60405180910390a38a6001600160a01b038b167fd6f2c8500df5b44f11e9e48b91ff9f1b9d81bc496d55570c2b1b75bf65243f5161331e8787613aac565b60405161332b91906135d3565b60405180910390a35b509099919850909650505050505050565b6000546001600160a01b031633146117095760405162461bcd60e51b8152600401611d7090613f8b565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600554600090815b8181101561342557836001600160a01b0316600582815481106133ec576133ec613a80565b60009182526020909120600290910201546001600160a01b031603613415575060009392505050565b61341e81613ccb565b90506133c7565b5060019392505050565b613450846323b872dd60e01b858585604051602401612adc93929190613f9b565b50505050565b60006134ab826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134e89092919063ffffffff16565b90508051600014806134cc5750808060200190518101906134cc9190613cef565b612b135760405162461bcd60e51b8152600401611d7090613ffb565b6060611b69848460008585600080866001600160a01b0316858760405161350f9190614051565b60006040518083038185875af1925050503d806000811461354c576040519150601f19603f3d011682016040523d82523d6000602084013e613551565b606091505b5091509150611b32878383876060831561359c578251600003613595576001600160a01b0385163b6135955760405162461bcd60e51b8152600401611d709061408d565b5081611b69565b611b6983838151156135b15781518083602001fd5b8060405162461bcd60e51b8152600401611d7091906140cf565b805b82525050565b60208101610a9182846135cb565b61ffff81165b8114611f2157600080fd5b8035610a91816135e1565b60006020828403121561361257613612600080fd5b6000611b6984846135f2565b806135e7565b8035610a918161361e565b6000806040838503121561364557613645600080fd5b60006136518585613624565b925050602061366285828601613624565b9150509250929050565b60006020828403121561368157613681600080fd5b6000611b698484613624565b6000610a916001600160a01b0383166136a4565b90565b6001600160a01b031690565b6000610a918261368d565b6000610a91826136b0565b6135cd816136bb565b6001600160801b0381166135cd565b63ffffffff81166135cd565b6001600160601b0381166135cd565b6080810161370782876136c6565b61371460208301866136cf565b61372160408301856136de565b611cbd60608301846136ea565b60208101610a9182846136cf565b8015156135cd565b60208101610a91828461373c565b60006001600160a01b038216610a91565b6135e781613752565b8035610a9181613763565b6000806040838503121561378d5761378d600080fd5b6000613651858561376c565b8015156135e7565b8035610a9181613799565b6000602082840312156137c1576137c1600080fd5b6000611b6984846137a1565b60ff81166135cd565b60208101610a9182846137cd565b64ffffffffff81166135cd565b60208101610a9182846137e4565b6001600160801b0381166135e7565b8035610a91816137ff565b60008060006060848603121561383157613831600080fd5b600061383d8686613624565b935050602061384e8682870161380e565b925050604061385f868287016137a1565b9150509250925092565b65ffffffffffff81166135e7565b8035610a9181613869565b60006020828403121561389757613897600080fd5b6000611b698484613877565b6000602082840312156138b8576138b8600080fd5b6000611b69848461376c565b6001600160581b0381166135e7565b8035610a91816138c4565b6000602082840312156138f3576138f3600080fd5b6000611b6984846138d3565b60208101610a9182846136c6565b62ffffff81166135cd565b60208101610a91828461390d565b61ffff81166135cd565b60208101610a918284613926565b67ffffffffffffffff81166135cd565b60208101610a91828461393e565b6135cd81613752565b60208101610a91828461395c565b6000806040838503121561398957613989600080fd5b60006139958585613624565b92505060206136628582860161376c565b6001600160e01b0381166135cd565b606081016139c382866135cb565b6139d060208301856139a6565b611b6960408301846136de565b6001600160581b0381166135cd565b60208101610a9182846139dd565b600080600060608486031215613a1257613a12600080fd5b6000613a1e868661380e565b935050602061384e8682870161376c565b65ffffffffffff81166135cd565b60208101610a918284613a2f565b7f4b4152524f5420544158204558454d50542028464f5220434f4d504f554e44498152624e472960e81b602082015260230190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115610a9157610a91613a96565b8181028115828204841417610a9157610a91613a96565b634e487b7160e01b600052601260045260246000fd5b600082613afb57613afb613ad6565b500490565b63ffffffff918216919081169082820190811115610a9157610a91613a96565b8051610a9181613763565b600060208284031215613b4057613b40600080fd5b6000611b698484613b20565b8051610a918161361e565b600060208284031215613b6c57613b6c600080fd5b6000611b698484613b4c565b6001600160801b03918216919081169082820390811115610a9157610a91613a96565b6001600160801b03918216919081169082820190811115610a9157610a91613a96565b6000610a916136a16001600160801b03841681565b6135cd81613bbe565b60208101610a918284613bd3565b6001600160801b03918216919081169082820290811690818114613c1057613c10613a96565b5092915050565b6001600160601b03918216919081169082820190811115610a9157610a91613a96565b6000610a916136a163ffffffff841681565b6135cd81613c3a565b6000610a916136a16001600160601b03841681565b6135cd81613c55565b60608101613c818286613c4c565b613c8e60208301856135cb565b611b696040830184613c6a565b6000610a916136a18381565b6135cd81613c9b565b60408101613cbe82856135cb565b612bd96020830184613ca7565b600060018201613cdd57613cdd613a96565b5060010190565b8051610a9181613799565b600060208284031215613d0457613d04600080fd5b6000611b698484613ce4565b80820180821115610a9157610a91613a96565b6000610a916136a162ffffff841681565b6135cd81613d23565b60608101613d4b828661395c565b613d5860208301856135cb565b611b696040830184613d34565b62ffffff16600062fffffe198201613cdd57613cdd613a96565b60408101613d8d82856135cb565b612bd960208301846135cb565b60408101613da8828561395c565b612bd9602083018461395c565b6001600160701b0381166135e7565b8051610a9181613db5565b63ffffffff81166135e7565b8051610a9181613dcf565b600080600060608486031215613dfe57613dfe600080fd5b6000613e0a8686613dc4565b9350506020613e1b86828701613dc4565b925050604061385f86828701613ddb565b60268152602081017f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015290505b60400190565b60208082528101610a9181613e2c565b601f8152602081017f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00815290505b60200190565b60208082528101610a9181613e7f565b60608101613ed1828661395c565b613ede60208301856135cb565b611b6960408301846135cb565b60408101613d8d828561395c565b6015815260208101744d6174683a206d756c446976206f766572666c6f7760581b81529050613ead565b60208082528101610a9181613ef9565b60608101613f4182866135cb565b613f4e60208301856135cb565b611b69604083018461373c565b60208082527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65729101908152613ead565b60208082528101610a9181613f5b565b60608101613fa9828661395c565b613ede602083018561395c565b602a8152602081017f5361666545524332303a204552433230206f7065726174696f6e20646964206e8152691bdd081cdd58d8d9595960b21b60208201529050613e69565b60208082528101610a9181613fb6565b60005b8381101561402657818101518382015260200161400e565b50506000910152565b6000614039825190565b61404781856020860161400b565b9290920192915050565b610a91818361402f565b601d8152602081017f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081529050613ead565b60208082528101610a918161405b565b60006140a7825190565b8084526020840193506140be81856020860161400b565b601f01601f19169290920192915050565b60208082528101612bd9818461409d56fea2646970667358221220473c52c90f5250c5e7db3083ad36eb5410987b34fb295183c2981209b03487ec64736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001b7d040a501f19f1e28ed9fe58e307a9516ee733
-----Decoded View---------------
Arg [0] : _configManager (address): 0x1b7d040A501F19F1e28ed9fe58e307a9516EE733
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000001b7d040a501f19f1e28ed9fe58e307a9516ee733
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.