Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60c06040 | 18025992 | 375 days ago | IN | 0 ETH | 0.06217874 |
Loading...
Loading
Contract Name:
LiquisViewHelpers
Compiler Version
v0.8.11+commit.d7f03943
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.11; import { IBalancerVault } from "../interfaces/balancer/IBalancerCore.sol"; import { LiqLocker } from "../core/LiqLocker.sol"; import { IBooster } from "../interfaces/IBooster.sol"; import { Math } from "../utils/Math.sol"; /** * @title LiquisViewHelpers * @author AuraFinance * @notice View-only contract to combine calls * @dev IMPORTANT: These functions are extremely gas-intensive * and should not be called from within a transaction. */ contract LiquisViewHelpers { using Math for uint256; IERC20Detailed public immutable liq = IERC20Detailed(0xD82fd4D6D62f89A1E50b1db69AD19932314aa408); IBalancerVault public immutable balancerVault = IBalancerVault(0xBA12222222228d8Ba445958a75a0704d566BF2C8); struct Token { address addr; uint8 decimals; string symbol; string name; } struct Pool { uint256 pid; address lptoken; address token; address gauge; address crvRewards; address stash; bool shutdown; address rewardToken; address uniV3Pool; address[] poolTokens; int24[] ticks; uint256 totalSupply; RewardsData rewardsData; ExtraRewards[] extraRewards; } struct Locker { uint256 epoch; uint256 totalSupply; uint256 lockedSupply; RewardsData rewardsData; } struct LockerAccount { address addr; uint256 total; uint256 unlockable; uint256 locked; uint256 nextUnlockIndex; uint128 rewardPerTokenPaid; uint128 rewards; address delegate; uint256 votes; LiqLocker.LockedBalance[] lockData; LiqLocker.EarnedData[] claimableRewards; } struct RewardsData { uint256 periodFinish; uint256 lastUpdateTime; uint256 rewardRate; uint256 rewardPerTokenStored; uint256 queuedRewards; } struct ExtraRewards { address addr; address rewardsToken; RewardsData rewardsData; } struct PoolBalances { uint256 pid; uint256 earned; uint256[] extraRewardsEarned; uint256 staked; } function getLocker(address _locker) external view returns (Locker memory locker) { LiqLocker liqLocker = LiqLocker(_locker); address rewardToken = liqLocker.cvxCrv(); (uint32 periodFinish, uint32 lastUpdateTime, uint96 rewardRate, uint96 rewardPerTokenStored) = liqLocker .rewardData(rewardToken); RewardsData memory rewardsData = RewardsData({ rewardRate: uint256(rewardRate), rewardPerTokenStored: uint256(rewardPerTokenStored), periodFinish: uint256(periodFinish), lastUpdateTime: uint256(lastUpdateTime), queuedRewards: liqLocker.queuedRewards(rewardToken) }); locker = Locker({ epoch: liqLocker.epochCount(), totalSupply: liqLocker.totalSupply(), lockedSupply: liqLocker.lockedSupply(), rewardsData: rewardsData }); } function getLockerAccount(address _locker, address _account) external view returns (LockerAccount memory lockerAccount) { LiqLocker liqLocker = LiqLocker(_locker); address cvxCrv = liqLocker.cvxCrv(); (, uint112 nextUnlockIndex) = liqLocker.balances(_account); (uint128 rewardPerTokenPaid, uint128 rewards) = liqLocker.userData(cvxCrv, _account); (uint256 total, uint256 unlockable, uint256 locked, LiqLocker.LockedBalance[] memory lockData) = liqLocker .lockedBalances(_account); lockerAccount = LockerAccount({ addr: _account, total: total, unlockable: unlockable, locked: locked, lockData: lockData, nextUnlockIndex: uint256(nextUnlockIndex), rewardPerTokenPaid: rewardPerTokenPaid, rewards: rewards, delegate: liqLocker.delegates(_account), votes: liqLocker.balanceOf(_account), claimableRewards: liqLocker.claimableRewards(_account) }); } function getPools(address _booster) external view returns (Pool[] memory) { IBooster booster = IBooster(_booster); uint256 poolLength = booster.poolLength(); Pool[] memory pools = new Pool[](poolLength + 1); // +1 for cvxCrvRewards for (uint256 i = 0; i < poolLength; i++) { IBooster.PoolInfo memory poolInfo = booster.poolInfo(i); pools[i] = getPool(poolInfo, i); } // Add cvxCrvRewards pools[poolLength] = getCvxCrvRewards(booster.lockRewards()); return pools; } function getCvxCrvRewards(address _cvxCrvRewards) public view returns (Pool memory) { IBaseRewardPool pool = IBaseRewardPool(_cvxCrvRewards); address cvxCrv = pool.stakingToken(); address[] memory poolTokens = new address[](1); poolTokens[0] = cvxCrv; int24[] memory ticks = new int24[](1); ticks[0] = 0; RewardsData memory rewardsData = RewardsData({ rewardRate: pool.rewardRate(), periodFinish: pool.periodFinish(), lastUpdateTime: pool.lastUpdateTime(), rewardPerTokenStored: pool.rewardPerTokenStored(), queuedRewards: pool.queuedRewards() }); ExtraRewards[] memory extraRewards = getExtraRewards(_cvxCrvRewards); return Pool({ pid: uint256(0), lptoken: cvxCrv, token: cvxCrv, gauge: address(0), crvRewards: _cvxCrvRewards, stash: address(0), shutdown: false, rewardToken: pool.rewardToken(), uniV3Pool: address(0), poolTokens: poolTokens, ticks: ticks, rewardsData: rewardsData, extraRewards: extraRewards, totalSupply: pool.totalSupply() }); } function getExtraRewards(address _baseRewardPool) internal view returns (ExtraRewards[] memory) { IBaseRewardPool baseRewardPool = IBaseRewardPool(_baseRewardPool); uint256 extraRewardsLength = baseRewardPool.extraRewardsLength(); ExtraRewards[] memory extraRewards = new ExtraRewards[](extraRewardsLength); for (uint256 i = 0; i < extraRewardsLength; i++) { address addr = baseRewardPool.extraRewards(i); IBaseRewardPool extraRewardsPool = IBaseRewardPool(addr); RewardsData memory data = RewardsData({ rewardRate: extraRewardsPool.rewardRate(), periodFinish: extraRewardsPool.periodFinish(), lastUpdateTime: extraRewardsPool.lastUpdateTime(), rewardPerTokenStored: extraRewardsPool.rewardPerTokenStored(), queuedRewards: extraRewardsPool.queuedRewards() }); extraRewards[i] = ExtraRewards({ addr: addr, rewardsData: data, rewardsToken: extraRewardsPool.rewardToken() }); } return extraRewards; } function getPool(IBooster.PoolInfo memory poolInfo, uint256 _pid) public view returns (Pool memory) { IBaseRewardPool rewardPool = IBaseRewardPool(poolInfo.crvRewards); IBunniLpToken bunniLpToken = IBunniLpToken(poolInfo.lptoken); // Some pools were added to the Booster without valid LP tokens // We need to try/catch all of these calls as a result address uniV3Pool; address[] memory poolTokens = new address[](2); int24[] memory ticks = new int24[](2); try bunniLpToken.pool() returns (address fetchedPool) { uniV3Pool = fetchedPool; poolTokens[0] = IUniV3Pool(uniV3Pool).token0(); poolTokens[1] = IUniV3Pool(uniV3Pool).token1(); ticks[0] = bunniLpToken.tickLower(); ticks[1] = bunniLpToken.tickUpper(); } catch { uniV3Pool = address(0); } ExtraRewards[] memory extraRewards = getExtraRewards(poolInfo.crvRewards); RewardsData memory rewardsData = RewardsData({ rewardRate: rewardPool.rewardRate(), periodFinish: rewardPool.periodFinish(), lastUpdateTime: rewardPool.lastUpdateTime(), rewardPerTokenStored: rewardPool.rewardPerTokenStored(), queuedRewards: rewardPool.queuedRewards() }); return Pool({ pid: _pid, lptoken: poolInfo.lptoken, token: poolInfo.token, gauge: poolInfo.gauge, crvRewards: poolInfo.crvRewards, stash: poolInfo.stash, shutdown: poolInfo.shutdown, rewardToken: rewardPool.rewardToken(), uniV3Pool: uniV3Pool, poolTokens: poolTokens, ticks: ticks, rewardsData: rewardsData, extraRewards: extraRewards, totalSupply: rewardPool.totalSupply() }); } function getPoolsBalances(address _booster, address _account) external view returns (PoolBalances[] memory) { uint256 poolLength = IBooster(_booster).poolLength(); PoolBalances[] memory balances = new PoolBalances[](poolLength); for (uint256 i = 0; i < poolLength; i++) { IBooster.PoolInfo memory poolInfo = IBooster(_booster).poolInfo(i); balances[i] = getPoolBalances(poolInfo.crvRewards, i, _account); } return balances; } function getPoolBalances( address _rewardPool, uint256 _pid, address _account ) public view returns (PoolBalances memory) { IBaseRewardPool pool = IBaseRewardPool(_rewardPool); uint256 staked = pool.balanceOf(_account); uint256 earned = pool.earned(_account); uint256 extraRewardsLength = pool.extraRewardsLength(); uint256[] memory extraRewardsEarned = new uint256[](extraRewardsLength); for (uint256 i = 0; i < extraRewardsLength; i++) { IBaseRewardPool extraRewardsPool = IBaseRewardPool(pool.extraRewards(i)); extraRewardsEarned[i] = extraRewardsPool.earned(_account); } return PoolBalances({ pid: _pid, staked: staked, earned: earned, extraRewardsEarned: extraRewardsEarned }); } function getTokens(address[] memory _addresses) public view returns (Token[] memory) { uint256 length = _addresses.length; Token[] memory tokens = new Token[](length); for (uint256 i = 0; i < length; i++) { address addr = _addresses[i]; IERC20Detailed token = IERC20Detailed(addr); uint8 decimals; try token.decimals() { decimals = token.decimals(); } catch { decimals = 0; } tokens[i] = Token({ addr: addr, decimals: decimals, symbol: token.symbol(), name: token.name() }); } return tokens; } function getEarmarkingReward( uint256 pool, address booster, address token ) public returns (uint256 pending) { uint256 start = IERC20Detailed(token).balanceOf(address(this)); IBooster(booster).earmarkRewards(pool); pending = IERC20Detailed(token).balanceOf(address(this)) - start; } function getMultipleEarmarkingRewards( uint256[] memory pools, address booster, address token ) external returns (uint256[] memory pendings) { pendings = new uint256[](pools.length); for (uint256 i = 0; i < pools.length; i++) { pendings[i] = getEarmarkingReward(pools[i], booster, token); } } function convertLitToLiq(uint256 _amount) external view returns (uint256 amount) { uint256 supply = liq.totalSupply(); uint256 totalCliffs = 500; uint256 maxSupply = 5e25; uint256 initMintAmount = 5e25; uint256 reductionPerCliff = 1e23; // After LiqMinter.inflationProtectionTime has passed, this calculation might not be valid. // uint256 emissionsMinted = supply - initMintAmount - minterMinted; uint256 emissionsMinted = supply - initMintAmount; uint256 cliff = emissionsMinted.div(reductionPerCliff); // e.g. 100 < 500 if (cliff < totalCliffs) { // e.g. (new) reduction = (500 - 100) * 0.25 + 70 = 170; // e.g. (new) reduction = (500 - 250) * 0.25 + 70 = 132.5; // e.g. (new) reduction = (500 - 400) * 0.25 + 70 = 95; uint256 reduction = totalCliffs.sub(cliff).div(4).add(70); // e.g. (new) amount = 1e19 * 170 / 500 = 34e17; // e.g. (new) amount = 1e19 * 132.5 / 500 = 26.5e17; // e.g. (new) amount = 1e19 * 95 / 500 = 19e16; amount = _amount.mul(reduction).div(totalCliffs); // e.g. amtTillMax = 5e25 - 1e25 = 4e25 uint256 amtTillMax = maxSupply.sub(emissionsMinted); if (amount > amtTillMax) { amount = amtTillMax; } } } } interface IBaseRewardPool { function extraRewards(uint256 index) external view returns (address rewards); function extraRewardsLength() external view returns (uint256); function lastUpdateTime() external view returns (uint256); function periodFinish() external view returns (uint256); function pid() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); function earned(address owner) external view returns (uint256); function queuedRewards() external view returns (uint256); function rewardPerTokenStored() external view returns (uint256); function rewardRate() external view returns (uint256); function totalSupply() external view returns (uint256); function rewardToken() external view returns (address); function stakingToken() external view returns (address); } interface IERC20Detailed { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); } interface IBunniLpToken { function pool() external view returns (address); function tickLower() external view returns (int24); function tickUpper() external view returns (int24); function name() external view returns (string memory); function symbol() external view returns (string memory); function balanceOf(address user) external view returns (uint256); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); } interface IUniV3Pool { function token0() external view returns (address); function token1() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.11; import { IERC20 } from "@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol"; interface IPriceOracle { struct OracleAverageQuery { Variable variable; uint256 secs; uint256 ago; } enum Variable { PAIR_PRICE, BPT_PRICE, INVARIANT } function getTimeWeightedAverage(OracleAverageQuery[] memory queries) external view returns (uint256[] memory results); } interface IBalancerVault { enum PoolSpecialization { GENERAL, MINIMAL_SWAP_INFO, TWO_TOKEN } enum JoinKind { INIT, EXACT_TOKENS_IN_FOR_BPT_OUT, TOKEN_IN_FOR_EXACT_BPT_OUT, ALL_TOKENS_IN_FOR_EXACT_BPT_OUT } enum SwapKind { GIVEN_IN, GIVEN_OUT } struct BatchSwapStep { bytes32 poolId; uint256 assetInIndex; uint256 assetOutIndex; uint256 amount; bytes userData; } function batchSwap( SwapKind kind, BatchSwapStep[] memory swaps, IAsset[] memory assets, FundManagement memory funds, int256[] memory limits, uint256 deadline ) external payable returns (int256[] memory); struct SingleSwap { bytes32 poolId; SwapKind kind; IAsset assetIn; IAsset assetOut; uint256 amount; bytes userData; } struct FundManagement { address sender; bool fromInternalBalance; address payable recipient; bool toInternalBalance; } struct JoinPoolRequest { IAsset[] assets; uint256[] maxAmountsIn; bytes userData; bool fromInternalBalance; } function getPool(bytes32 poolId) external view returns (address, PoolSpecialization); function getPoolTokens(bytes32 poolId) external view returns ( address[] memory tokens, uint256[] memory balances, uint256 lastChangeBlock ); function joinPool( bytes32 poolId, address sender, address recipient, JoinPoolRequest memory request ) external payable; function swap( SingleSwap memory singleSwap, FundManagement memory funds, uint256 limit, uint256 deadline ) external returns (uint256 amountCalculated); function exitPool( bytes32 poolId, address sender, address payable recipient, ExitPoolRequest memory request ) external; function getInternalBalance(address user, address[] memory tokens) external view returns (uint256[] memory); function queryBatchSwap( SwapKind kind, BatchSwapStep[] memory swaps, IAsset[] memory assets, FundManagement memory funds ) external returns (int256[] memory assetDeltas); struct ExitPoolRequest { IAsset[] assets; uint256[] minAmountsOut; bytes userData; bool toInternalBalance; } enum ExitKind { EXACT_BPT_IN_FOR_ONE_TOKEN_OUT, EXACT_BPT_IN_FOR_TOKENS_OUT, BPT_IN_FOR_EXACT_TOKENS_OUT, MANAGEMENT_FEE_TOKENS_OUT // for ManagedPool } } interface IAsset { // solhint-disable-previous-line no-empty-blocks } interface IBalancerPool { function getPoolId() external view returns (bytes32); function getNormalizedWeights() external view returns (uint256[] memory); function getSwapEnabled() external view returns (bool); function getOwner() external view returns (address); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); } interface ILBPFactory { function create( string memory name, string memory symbol, IERC20[] memory tokens, uint256[] memory weights, uint256 swapFeePercentage, address owner, bool swapEnabledOnStart ) external returns (address); } interface ILBP { function setSwapEnabled(bool swapEnabled) external; function updateWeightsGradually( uint256 startTime, uint256 endTime, uint256[] memory endWeights ) external; function getGradualWeightUpdateParams() external view returns ( uint256 startTime, uint256 endTime, uint256[] memory endWeights ); } interface IStablePoolFactory { function create( string memory name, string memory symbol, IERC20[] memory tokens, uint256 amplificationParameter, uint256 swapFeePercentage, address owner ) external returns (address); } interface IWeightedPool2TokensFactory { function create( string memory name, string memory symbol, IERC20[] memory tokens, uint256[] memory weights, uint256 swapFeePercentage, bool oracleEnabled, address owner ) external returns (address); } interface IRateProvider { function getRate() external view returns (uint256); } interface IWeightedPoolFactory { /** * @dev Deploys a new `WeightedPool`. */ function create( string memory name, string memory symbol, IERC20[] memory tokens, uint256[] memory normalizedWeights, IRateProvider[] memory rateProviders, uint256 swapFeePercentage, address owner ) external returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.11; import { IERC20 } from "@openzeppelin/contracts-0.8/token/ERC20/IERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts-0.8/token/ERC20/utils/SafeERC20.sol"; import { Ownable } from "@openzeppelin/contracts-0.8/access/Ownable.sol"; import { ReentrancyGuard } from "@openzeppelin/contracts-0.8/security/ReentrancyGuard.sol"; import { AuraMath, AuraMath32, AuraMath112, AuraMath224 } from "../utils/AuraMath.sol"; import { ILiqLocker } from "../interfaces/ILiqLocker.sol"; import { IRewardStaking } from "../interfaces/IRewardStaking.sol"; import { Permission } from "../utils/Permission.sol"; /** * @title LiqLocker * @author ConvexFinance * @notice Effectively allows for rolling 16 week lockups of CVX, and provides balances available * at each epoch (1 week). Also receives cvxCrv from `CvxStakingProxy` and redistributes * to depositors. * @dev Individual and delegatee vote power lookups both use independent accounting mechanisms. */ contract LiqLocker is ReentrancyGuard, Ownable, Permission, ILiqLocker { using AuraMath for uint256; using AuraMath224 for uint224; using AuraMath112 for uint112; using AuraMath32 for uint32; using SafeERC20 for IERC20; /* ========== STRUCTS ========== */ struct RewardData { /// Timestamp for current period finish uint32 periodFinish; /// Last time any user took action uint32 lastUpdateTime; /// RewardRate for the rest of the period uint96 rewardRate; /// Ever increasing rewardPerToken rate, based on % of total supply uint96 rewardPerTokenStored; } struct UserData { uint128 rewardPerTokenPaid; uint128 rewards; } struct EarnedData { address token; uint256 amount; } struct Balances { uint112 locked; uint32 nextUnlockIndex; } struct LockedBalance { uint112 amount; uint32 unlockTime; } struct Epoch { uint224 supply; uint32 date; //epoch start date } struct DelegateeCheckpoint { uint224 votes; uint32 epochStart; } /* ========== STATE VARIABLES ========== */ // Rewards address[] public rewardTokens; mapping(address => uint256) public queuedRewards; uint256 public constant newRewardRatio = 830; // Core reward data mapping(address => RewardData) public rewardData; // Reward token -> distributor -> is approved to add rewards mapping(address => mapping(address => bool)) public rewardDistributors; // User -> reward token -> amount mapping(address => mapping(address => UserData)) public userData; // Duration that rewards are streamed over uint256 public constant rewardsDuration = 86400 * 7; // Duration of lock/earned penalty period uint256 public constant lockDuration = rewardsDuration * 17; // Balances // Supplies and historic supply uint256 public lockedSupply; // Epochs contains only the tokens that were locked at that epoch, not a cumulative supply Epoch[] public epochs; // Mappings for balance data mapping(address => Balances) public balances; mapping(address => LockedBalance[]) public userLocks; // Voting // Stored delegations mapping(address => address) private _delegates; // Checkpointed votes mapping(address => DelegateeCheckpoint[]) private _checkpointedVotes; // Delegatee balances (user -> unlock timestamp -> amount) mapping(address => mapping(uint256 => uint256)) public delegateeUnlocks; // Config // Blacklisted smart contract interactions mapping(address => bool) public blacklist; // Tokens IERC20 public immutable stakingToken; address public immutable cvxCrv; // Denom for calcs uint256 public constant denominator = 10000; // Staking cvxCrv address public immutable cvxcrvStaking; // olit address address public immutable olit; // Incentives uint256 public kickRewardPerEpoch = 100; uint256 public kickRewardEpochDelay = 3; // Shutdown bool public isShutdown = false; // Basic token data string private _name; string private _symbol; uint8 private immutable _decimals; /* ========== EVENTS ========== */ event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); event DelegateCheckpointed(address indexed delegate); event Recovered(address _token, uint256 _amount); event RewardPaid(address indexed _user, address indexed _rewardsToken, uint256 _reward); event Staked(address indexed _user, uint256 _lockedAmount, uint256 _unlockTime); event Withdrawn(address indexed _user, uint256 _amount, uint256 _expiryTime, bool _relocked); event KickReward(address indexed _user, address indexed _kicked, uint256 _reward); event RewardAdded(address indexed _token, uint256 _reward); event BlacklistModified(address account, bool blacklisted); event KickIncentiveSet(uint256 rate, uint256 delay); event Shutdown(); /*************************************** CONSTRUCTOR ****************************************/ /** * @param _nameArg Token name, simples * @param _symbolArg Token symbol * @param _stakingToken CVX (0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B) * @param _cvxCrv cvxCRV (0x62B9c7356A2Dc64a1969e19C23e4f579F9810Aa7) * @param _cvxCrvStaking cvxCRV rewards (0x3Fe65692bfCD0e6CF84cB1E7d24108E434A7587e) * @param _olit olit token (0x627fee87d0D9D2c55098A06ac805Db8F98B158Aa) */ constructor( string memory _nameArg, string memory _symbolArg, address _stakingToken, address _cvxCrv, address _cvxCrvStaking, address _olit ) Ownable() { _name = _nameArg; _symbol = _symbolArg; _decimals = 18; stakingToken = IERC20(_stakingToken); cvxCrv = _cvxCrv; cvxcrvStaking = _cvxCrvStaking; olit = _olit; uint256 currentEpoch = block.timestamp.div(rewardsDuration).mul(rewardsDuration); epochs.push(Epoch({ supply: 0, date: uint32(currentEpoch) })); } /*************************************** MODIFIER ****************************************/ modifier updateReward(address _account) { { Balances storage userBalance = balances[_account]; uint256 rewardTokensLength = rewardTokens.length; for (uint256 i = 0; i < rewardTokensLength; i++) { address token = rewardTokens[i]; uint256 newRewardPerToken = _rewardPerToken(token); rewardData[token].rewardPerTokenStored = newRewardPerToken.to96(); rewardData[token].lastUpdateTime = _lastTimeRewardApplicable(rewardData[token].periodFinish).to32(); if (_account != address(0)) { userData[_account][token] = UserData({ rewardPerTokenPaid: newRewardPerToken.to128(), rewards: _earned(_account, token, userBalance.locked).to128() }); } } } _; } modifier notBlacklisted(address _sender, address _receiver) { require(!blacklist[_sender], "blacklisted"); if (_sender != _receiver) { require(!blacklist[_receiver], "blacklisted"); } _; } /*************************************** ADMIN ****************************************/ function modifyBlacklist(address _account, bool _blacklisted) external onlyOwner { uint256 cs; // solhint-disable-next-line no-inline-assembly assembly { cs := extcodesize(_account) } require(cs != 0, "Must be contract"); blacklist[_account] = _blacklisted; emit BlacklistModified(_account, _blacklisted); } // Add a new reward token to be distributed to stakers function addReward(address _rewardsToken, address _distributor) external onlyOwner { require(rewardData[_rewardsToken].lastUpdateTime == 0, "Reward already exists"); require(_rewardsToken != address(stakingToken), "Cannot add StakingToken as reward"); require(rewardTokens.length < 5, "Max rewards length"); rewardTokens.push(_rewardsToken); rewardData[_rewardsToken].lastUpdateTime = uint32(block.timestamp); rewardData[_rewardsToken].periodFinish = uint32(block.timestamp); rewardDistributors[_rewardsToken][_distributor] = true; } // Modify approval for an address to call notifyRewardAmount function approveRewardDistributor( address _rewardsToken, address _distributor, bool _approved ) external onlyOwner { require(rewardData[_rewardsToken].lastUpdateTime > 0, "Reward does not exist"); rewardDistributors[_rewardsToken][_distributor] = _approved; } //set kick incentive function setKickIncentive(uint256 _rate, uint256 _delay) external onlyOwner { require(_rate <= 500, "over max rate"); //max 5% per epoch require(_delay >= 2, "min delay"); //minimum 2 epochs of grace kickRewardPerEpoch = _rate; kickRewardEpochDelay = _delay; emit KickIncentiveSet(_rate, _delay); } //shutdown the contract. unstake all tokens. release all locks function shutdown() external onlyOwner { isShutdown = true; emit Shutdown(); } // Added to support recovering LP Rewards from other systems such as BAL to be distributed to holders function recoverERC20(address _tokenAddress, uint256 _tokenAmount) external onlyOwner { require(_tokenAddress != address(stakingToken), "Cannot withdraw staking token"); require(rewardData[_tokenAddress].lastUpdateTime == 0, "Cannot withdraw reward token"); IERC20(_tokenAddress).safeTransfer(owner(), _tokenAmount); emit Recovered(_tokenAddress, _tokenAmount); } // Set approvals for staking cvx and cvxcrv function setApprovals() external { IERC20(cvxCrv).safeApprove(cvxcrvStaking, 0); IERC20(cvxCrv).safeApprove(cvxcrvStaking, type(uint256).max); } /*************************************** ACTIONS ****************************************/ // Locked tokens cannot be withdrawn for lockDuration and are eligible to receive stakingReward rewards function lock(address _account, uint256 _amount) external nonReentrant updateReward(_account) { //pull tokens stakingToken.safeTransferFrom(msg.sender, address(this), _amount); //lock _lock(_account, _amount); } //lock tokens function _lock(address _account, uint256 _amount) internal notBlacklisted(msg.sender, _account) { require(_amount > 0, "Cannot stake 0"); require(!isShutdown, "shutdown"); Balances storage bal = balances[_account]; //must try check pointing epoch first _checkpointEpoch(); //add user balances uint112 lockAmount = _amount.to112(); bal.locked = bal.locked.add(lockAmount); //add to total supplies lockedSupply = lockedSupply.add(_amount); //add user lock records or add to current uint256 currentEpoch = block.timestamp.div(rewardsDuration).mul(rewardsDuration); uint256 unlockTime = currentEpoch.add(lockDuration); uint256 idx = userLocks[_account].length; if (idx == 0 || userLocks[_account][idx - 1].unlockTime < unlockTime) { userLocks[_account].push(LockedBalance({ amount: lockAmount, unlockTime: uint32(unlockTime) })); } else { LockedBalance storage userL = userLocks[_account][idx - 1]; userL.amount = userL.amount.add(lockAmount); } address delegatee = delegates(_account); if (delegatee != address(0)) { delegateeUnlocks[delegatee][unlockTime] += lockAmount; _checkpointDelegate(delegatee, lockAmount, 0); } //update epoch supply, epoch checkpointed above so safe to add to latest Epoch storage e = epochs[epochs.length - 1]; e.supply = e.supply.add(lockAmount); emit Staked(_account, lockAmount, unlockTime); } // claim all pending rewards function getReward(address _account) external { getReward(_account, false); } // Claim all pending rewards function getReward(address _account, bool _stake) public nonReentrant updateReward(_account) { uint256 rewardTokensLength = rewardTokens.length; for (uint256 i; i < rewardTokensLength; i++) { address _rewardsToken = rewardTokens[i]; uint256 reward = userData[_account][_rewardsToken].rewards; if (reward > 0) { userData[_account][_rewardsToken].rewards = 0; if (_rewardsToken == cvxCrv && _stake && _account == msg.sender) { IRewardStaking(cvxcrvStaking).stakeFor(_account, reward); } else { IERC20(_rewardsToken).safeTransfer(_account, reward); } emit RewardPaid(_account, _rewardsToken, reward); } } } function getReward(address _account, bool[] calldata _skipIdx) external nonReentrant updateReward(_account) { uint256 rewardTokensLength = rewardTokens.length; require(_skipIdx.length == rewardTokensLength, "!arr"); for (uint256 i; i < rewardTokensLength; i++) { if (_skipIdx[i]) continue; address _rewardsToken = rewardTokens[i]; uint256 reward = userData[_account][_rewardsToken].rewards; if (reward > 0) { userData[_account][_rewardsToken].rewards = 0; IERC20(_rewardsToken).safeTransfer(_account, reward); emit RewardPaid(_account, _rewardsToken, reward); } } } /** * @dev Sends oLIT to OptionsExerciser for converting it to LIT or liqLit, LIQ and extra rewards are sent to the user * @param _account Account for which to claim * @return rewardAmount oLIT amount claimed as reward */ function getRewardFor(address _account) external nonReentrant updateReward(_account) returns (uint256 rewardAmount) { require(hasPermission(_account, msg.sender), "permission not granted"); uint256 rewardTokensLength = rewardTokens.length; for (uint256 i; i < rewardTokensLength; i++) { address _rewardsToken = rewardTokens[i]; uint256 reward = userData[_account][_rewardsToken].rewards; if (reward > 0) { userData[_account][_rewardsToken].rewards = 0; if (_rewardsToken == olit) { IERC20(_rewardsToken).safeTransfer(msg.sender, reward); rewardAmount = reward; // return oLIT amount claimed } else { IERC20(_rewardsToken).safeTransfer(_account, reward); } emit RewardPaid(_account, _rewardsToken, reward); } } } function checkpointEpoch() external { _checkpointEpoch(); } //insert a new epoch if needed. fill in any gaps function _checkpointEpoch() internal { uint256 currentEpoch = block.timestamp.div(rewardsDuration).mul(rewardsDuration); //first epoch add in constructor, no need to check 0 length //check to add uint256 nextEpochDate = uint256(epochs[epochs.length - 1].date); if (nextEpochDate < currentEpoch) { while (nextEpochDate != currentEpoch) { nextEpochDate = nextEpochDate.add(rewardsDuration); epochs.push(Epoch({ supply: 0, date: uint32(nextEpochDate) })); } } } // Withdraw/relock all currently locked tokens where the unlock time has passed function processExpiredLocks(bool _relock) external nonReentrant { _processExpiredLocks(msg.sender, _relock, msg.sender, 0); } function kickExpiredLocks(address _account) external nonReentrant { //allow kick after grace period of 'kickRewardEpochDelay' _processExpiredLocks(_account, false, msg.sender, rewardsDuration.mul(kickRewardEpochDelay)); } // Withdraw without checkpointing or accruing any rewards, providing system is shutdown function emergencyWithdraw() external nonReentrant { require(isShutdown, "Must be shutdown"); LockedBalance[] memory locks = userLocks[msg.sender]; Balances storage userBalance = balances[msg.sender]; uint256 amt = userBalance.locked; require(amt > 0, "Nothing locked"); userBalance.locked = 0; userBalance.nextUnlockIndex = locks.length.to32(); lockedSupply -= amt; emit Withdrawn(msg.sender, amt, type(uint256).max, false); stakingToken.safeTransfer(msg.sender, amt); } // Withdraw all currently locked tokens where the unlock time has passed function _processExpiredLocks( address _account, bool _relock, address _rewardAddress, uint256 _checkDelay ) internal updateReward(_account) { LockedBalance[] storage locks = userLocks[_account]; Balances storage userBalance = balances[_account]; uint112 locked; uint256 length = locks.length; uint256 reward = 0; uint256 expiryTime = _checkDelay == 0 && _relock ? block.timestamp.add(rewardsDuration) : block.timestamp.sub(_checkDelay); require(length > 0, "no locks"); // e.g. now = 16 // if contract is shutdown OR latest lock unlock time (e.g. 17) <= now - (1) // e.g. 17 <= (16 + 1) if (isShutdown || locks[length - 1].unlockTime <= expiryTime) { //if time is beyond last lock, can just bundle everything together locked = userBalance.locked; //dont delete, just set next index userBalance.nextUnlockIndex = length.to32(); //check for kick reward //this wont have the exact reward rate that you would get if looped through //but this section is supposed to be for quick and easy low gas processing of all locks //we'll assume that if the reward was good enough someone would have processed at an earlier epoch if (_checkDelay > 0) { uint256 currentEpoch = block.timestamp.sub(_checkDelay).div(rewardsDuration).mul(rewardsDuration); uint256 epochsover = currentEpoch.sub(uint256(locks[length - 1].unlockTime)).div(rewardsDuration); uint256 rRate = AuraMath.min(kickRewardPerEpoch.mul(epochsover + 1), denominator); reward = uint256(locked).mul(rRate).div(denominator); } } else { //use a processed index(nextUnlockIndex) to not loop as much //deleting does not change array length uint32 nextUnlockIndex = userBalance.nextUnlockIndex; for (uint256 i = nextUnlockIndex; i < length; i++) { //unlock time must be less or equal to time if (locks[i].unlockTime > expiryTime) break; //add to cumulative amounts locked = locked.add(locks[i].amount); //check for kick reward //each epoch over due increases reward if (_checkDelay > 0) { uint256 currentEpoch = block.timestamp.sub(_checkDelay).div(rewardsDuration).mul(rewardsDuration); uint256 epochsover = currentEpoch.sub(uint256(locks[i].unlockTime)).div(rewardsDuration); uint256 rRate = AuraMath.min(kickRewardPerEpoch.mul(epochsover + 1), denominator); reward = reward.add(uint256(locks[i].amount).mul(rRate).div(denominator)); } //set next unlock index nextUnlockIndex++; } //update next unlock index userBalance.nextUnlockIndex = nextUnlockIndex; } require(locked > 0, "no exp locks"); //update user balances and total supplies userBalance.locked = userBalance.locked.sub(locked); lockedSupply = lockedSupply.sub(locked); //checkpoint the delegatee _checkpointDelegate(delegates(_account), 0, 0); emit Withdrawn(_account, locked, expiryTime, _relock); //send process incentive if (reward > 0) { //reduce return amount by the kick reward locked = locked.sub(reward.to112()); //transfer reward stakingToken.safeTransfer(_rewardAddress, reward); emit KickReward(_rewardAddress, _account, reward); } //relock or return to user if (_relock) { _lock(_account, locked); } else { stakingToken.safeTransfer(_account, locked); } } /*************************************** DELEGATION & VOTE BALANCE ****************************************/ /** * @dev Delegate votes from the sender to `newDelegatee`. */ function delegate(address newDelegatee) external virtual nonReentrant { // Step 1: Get lock data LockedBalance[] storage locks = userLocks[msg.sender]; uint256 len = locks.length; require(len > 0, "Nothing to delegate"); require(newDelegatee != address(0), "Must delegate to someone"); // Step 2: Update delegatee storage address oldDelegatee = delegates(msg.sender); require(newDelegatee != oldDelegatee, "Must choose new delegatee"); _delegates[msg.sender] = newDelegatee; emit DelegateChanged(msg.sender, oldDelegatee, newDelegatee); // Step 3: Move balances around // Delegate for the upcoming epoch uint256 upcomingEpoch = block.timestamp.add(rewardsDuration).div(rewardsDuration).mul(rewardsDuration); uint256 i = len - 1; uint256 futureUnlocksSum = 0; LockedBalance memory currentLock = locks[i]; // Step 3.1: Add future unlocks and sum balances while (currentLock.unlockTime > upcomingEpoch) { futureUnlocksSum += currentLock.amount; if (oldDelegatee != address(0)) { delegateeUnlocks[oldDelegatee][currentLock.unlockTime] -= currentLock.amount; } delegateeUnlocks[newDelegatee][currentLock.unlockTime] += currentLock.amount; if (i > 0) { i--; currentLock = locks[i]; } else { break; } } // Step 3.2: Checkpoint old delegatee _checkpointDelegate(oldDelegatee, 0, futureUnlocksSum); // Step 3.3: Checkpoint new delegatee _checkpointDelegate(newDelegatee, futureUnlocksSum, 0); } function _checkpointDelegate( address _account, uint256 _upcomingAddition, uint256 _upcomingDeduction ) internal { // This would only skip on first checkpointing if (_account != address(0)) { uint256 upcomingEpoch = block.timestamp.add(rewardsDuration).div(rewardsDuration).mul(rewardsDuration); DelegateeCheckpoint[] storage ckpts = _checkpointedVotes[_account]; if (ckpts.length > 0) { DelegateeCheckpoint memory prevCkpt = ckpts[ckpts.length - 1]; // If there has already been a record for the upcoming epoch, no need to deduct the unlocks if (prevCkpt.epochStart == upcomingEpoch) { ckpts[ckpts.length - 1] = DelegateeCheckpoint({ votes: (prevCkpt.votes + _upcomingAddition - _upcomingDeduction).to224(), epochStart: upcomingEpoch.to32() }); } // else if it has been over 16 weeks since the previous checkpoint, all locks have since expired // e.g. week 1 + 17 <= 18 else if (prevCkpt.epochStart + lockDuration <= upcomingEpoch) { ckpts.push( DelegateeCheckpoint({ votes: (_upcomingAddition - _upcomingDeduction).to224(), epochStart: upcomingEpoch.to32() }) ); } else { uint256 nextEpoch = upcomingEpoch; uint256 unlocksSinceLatestCkpt = 0; // Should be maximum 18 iterations while (nextEpoch > prevCkpt.epochStart) { unlocksSinceLatestCkpt += delegateeUnlocks[_account][nextEpoch]; nextEpoch -= rewardsDuration; } ckpts.push( DelegateeCheckpoint({ votes: (prevCkpt.votes - unlocksSinceLatestCkpt + _upcomingAddition - _upcomingDeduction) .to224(), epochStart: upcomingEpoch.to32() }) ); } } else { ckpts.push( DelegateeCheckpoint({ votes: (_upcomingAddition - _upcomingDeduction).to224(), epochStart: upcomingEpoch.to32() }) ); } emit DelegateCheckpointed(_account); } } /** * @dev Get the address `account` is currently delegating to. */ function delegates(address account) public view virtual returns (address) { return _delegates[account]; } /** * @dev Gets the current votes balance for `account` */ function getVotes(address account) external view returns (uint256) { return getPastVotes(account, block.timestamp); } /** * @dev Get the `pos`-th checkpoint for `account`. */ function checkpoints(address account, uint32 pos) external view virtual returns (DelegateeCheckpoint memory) { return _checkpointedVotes[account][pos]; } /** * @dev Get number of checkpoints for `account`. */ function numCheckpoints(address account) external view virtual returns (uint32) { return _checkpointedVotes[account].length.to32(); } /** * @dev Retrieve the number of votes for `account` at the end of `blockNumber`. */ function getPastVotes(address account, uint256 timestamp) public view returns (uint256 votes) { require(timestamp <= block.timestamp, "ERC20Votes: block not yet mined"); uint256 epoch = timestamp.div(rewardsDuration).mul(rewardsDuration); DelegateeCheckpoint memory ckpt = _checkpointsLookup(_checkpointedVotes[account], epoch); votes = ckpt.votes; if (votes == 0 || ckpt.epochStart + lockDuration <= epoch) { return 0; } while (epoch > ckpt.epochStart) { votes -= delegateeUnlocks[account][epoch]; epoch -= rewardsDuration; } } /** * @dev Retrieve the `totalSupply` at the end of `timestamp`. Note, this value is the sum of all balances. * It is but NOT the sum of all the delegated votes! */ function getPastTotalSupply(uint256 timestamp) external view returns (uint256) { require(timestamp < block.timestamp, "ERC20Votes: block not yet mined"); return totalSupplyAtEpoch(findEpochId(timestamp)); } /** * @dev Lookup a value in a list of (sorted) checkpoints. * Copied from oz/ERC20Votes.sol */ function _checkpointsLookup(DelegateeCheckpoint[] storage ckpts, uint256 epochStart) private view returns (DelegateeCheckpoint memory) { uint256 high = ckpts.length; uint256 low = 0; while (low < high) { uint256 mid = AuraMath.average(low, high); if (ckpts[mid].epochStart > epochStart) { high = mid; } else { low = mid + 1; } } return high == 0 ? DelegateeCheckpoint(0, 0) : ckpts[high - 1]; } /*************************************** VIEWS - BALANCES ****************************************/ // Balance of an account which only includes properly locked tokens as of the most recent eligible epoch function balanceOf(address _user) external view returns (uint256 amount) { return balanceAtEpochOf(findEpochId(block.timestamp), _user); } // Balance of an account which only includes properly locked tokens at the given epoch function balanceAtEpochOf(uint256 _epoch, address _user) public view returns (uint256 amount) { uint256 epochStart = uint256(epochs[0].date).add(uint256(_epoch).mul(rewardsDuration)); require(epochStart < block.timestamp, "Epoch is in the future"); uint256 cutoffEpoch = epochStart.sub(lockDuration); LockedBalance[] storage locks = userLocks[_user]; //need to add up since the range could be in the middle somewhere //traverse inversely to make more current queries more gas efficient uint256 locksLength = locks.length; for (uint256 i = locksLength; i > 0; i--) { uint256 lockEpoch = uint256(locks[i - 1].unlockTime).sub(lockDuration); //lock epoch must be less or equal to the epoch we're basing from. //also not include the current epoch if (lockEpoch < epochStart) { if (lockEpoch > cutoffEpoch) { amount = amount.add(locks[i - 1].amount); } else { //stop now as no futher checks matter break; } } } return amount; } // Information on a user's locked balances function lockedBalances(address _user) external view returns ( uint256 total, uint256 unlockable, uint256 locked, LockedBalance[] memory lockData ) { LockedBalance[] storage locks = userLocks[_user]; Balances storage userBalance = balances[_user]; uint256 nextUnlockIndex = userBalance.nextUnlockIndex; uint256 idx; for (uint256 i = nextUnlockIndex; i < locks.length; i++) { if (locks[i].unlockTime > block.timestamp) { if (idx == 0) { lockData = new LockedBalance[](locks.length - i); } lockData[idx] = locks[i]; idx++; locked = locked.add(locks[i].amount); } else { unlockable = unlockable.add(locks[i].amount); } } return (userBalance.locked, unlockable, locked, lockData); } // Supply of all properly locked balances at most recent eligible epoch function totalSupply() external view returns (uint256 supply) { return totalSupplyAtEpoch(findEpochId(block.timestamp)); } // Supply of all properly locked balances at the given epoch function totalSupplyAtEpoch(uint256 _epoch) public view returns (uint256 supply) { uint256 epochStart = uint256(epochs[0].date).add(uint256(_epoch).mul(rewardsDuration)); require(epochStart < block.timestamp, "Epoch is in the future"); uint256 cutoffEpoch = epochStart.sub(lockDuration); uint256 lastIndex = epochs.length - 1; uint256 epochIndex = _epoch > lastIndex ? lastIndex : _epoch; for (uint256 i = epochIndex + 1; i > 0; i--) { Epoch memory e = epochs[i - 1]; if (e.date == epochStart) { continue; } else if (e.date <= cutoffEpoch) { break; } else { supply += e.supply; } } } // Get an epoch index based on timestamp function findEpochId(uint256 _time) public view returns (uint256 epoch) { return _time.sub(epochs[0].date).div(rewardsDuration); } /*************************************** VIEWS - GENERAL ****************************************/ // Number of epochs function epochCount() external view returns (uint256) { return epochs.length; } function decimals() external view returns (uint8) { return _decimals; } function name() external view returns (string memory) { return _name; } function symbol() external view returns (string memory) { return _symbol; } /*************************************** VIEWS - REWARDS ****************************************/ // Address and claimable amount of all reward tokens for the given account function claimableRewards(address _account) external view returns (EarnedData[] memory userRewards) { userRewards = new EarnedData[](rewardTokens.length); Balances storage userBalance = balances[_account]; uint256 userRewardsLength = userRewards.length; for (uint256 i = 0; i < userRewardsLength; i++) { address token = rewardTokens[i]; userRewards[i].token = token; userRewards[i].amount = _earned(_account, token, userBalance.locked); } return userRewards; } function lastTimeRewardApplicable(address _rewardsToken) external view returns (uint256) { return _lastTimeRewardApplicable(rewardData[_rewardsToken].periodFinish); } function rewardPerToken(address _rewardsToken) external view returns (uint256) { return _rewardPerToken(_rewardsToken); } // Claimable amount of a specific reward token for the given account // For compatibility with BaseRewardPool function earned(address _account, address token) external view returns (uint256 userRewards) { Balances storage userBalance = balances[_account]; userRewards = _earned(_account, token, userBalance.locked); } function _earned( address _user, address _rewardsToken, uint256 _balance ) internal view returns (uint256) { UserData memory data = userData[_user][_rewardsToken]; return _balance.mul(_rewardPerToken(_rewardsToken).sub(data.rewardPerTokenPaid)).div(1e18).add(data.rewards); } function _lastTimeRewardApplicable(uint256 _finishTime) internal view returns (uint256) { return AuraMath.min(block.timestamp, _finishTime); } function _rewardPerToken(address _rewardsToken) internal view returns (uint256) { if (lockedSupply == 0) { return rewardData[_rewardsToken].rewardPerTokenStored; } return uint256(rewardData[_rewardsToken].rewardPerTokenStored).add( _lastTimeRewardApplicable(rewardData[_rewardsToken].periodFinish) .sub(rewardData[_rewardsToken].lastUpdateTime) .mul(rewardData[_rewardsToken].rewardRate) .mul(1e18) .div(lockedSupply) ); } /*************************************** REWARD FUNDING ****************************************/ /// @notice no pull method, rewards are first transferred and subsequently call queueNewRewards function queueNewRewards(address _rewardsToken, uint256 _rewards) external nonReentrant { require(rewardDistributors[_rewardsToken][msg.sender], "!authorized"); require(_rewards > 0, "No reward"); RewardData storage rdata = rewardData[_rewardsToken]; _rewards = _rewards.add(queuedRewards[_rewardsToken]); require(_rewards < 1e25, "!rewards"); if (block.timestamp >= rdata.periodFinish) { _notifyReward(_rewardsToken, _rewards); queuedRewards[_rewardsToken] = 0; return; } //et = now - (finish-duration) uint256 elapsedTime = block.timestamp.sub(rdata.periodFinish.sub(rewardsDuration.to32())); //current at now: rewardRate * elapsedTime uint256 currentAtNow = rdata.rewardRate * elapsedTime; uint256 queuedRatio = currentAtNow.mul(1000).div(_rewards); if (queuedRatio < newRewardRatio) { _notifyReward(_rewardsToken, _rewards); queuedRewards[_rewardsToken] = 0; } else { queuedRewards[_rewardsToken] = _rewards; } } function _notifyReward(address _rewardsToken, uint256 _reward) internal updateReward(address(0)) { RewardData storage rdata = rewardData[_rewardsToken]; if (block.timestamp >= rdata.periodFinish) { rdata.rewardRate = _reward.div(rewardsDuration).to96(); } else { uint256 remaining = uint256(rdata.periodFinish).sub(block.timestamp); uint256 leftover = remaining.mul(rdata.rewardRate); rdata.rewardRate = _reward.add(leftover).div(rewardsDuration).to96(); } // Equivalent to 10 million tokens over a weeks duration require(rdata.rewardRate < 1e20, "!rewardRate"); require(lockedSupply >= 1e20, "!balance"); rdata.lastUpdateTime = block.timestamp.to32(); rdata.periodFinish = block.timestamp.add(rewardsDuration).to32(); emit RewardAdded(_rewardsToken, _reward); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.11; interface IBooster { struct FeeDistro { address distro; address rewards; bool active; } function feeTokens(address _token) external returns (FeeDistro memory); function earmarkFees(address _feeToken) external returns (bool); struct PoolInfo { address lptoken; address token; address gauge; address crvRewards; address stash; bool shutdown; } function earmarkRewards(uint256 _pid) external returns (bool); function poolInfo(uint256 _pid) external view returns (PoolInfo memory poolInfo); function poolLength() external view returns (uint256); function lockRewards() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.11; /// @notice A library for performing overflow-/underflow-safe math, /// updated with awesomeness from of DappHub (https://github.com/dapphub/ds-math). library Math { /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } function add(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a + b; } function sub(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a - b; } function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a * b; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return 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, so we distribute. return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2); } function to224(uint256 a) internal pure returns (uint224 c) { require(a <= type(uint224).max, "Math: uint224 Overflow"); c = uint224(a); } function to128(uint256 a) internal pure returns (uint128 c) { require(a <= type(uint128).max, "Math: uint128 Overflow"); c = uint128(a); } function to112(uint256 a) internal pure returns (uint112 c) { require(a <= type(uint112).max, "Math: uint112 Overflow"); c = uint112(a); } function to96(uint256 a) internal pure returns (uint96 c) { require(a <= type(uint96).max, "Math: uint96 Overflow"); c = uint96(a); } function to32(uint256 a) internal pure returns (uint32 c) { require(a <= type(uint32).max, "Math: uint32 Overflow"); c = uint32(a); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint32. library Math32 { function sub(uint32 a, uint32 b) internal pure returns (uint32 c) { c = a - b; } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint112. library Math112 { function add(uint112 a, uint112 b) internal pure returns (uint112 c) { c = a + b; } function sub(uint112 a, uint112 b) internal pure returns (uint112 c) { c = a - b; } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint224. library Math224 { function add(uint224 a, uint224 b) internal pure returns (uint224 c) { c = a + b; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.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; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } 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"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (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 Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _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 v4.4.1 (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() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.11; /// @notice A library for performing overflow-/underflow-safe math, /// updated with awesomeness from of DappHub (https://github.com/dapphub/ds-math). library AuraMath { /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } function add(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a + b; } function sub(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a - b; } function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a * b; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return 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, so we distribute. return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2); } function to224(uint256 a) internal pure returns (uint224 c) { require(a <= type(uint224).max, "AuraMath: uint224 Overflow"); c = uint224(a); } function to128(uint256 a) internal pure returns (uint128 c) { require(a <= type(uint128).max, "AuraMath: uint128 Overflow"); c = uint128(a); } function to112(uint256 a) internal pure returns (uint112 c) { require(a <= type(uint112).max, "AuraMath: uint112 Overflow"); c = uint112(a); } function to96(uint256 a) internal pure returns (uint96 c) { require(a <= type(uint96).max, "AuraMath: uint96 Overflow"); c = uint96(a); } function to32(uint256 a) internal pure returns (uint32 c) { require(a <= type(uint32).max, "AuraMath: uint32 Overflow"); c = uint32(a); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint32. library AuraMath32 { function sub(uint32 a, uint32 b) internal pure returns (uint32 c) { c = a - b; } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint112. library AuraMath112 { function add(uint112 a, uint112 b) internal pure returns (uint112 c) { c = a + b; } function sub(uint112 a, uint112 b) internal pure returns (uint112 c) { c = a - b; } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint224. library AuraMath224 { function add(uint224 a, uint224 b) internal pure returns (uint224 c) { c = a + b; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.11; interface ILiqLocker { function lock(address _account, uint256 _amount) external; function checkpointEpoch() external; function epochCount() external view returns (uint256); function balanceAtEpochOf(uint256 _epoch, address _user) external view returns (uint256 amount); function totalSupplyAtEpoch(uint256 _epoch) external view returns (uint256 supply); function queueNewRewards(address _rewardsToken, uint256 reward) external; function getReward(address _account, bool _stake) external; function getReward(address _account) external; function getRewardFor(address _account) external returns (uint256 rewardAmount); function earned(address _account, address token) external view returns (uint256 userRewards); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.11; interface IRewardStaking { function getReward(address _account, bool _claimExtras) external; function getReward(address _account) external; function getReward(address _account, address _token) external; function stakeFor(address, uint256) external; function processIdleRewards() external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.11; /** * @title Permission * @author Liquis Finance * @notice A simple permissions system giving a `caller` the ability to act on behalf of `owner` * @dev Other than ERC20 Allowances, Permissions are boolean giving `caller` the ability * to call a specific contract function without further controls. * Permission are thought to allow users to give peripheral contracts permission to act * on their behalf in order to improve UX e.g. around claiming rewards. */ abstract contract Permission { event ModifyPermission(address owner, address caller, bool grant); /// @notice Specify whether `caller` can act on behalf of `owner` mapping(address => mapping(address => bool)) private _permitted; /** * @notice Allow (or revoke allowance) `caller` to act on behalf of `msg.sender` * @param caller Address of the `caller` * @param permitted Allow (true) or revoke (false) permission */ function modifyPermission(address caller, bool permitted) external { _permitted[msg.sender][caller] = permitted; emit ModifyPermission(msg.sender, caller, permitted); } /** * @notice Checks permission of `caller` to act on behalf of `owner` * @param owner Address of the `owner` * @param caller Address of the `caller` * @return permission Whether `caller` has the permission */ function hasPermission(address owner, address caller) public view returns (bool) { return owner == caller || _permitted[owner][caller]; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.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) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// 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; } }
{ "optimizer": { "enabled": true, "runs": 1000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"balancerVault","outputs":[{"internalType":"contract IBalancerVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"convertLitToLiq","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_cvxCrvRewards","type":"address"}],"name":"getCvxCrvRewards","outputs":[{"components":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"lptoken","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"gauge","type":"address"},{"internalType":"address","name":"crvRewards","type":"address"},{"internalType":"address","name":"stash","type":"address"},{"internalType":"bool","name":"shutdown","type":"bool"},{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"address","name":"uniV3Pool","type":"address"},{"internalType":"address[]","name":"poolTokens","type":"address[]"},{"internalType":"int24[]","name":"ticks","type":"int24[]"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"components":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"queuedRewards","type":"uint256"}],"internalType":"struct LiquisViewHelpers.RewardsData","name":"rewardsData","type":"tuple"},{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"address","name":"rewardsToken","type":"address"},{"components":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"queuedRewards","type":"uint256"}],"internalType":"struct LiquisViewHelpers.RewardsData","name":"rewardsData","type":"tuple"}],"internalType":"struct LiquisViewHelpers.ExtraRewards[]","name":"extraRewards","type":"tuple[]"}],"internalType":"struct LiquisViewHelpers.Pool","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pool","type":"uint256"},{"internalType":"address","name":"booster","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"getEarmarkingReward","outputs":[{"internalType":"uint256","name":"pending","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_locker","type":"address"}],"name":"getLocker","outputs":[{"components":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"lockedSupply","type":"uint256"},{"components":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"queuedRewards","type":"uint256"}],"internalType":"struct LiquisViewHelpers.RewardsData","name":"rewardsData","type":"tuple"}],"internalType":"struct LiquisViewHelpers.Locker","name":"locker","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_locker","type":"address"},{"internalType":"address","name":"_account","type":"address"}],"name":"getLockerAccount","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"unlockable","type":"uint256"},{"internalType":"uint256","name":"locked","type":"uint256"},{"internalType":"uint256","name":"nextUnlockIndex","type":"uint256"},{"internalType":"uint128","name":"rewardPerTokenPaid","type":"uint128"},{"internalType":"uint128","name":"rewards","type":"uint128"},{"internalType":"address","name":"delegate","type":"address"},{"internalType":"uint256","name":"votes","type":"uint256"},{"components":[{"internalType":"uint112","name":"amount","type":"uint112"},{"internalType":"uint32","name":"unlockTime","type":"uint32"}],"internalType":"struct LiqLocker.LockedBalance[]","name":"lockData","type":"tuple[]"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct LiqLocker.EarnedData[]","name":"claimableRewards","type":"tuple[]"}],"internalType":"struct LiquisViewHelpers.LockerAccount","name":"lockerAccount","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"pools","type":"uint256[]"},{"internalType":"address","name":"booster","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"getMultipleEarmarkingRewards","outputs":[{"internalType":"uint256[]","name":"pendings","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"lptoken","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"gauge","type":"address"},{"internalType":"address","name":"crvRewards","type":"address"},{"internalType":"address","name":"stash","type":"address"},{"internalType":"bool","name":"shutdown","type":"bool"}],"internalType":"struct IBooster.PoolInfo","name":"poolInfo","type":"tuple"},{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"getPool","outputs":[{"components":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"lptoken","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"gauge","type":"address"},{"internalType":"address","name":"crvRewards","type":"address"},{"internalType":"address","name":"stash","type":"address"},{"internalType":"bool","name":"shutdown","type":"bool"},{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"address","name":"uniV3Pool","type":"address"},{"internalType":"address[]","name":"poolTokens","type":"address[]"},{"internalType":"int24[]","name":"ticks","type":"int24[]"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"components":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"queuedRewards","type":"uint256"}],"internalType":"struct LiquisViewHelpers.RewardsData","name":"rewardsData","type":"tuple"},{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"address","name":"rewardsToken","type":"address"},{"components":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"queuedRewards","type":"uint256"}],"internalType":"struct LiquisViewHelpers.RewardsData","name":"rewardsData","type":"tuple"}],"internalType":"struct LiquisViewHelpers.ExtraRewards[]","name":"extraRewards","type":"tuple[]"}],"internalType":"struct LiquisViewHelpers.Pool","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardPool","type":"address"},{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_account","type":"address"}],"name":"getPoolBalances","outputs":[{"components":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"earned","type":"uint256"},{"internalType":"uint256[]","name":"extraRewardsEarned","type":"uint256[]"},{"internalType":"uint256","name":"staked","type":"uint256"}],"internalType":"struct LiquisViewHelpers.PoolBalances","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_booster","type":"address"}],"name":"getPools","outputs":[{"components":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"lptoken","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"gauge","type":"address"},{"internalType":"address","name":"crvRewards","type":"address"},{"internalType":"address","name":"stash","type":"address"},{"internalType":"bool","name":"shutdown","type":"bool"},{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"address","name":"uniV3Pool","type":"address"},{"internalType":"address[]","name":"poolTokens","type":"address[]"},{"internalType":"int24[]","name":"ticks","type":"int24[]"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"components":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"queuedRewards","type":"uint256"}],"internalType":"struct LiquisViewHelpers.RewardsData","name":"rewardsData","type":"tuple"},{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"address","name":"rewardsToken","type":"address"},{"components":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"queuedRewards","type":"uint256"}],"internalType":"struct LiquisViewHelpers.RewardsData","name":"rewardsData","type":"tuple"}],"internalType":"struct LiquisViewHelpers.ExtraRewards[]","name":"extraRewards","type":"tuple[]"}],"internalType":"struct LiquisViewHelpers.Pool[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_booster","type":"address"},{"internalType":"address","name":"_account","type":"address"}],"name":"getPoolsBalances","outputs":[{"components":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"earned","type":"uint256"},{"internalType":"uint256[]","name":"extraRewardsEarned","type":"uint256[]"},{"internalType":"uint256","name":"staked","type":"uint256"}],"internalType":"struct LiquisViewHelpers.PoolBalances[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"getTokens","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct LiquisViewHelpers.Token[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liq","outputs":[{"internalType":"contract IERC20Detailed","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c060405273d82fd4d6d62f89a1e50b1db69ad19932314aa40860805273ba12222222228d8ba445958a75a0704d566bf2c860a05234801561004057600080fd5b5060805160a0516137e161006c600039600060e90152600081816102bd01526102e401526137e16000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c80635c39f4671161008c578063919884bf11610066578063919884bf1461021c5780639b9e095514610285578063eda24290146102a5578063faba8c3b146102b857600080fd5b80635c39f467146101bc578063654b72f1146101dc5780637f5f53d1146101fc57600080fd5b8063273a94aa116100bd578063273a94aa1461015c5780633e3dcce81461017c5780634cf4c36a1461019c57600080fd5b8063158274a5146100e45780631b29059b146101285780631fbf73ac14610149575b600080fd5b61010b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61013b610136366004612867565b6102df565b60405190815260200161011f565b61013b6101573660046128a8565b610402565b61016f61016a3660046129a1565b610574565b60405161011f9190612a9c565b61018f61018a366004612b44565b610819565b60405161011f9190612bf3565b6101af6101aa366004612c06565b610b0f565b60405161011f9190612cb9565b6101cf6101ca366004612ccc565b610bb6565b60405161011f9190612f4c565b6101ef6101ea366004612fae565b610dc3565b60405161011f919061307c565b61020f61020a36600461316e565b61126b565b60405161011f9190613213565b61022f61022a366004612ccc565b611920565b6040805182518152602080840151818301528383015182840152606093840151805185840152908101516080808401919091529281015160a08301529283015160c082015291015160e08201526101000161011f565b610298610293366004612fae565b611c47565b60405161011f9190613226565b61020f6102b3366004612ccc565b611deb565b61010b7f000000000000000000000000000000000000000000000000000000000000000081565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610340573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610364919061327b565b90506101f46a295be96e640669720000008069152d02c7e14af6800000600061038d83876132aa565b9050600061039b8284612289565b9050858110156103f65760006103c760466103c160046103bb8b8761229c565b90612289565b906122a8565b90506103d7876103bb8c846122b4565b985060006103e5878561229c565b9050808a11156103f3578099505b50505b50505050505050919050565b6040516370a0823160e01b815230600482015260009081906001600160a01b038416906370a0823190602401602060405180830381865afa15801561044b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046f919061327b565b6040517fcc956f3f000000000000000000000000000000000000000000000000000000008152600481018790529091506001600160a01b0385169063cc956f3f906024016020604051808303816000875af11580156104d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f691906132c1565b506040516370a0823160e01b815230600482015281906001600160a01b038516906370a0823190602401602060405180830381865afa15801561053d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610561919061327b565b61056b91906132aa565b95945050505050565b805160609060008167ffffffffffffffff811115610594576105946128ea565b6040519080825280602002602001820160405280156105e857816020015b60408051608081018252600080825260208201526060918101829052818101919091528152602001906001900390816105b25790505b50905060005b8281101561081157600085828151811061060a5761060a6132de565b6020026020010151905060008190506000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610675575060408051601f3d908101601f19168201909252610672918101906132f4565b60015b610681575060006106e7565b50816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e491906132f4565b90505b6040518060800160405280846001600160a01b031681526020018260ff168152602001836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610748573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107709190810190613317565b8152602001836001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156107b3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107db9190810190613317565b8152508585815181106107f0576107f06132de565b60200260200101819052505050508080610809906133a2565b9150506105ee565b509392505050565b6108446040518060800160405280600081526020016000815260200160608152602001600081525090565b6040516370a0823160e01b81526001600160a01b03838116600483015285916000918316906370a0823190602401602060405180830381865afa15801561088f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b3919061327b565b6040516246613160e11b81526001600160a01b038681166004830152919250600091841690628cc26290602401602060405180830381865afa1580156108fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610921919061327b565b90506000836001600160a01b031663d55a23f46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610963573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610987919061327b565b905060008167ffffffffffffffff8111156109a4576109a46128ea565b6040519080825280602002602001820160405280156109cd578160200160208202803683370190505b50905060005b82811015610ae357604051632061aa2360e11b8152600481018290526000906001600160a01b038816906340c3544690602401602060405180830381865afa158015610a23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4791906133bd565b6040516246613160e11b81526001600160a01b038b8116600483015291925090821690628cc26290602401602060405180830381865afa158015610a8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab3919061327b565b838381518110610ac557610ac56132de565b60209081029190910101525080610adb816133a2565b9150506109d3565b506040805160808101825289815260208101949094528301525060608101919091529150509392505050565b6060835167ffffffffffffffff811115610b2b57610b2b6128ea565b604051908082528060200260200182016040528015610b54578160200160208202803683370190505b50905060005b845181101561081157610b87858281518110610b7857610b786132de565b60200260200101518585610402565b828281518110610b9957610b996132de565b602090810291909101015280610bae816133a2565b915050610b5a565b606060008290506000816001600160a01b031663081e3eda6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c21919061327b565b90506000610c308260016133da565b67ffffffffffffffff811115610c4857610c486128ea565b604051908082528060200260200182016040528015610c8157816020015b610c6e6126d3565b815260200190600190039081610c665790505b50905060005b82811015610d3857604051631526fe2760e01b8152600481018290526000906001600160a01b03861690631526fe279060240160c060405180830381865afa158015610cd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cfb91906133f2565b9050610d07818361126b565b838381518110610d1957610d196132de565b6020026020010181905250508080610d30906133a2565b915050610c87565b50610d9e836001600160a01b031663376d771a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d7a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b391906133bd565b818381518110610db057610db06132de565b6020908102919091010152949350505050565b610e4460405180610160016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160006001600160801b0316815260200160006001600160801b0316815260200160006001600160a01b031681526020016000815260200160608152602001606081525090565b60008390506000816001600160a01b03166382480df96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ead91906133bd565b6040517f27e235e30000000000000000000000000000000000000000000000000000000081526001600160a01b0386811660048301529192506000918416906327e235e3906024016040805180830381865afa158015610f11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3591906134cf565b6040517f768e5b270000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152888116602483015263ffffffff92909216935060009250829186169063768e5b27906044016040805180830381865afa158015610fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd09190613519565b6040517f0483a7f60000000000000000000000000000000000000000000000000000000081526001600160a01b038a81166004830152929450909250600091829182918291908a1690630483a7f690602401600060405180830381865afa15801561103f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110679190810190613543565b93509350935093506040518061016001604052808c6001600160a01b03168152602001858152602001848152602001838152602001886dffffffffffffffffffffffffffff168152602001876001600160801b03168152602001866001600160801b031681526020018a6001600160a01b031663587cde1e8e6040518263ffffffff1660e01b815260040161110b91906001600160a01b0391909116815260200190565b602060405180830381865afa158015611128573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114c91906133bd565b6001600160a01b0390811682526040516370a0823160e01b81528e82166004820152602090920191908c16906370a0823190602401602060405180830381865afa15801561119e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c2919061327b565b815260208101839052604080517fdc01f60d0000000000000000000000000000000000000000000000000000000081526001600160a01b038f811660048301529190920191908c169063dc01f60d90602401600060405180830381865afa158015611231573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112599190810190613623565b90529c9b505050505050505050505050565b6112736126d3565b6060830151835160008060026040519080825280602002602001820160405280156112a8578160200160208202803683370190505b506040805160028082526060820183529293506000929091602083019080368337019050509050836001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611329575060408051601f3d908101601f19168201909252611326918101906133bd565b60015b6113365760009250611577565b809350836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139b91906133bd565b836000815181106113ae576113ae6132de565b60200260200101906001600160a01b031690816001600160a01b031681525050836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561140c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143091906133bd565b83600181518110611443576114436132de565b60200260200101906001600160a01b031690816001600160a01b031681525050846001600160a01b03166359c4f9056040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c591906136d7565b826000815181106114d8576114d86132de565b602002602001019060020b908160020b81525050846001600160a01b03166355b812a86040518163ffffffff1660e01b8152600401602060405180830381865afa15801561152a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154e91906136d7565b82600181518110611561576115616132de565b602002602001019060020b908160020b81525050505b600061158689606001516122c0565b905060006040518060a00160405280886001600160a01b031663ebe2b12b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f7919061327b565b8152602001886001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561163a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165e919061327b565b8152602001886001600160a01b0316637b0a47ee6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c5919061327b565b8152602001886001600160a01b031663df136d656040518163ffffffff1660e01b8152600401602060405180830381865afa158015611708573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172c919061327b565b8152602001886001600160a01b03166363d38c3b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561176f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611793919061327b565b8152509050604051806101c001604052808a81526020018b600001516001600160a01b031681526020018b602001516001600160a01b031681526020018b604001516001600160a01b031681526020018b606001516001600160a01b031681526020018b608001516001600160a01b031681526020018b60a0015115158152602001886001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa158015611853573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061187791906133bd565b6001600160a01b03168152602001866001600160a01b03168152602001858152602001848152602001886001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611902919061327b565b81526020018281526020018381525097505050505050505092915050565b6119286127b3565b60008290506000816001600160a01b03166382480df96040518163ffffffff1660e01b8152600401602060405180830381865afa15801561196d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061199191906133bd565b6040517f48e5d9f80000000000000000000000000000000000000000000000000000000081526001600160a01b038083166004830152919250600091829182918291908716906348e5d9f890602401608060405180830381865afa1580156119fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a219190613716565b935093509350935060006040518060a001604052808663ffffffff1681526020018563ffffffff168152602001846bffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff168152602001886001600160a01b031663b53a6a71896040518263ffffffff1660e01b8152600401611ab191906001600160a01b0391909116815260200190565b602060405180830381865afa158015611ace573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af2919061327b565b81525090506040518060800160405280886001600160a01b031663829965cc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b64919061327b565b8152602001886001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ba7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bcb919061327b565b8152602001886001600160a01b031663ca5c7b916040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c32919061327b565b81526020019190915298975050505050505050565b60606000836001600160a01b031663081e3eda6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cad919061327b565b905060008167ffffffffffffffff811115611cca57611cca6128ea565b604051908082528060200260200182016040528015611d2657816020015b611d136040518060800160405280600081526020016000815260200160608152602001600081525090565b815260200190600190039081611ce85790505b50905060005b82811015611de257604051631526fe2760e01b8152600481018290526000906001600160a01b03881690631526fe279060240160c060405180830381865afa158015611d7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da091906133f2565b9050611db181606001518388610819565b838381518110611dc357611dc36132de565b6020026020010181905250508080611dda906133a2565b915050611d2c565b50949350505050565b611df36126d3565b60008290506000816001600160a01b03166372f702f36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5c91906133bd565b60408051600180825281830190925291925060009190602080830190803683370190505090508181600081518110611e9657611e966132de565b6001600160a01b039290921660209283029190910190910152604080516001808252818301909252600091816020016020820280368337019050509050600081600081518110611ee857611ee86132de565b602002602001019060020b908160020b8152505060006040518060a00160405280866001600160a01b031663ebe2b12b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f6b919061327b565b8152602001866001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd2919061327b565b8152602001866001600160a01b0316637b0a47ee6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612015573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612039919061327b565b8152602001866001600160a01b031663df136d656040518163ffffffff1660e01b8152600401602060405180830381865afa15801561207c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a0919061327b565b8152602001866001600160a01b03166363d38c3b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612107919061327b565b905290506000612116886122c0565b9050604051806101c0016040528060008152602001866001600160a01b03168152602001866001600160a01b0316815260200160006001600160a01b03168152602001896001600160a01b0316815260200160006001600160a01b03168152602001600015158152602001876001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e391906133bd565b6001600160a01b0316815260200160006001600160a01b03168152602001858152602001848152602001876001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561224b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226f919061327b565b815260208101939093526040909201529695505050505050565b6000612295828461376a565b9392505050565b600061229582846132aa565b600061229582846133da565b6000612295828461378c565b606060008290506000816001600160a01b031663d55a23f46040518163ffffffff1660e01b8152600401602060405180830381865afa158015612307573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061232b919061327b565b905060008167ffffffffffffffff811115612348576123486128ea565b60405190808252806020026020018201604052801561238157816020015b61236e61280a565b8152602001906001900390816123665790505b50905060005b82811015611de257604051632061aa2360e11b8152600481018290526000906001600160a01b038616906340c3544690602401602060405180830381865afa1580156123d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123fb91906133bd565b9050600081905060006040518060a00160405280836001600160a01b031663ebe2b12b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561244d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612471919061327b565b8152602001836001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124d8919061327b565b8152602001836001600160a01b0316637b0a47ee6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561251b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061253f919061327b565b8152602001836001600160a01b031663df136d656040518163ffffffff1660e01b8152600401602060405180830381865afa158015612582573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125a6919061327b565b8152602001836001600160a01b03166363d38c3b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260d919061327b565b81525090506040518060600160405280846001600160a01b03168152602001836001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa15801561266a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268e91906133bd565b6001600160a01b03168152602001828152508585815181106126b2576126b26132de565b602002602001018190525050505080806126cb906133a2565b915050612387565b604051806101c001604052806000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160001515815260200160006001600160a01b0316815260200160006001600160a01b031681526020016060815260200160608152602001600081526020016127a66040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b8152602001606081525090565b60405180608001604052806000815260200160008152602001600081526020016128056040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b905290565b604051806060016040528060006001600160a01b0316815260200160006001600160a01b031681526020016128056040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60006020828403121561287957600080fd5b5035919050565b6001600160a01b038116811461289557600080fd5b50565b80356128a381612880565b919050565b6000806000606084860312156128bd57600080fd5b8335925060208401356128cf81612880565b915060408401356128df81612880565b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715612923576129236128ea565b60405290565b6040805190810167ffffffffffffffff81118282101715612923576129236128ea565b604051601f8201601f1916810167ffffffffffffffff81118282101715612975576129756128ea565b604052919050565b600067ffffffffffffffff821115612997576129976128ea565b5060051b60200190565b600060208083850312156129b457600080fd5b823567ffffffffffffffff8111156129cb57600080fd5b8301601f810185136129dc57600080fd5b80356129ef6129ea8261297d565b61294c565b81815260059190911b82018301908381019087831115612a0e57600080fd5b928401925b82841015612a35578335612a2681612880565b82529284019290840190612a13565b979650505050505050565b60005b83811015612a5b578181015183820152602001612a43565b83811115612a6a576000848401525b50505050565b60008151808452612a88816020860160208601612a40565b601f01601f19169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015612b3657603f19898403018552815160806001600160a01b03825116855260ff898301511689860152878201518189870152612b0582870182612a70565b91505060608083015192508582038187015250612b228183612a70565b968901969450505090860190600101612ac3565b509098975050505050505050565b600080600060608486031215612b5957600080fd5b8335612b6481612880565b92506020840135915060408401356128df81612880565b600081518084526020808501945080840160005b83811015612bab57815187529582019590820190600101612b8f565b509495945050505050565b80518252602081015160208301526000604082015160806040850152612bdf6080850182612b7b565b606093840151949093019390935250919050565b6020815260006122956020830184612bb6565b600080600060608486031215612c1b57600080fd5b833567ffffffffffffffff811115612c3257600080fd5b8401601f81018613612c4357600080fd5b80356020612c536129ea8361297d565b82815260059290921b83018101918181019089841115612c7257600080fd5b938201935b83851015612c9057843582529382019390820190612c77565b9650612c9f9050878201612898565b9450505050612cb060408501612898565b90509250925092565b6020815260006122956020830184612b7b565b600060208284031215612cde57600080fd5b813561229581612880565b600081518084526020808501945080840160005b83811015612bab5781516001600160a01b031687529582019590820190600101612cfd565b600081518084526020808501945080840160005b83811015612bab57815160020b87529582019590820190600101612d36565b600081518084526020808501945080840160005b83811015612bab57815180516001600160a01b03908116895284820151168489015260409081015190612dc9818a018380518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b505060e0969096019590820190600101612d69565b6000610240825184526020830151612e0160208601826001600160a01b03169052565b506040830151612e1c60408601826001600160a01b03169052565b506060830151612e3760608601826001600160a01b03169052565b506080830151612e5260808601826001600160a01b03169052565b5060a0830151612e6d60a08601826001600160a01b03169052565b5060c0830151612e8160c086018215159052565b5060e0830151612e9c60e08601826001600160a01b03169052565b50610100838101516001600160a01b03169085015261012080840151818601839052612eca83870182612ce9565b925050506101408084015185830382870152612ee68382612d22565b6101608681015190880152610180808701518051828a015260208101516101a08a015260408101516101c08a015260608101516101e08a015260808101516102008a01529194509250905050506101a083015184820361022086015261056b8282612d55565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015612fa157603f19888603018452612f8f858351612dde565b94509285019290850190600101612f73565b5092979650505050505050565b60008060408385031215612fc157600080fd5b8235612fcc81612880565b91506020830135612fdc81612880565b809150509250929050565b600081518084526020808501945080840160005b83811015612bab57815180516dffffffffffffffffffffffffffff16885283015163ffffffff168388015260409096019590820190600101612ffb565b600081518084526020808501945080840160005b83811015612bab57815180516001600160a01b03168852830151838801526040909601959082019060010161304c565b602081526130966020820183516001600160a01b03169052565b602082015160408201526040820151606082015260608201516080820152608082015160a0820152600060a08301516130da60c08401826001600160801b03169052565b5060c08301516001600160801b03811660e08401525060e083015161010061310c818501836001600160a01b03169052565b840151610120848101919091528401516101606101408086018290529192509061313a610180860184612fe7565b90860151858203601f1901838701529092506131568382613038565b9695505050505050565b801515811461289557600080fd5b60008082840360e081121561318257600080fd5b60c081121561319057600080fd5b50613199612900565b83356131a481612880565b815260208401356131b481612880565b602082015260408401356131c781612880565b604082015260608401356131da81612880565b606082015260808401356131ed81612880565b608082015260a084013561320081613160565b60a08201529460c0939093013593505050565b6020815260006122956020830184612dde565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015612fa157603f19888603018452613269858351612bb6565b9450928501929085019060010161324d565b60006020828403121561328d57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000828210156132bc576132bc613294565b500390565b6000602082840312156132d357600080fd5b815161229581613160565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561330657600080fd5b815160ff8116811461229557600080fd5b60006020828403121561332957600080fd5b815167ffffffffffffffff8082111561334157600080fd5b818401915084601f83011261335557600080fd5b815181811115613367576133676128ea565b61337a601f8201601f191660200161294c565b915080825285602082850101111561339157600080fd5b611de2816020840160208601612a40565b60006000198214156133b6576133b6613294565b5060010190565b6000602082840312156133cf57600080fd5b815161229581612880565b600082198211156133ed576133ed613294565b500190565b600060c0828403121561340457600080fd5b60405160c0810181811067ffffffffffffffff82111715613427576134276128ea565b604052825161343581612880565b8152602083015161344581612880565b6020820152604083015161345881612880565b6040820152606083015161346b81612880565b6060820152608083015161347e81612880565b608082015260a083015161349181613160565b60a08201529392505050565b80516dffffffffffffffffffffffffffff811681146128a357600080fd5b805163ffffffff811681146128a357600080fd5b600080604083850312156134e257600080fd5b6134eb8361349d565b91506134f9602084016134bb565b90509250929050565b80516001600160801b03811681146128a357600080fd5b6000806040838503121561352c57600080fd5b61353583613502565b91506134f960208401613502565b6000806000806080858703121561355957600080fd5b8451935060208086015193506040808701519350606087015167ffffffffffffffff81111561358757600080fd5b8701601f8101891361359857600080fd5b80516135a66129ea8261297d565b81815260069190911b8201840190848101908b8311156135c557600080fd5b928501925b828410156136135784848d0312156135e25760008081fd5b6135ea612929565b6135f38561349d565b81526136008786016134bb565b81880152825292840192908501906135ca565b989b979a50959850505050505050565b6000602080838503121561363657600080fd5b825167ffffffffffffffff81111561364d57600080fd5b8301601f8101851361365e57600080fd5b805161366c6129ea8261297d565b81815260069190911b8201830190838101908783111561368b57600080fd5b928401925b82841015612a3557604084890312156136a95760008081fd5b6136b1612929565b84516136bc81612880565b81528486015186820152825260409093019290840190613690565b6000602082840312156136e957600080fd5b81518060020b811461229557600080fd5b80516bffffffffffffffffffffffff811681146128a357600080fd5b6000806000806080858703121561372c57600080fd5b613735856134bb565b9350613743602086016134bb565b9250613751604086016136fa565b915061375f606086016136fa565b905092959194509250565b60008261378757634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156137a6576137a6613294565b50029056fea2646970667358221220904db1418d2f8e4482dd005fec06ed709419b177980ec43da96d4e4b14e1705664736f6c634300080b0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100df5760003560e01c80635c39f4671161008c578063919884bf11610066578063919884bf1461021c5780639b9e095514610285578063eda24290146102a5578063faba8c3b146102b857600080fd5b80635c39f467146101bc578063654b72f1146101dc5780637f5f53d1146101fc57600080fd5b8063273a94aa116100bd578063273a94aa1461015c5780633e3dcce81461017c5780634cf4c36a1461019c57600080fd5b8063158274a5146100e45780631b29059b146101285780631fbf73ac14610149575b600080fd5b61010b7f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c881565b6040516001600160a01b0390911681526020015b60405180910390f35b61013b610136366004612867565b6102df565b60405190815260200161011f565b61013b6101573660046128a8565b610402565b61016f61016a3660046129a1565b610574565b60405161011f9190612a9c565b61018f61018a366004612b44565b610819565b60405161011f9190612bf3565b6101af6101aa366004612c06565b610b0f565b60405161011f9190612cb9565b6101cf6101ca366004612ccc565b610bb6565b60405161011f9190612f4c565b6101ef6101ea366004612fae565b610dc3565b60405161011f919061307c565b61020f61020a36600461316e565b61126b565b60405161011f9190613213565b61022f61022a366004612ccc565b611920565b6040805182518152602080840151818301528383015182840152606093840151805185840152908101516080808401919091529281015160a08301529283015160c082015291015160e08201526101000161011f565b610298610293366004612fae565b611c47565b60405161011f9190613226565b61020f6102b3366004612ccc565b611deb565b61010b7f000000000000000000000000d82fd4d6d62f89a1e50b1db69ad19932314aa40881565b6000807f000000000000000000000000d82fd4d6d62f89a1e50b1db69ad19932314aa4086001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610340573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610364919061327b565b90506101f46a295be96e640669720000008069152d02c7e14af6800000600061038d83876132aa565b9050600061039b8284612289565b9050858110156103f65760006103c760466103c160046103bb8b8761229c565b90612289565b906122a8565b90506103d7876103bb8c846122b4565b985060006103e5878561229c565b9050808a11156103f3578099505b50505b50505050505050919050565b6040516370a0823160e01b815230600482015260009081906001600160a01b038416906370a0823190602401602060405180830381865afa15801561044b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046f919061327b565b6040517fcc956f3f000000000000000000000000000000000000000000000000000000008152600481018790529091506001600160a01b0385169063cc956f3f906024016020604051808303816000875af11580156104d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f691906132c1565b506040516370a0823160e01b815230600482015281906001600160a01b038516906370a0823190602401602060405180830381865afa15801561053d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610561919061327b565b61056b91906132aa565b95945050505050565b805160609060008167ffffffffffffffff811115610594576105946128ea565b6040519080825280602002602001820160405280156105e857816020015b60408051608081018252600080825260208201526060918101829052818101919091528152602001906001900390816105b25790505b50905060005b8281101561081157600085828151811061060a5761060a6132de565b6020026020010151905060008190506000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610675575060408051601f3d908101601f19168201909252610672918101906132f4565b60015b610681575060006106e7565b50816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e491906132f4565b90505b6040518060800160405280846001600160a01b031681526020018260ff168152602001836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610748573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107709190810190613317565b8152602001836001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156107b3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107db9190810190613317565b8152508585815181106107f0576107f06132de565b60200260200101819052505050508080610809906133a2565b9150506105ee565b509392505050565b6108446040518060800160405280600081526020016000815260200160608152602001600081525090565b6040516370a0823160e01b81526001600160a01b03838116600483015285916000918316906370a0823190602401602060405180830381865afa15801561088f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b3919061327b565b6040516246613160e11b81526001600160a01b038681166004830152919250600091841690628cc26290602401602060405180830381865afa1580156108fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610921919061327b565b90506000836001600160a01b031663d55a23f46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610963573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610987919061327b565b905060008167ffffffffffffffff8111156109a4576109a46128ea565b6040519080825280602002602001820160405280156109cd578160200160208202803683370190505b50905060005b82811015610ae357604051632061aa2360e11b8152600481018290526000906001600160a01b038816906340c3544690602401602060405180830381865afa158015610a23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4791906133bd565b6040516246613160e11b81526001600160a01b038b8116600483015291925090821690628cc26290602401602060405180830381865afa158015610a8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab3919061327b565b838381518110610ac557610ac56132de565b60209081029190910101525080610adb816133a2565b9150506109d3565b506040805160808101825289815260208101949094528301525060608101919091529150509392505050565b6060835167ffffffffffffffff811115610b2b57610b2b6128ea565b604051908082528060200260200182016040528015610b54578160200160208202803683370190505b50905060005b845181101561081157610b87858281518110610b7857610b786132de565b60200260200101518585610402565b828281518110610b9957610b996132de565b602090810291909101015280610bae816133a2565b915050610b5a565b606060008290506000816001600160a01b031663081e3eda6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c21919061327b565b90506000610c308260016133da565b67ffffffffffffffff811115610c4857610c486128ea565b604051908082528060200260200182016040528015610c8157816020015b610c6e6126d3565b815260200190600190039081610c665790505b50905060005b82811015610d3857604051631526fe2760e01b8152600481018290526000906001600160a01b03861690631526fe279060240160c060405180830381865afa158015610cd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cfb91906133f2565b9050610d07818361126b565b838381518110610d1957610d196132de565b6020026020010181905250508080610d30906133a2565b915050610c87565b50610d9e836001600160a01b031663376d771a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d7a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b391906133bd565b818381518110610db057610db06132de565b6020908102919091010152949350505050565b610e4460405180610160016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160006001600160801b0316815260200160006001600160801b0316815260200160006001600160a01b031681526020016000815260200160608152602001606081525090565b60008390506000816001600160a01b03166382480df96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ead91906133bd565b6040517f27e235e30000000000000000000000000000000000000000000000000000000081526001600160a01b0386811660048301529192506000918416906327e235e3906024016040805180830381865afa158015610f11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3591906134cf565b6040517f768e5b270000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152888116602483015263ffffffff92909216935060009250829186169063768e5b27906044016040805180830381865afa158015610fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd09190613519565b6040517f0483a7f60000000000000000000000000000000000000000000000000000000081526001600160a01b038a81166004830152929450909250600091829182918291908a1690630483a7f690602401600060405180830381865afa15801561103f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110679190810190613543565b93509350935093506040518061016001604052808c6001600160a01b03168152602001858152602001848152602001838152602001886dffffffffffffffffffffffffffff168152602001876001600160801b03168152602001866001600160801b031681526020018a6001600160a01b031663587cde1e8e6040518263ffffffff1660e01b815260040161110b91906001600160a01b0391909116815260200190565b602060405180830381865afa158015611128573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114c91906133bd565b6001600160a01b0390811682526040516370a0823160e01b81528e82166004820152602090920191908c16906370a0823190602401602060405180830381865afa15801561119e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c2919061327b565b815260208101839052604080517fdc01f60d0000000000000000000000000000000000000000000000000000000081526001600160a01b038f811660048301529190920191908c169063dc01f60d90602401600060405180830381865afa158015611231573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112599190810190613623565b90529c9b505050505050505050505050565b6112736126d3565b6060830151835160008060026040519080825280602002602001820160405280156112a8578160200160208202803683370190505b506040805160028082526060820183529293506000929091602083019080368337019050509050836001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611329575060408051601f3d908101601f19168201909252611326918101906133bd565b60015b6113365760009250611577565b809350836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139b91906133bd565b836000815181106113ae576113ae6132de565b60200260200101906001600160a01b031690816001600160a01b031681525050836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561140c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143091906133bd565b83600181518110611443576114436132de565b60200260200101906001600160a01b031690816001600160a01b031681525050846001600160a01b03166359c4f9056040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c591906136d7565b826000815181106114d8576114d86132de565b602002602001019060020b908160020b81525050846001600160a01b03166355b812a86040518163ffffffff1660e01b8152600401602060405180830381865afa15801561152a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154e91906136d7565b82600181518110611561576115616132de565b602002602001019060020b908160020b81525050505b600061158689606001516122c0565b905060006040518060a00160405280886001600160a01b031663ebe2b12b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f7919061327b565b8152602001886001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561163a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165e919061327b565b8152602001886001600160a01b0316637b0a47ee6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c5919061327b565b8152602001886001600160a01b031663df136d656040518163ffffffff1660e01b8152600401602060405180830381865afa158015611708573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172c919061327b565b8152602001886001600160a01b03166363d38c3b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561176f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611793919061327b565b8152509050604051806101c001604052808a81526020018b600001516001600160a01b031681526020018b602001516001600160a01b031681526020018b604001516001600160a01b031681526020018b606001516001600160a01b031681526020018b608001516001600160a01b031681526020018b60a0015115158152602001886001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa158015611853573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061187791906133bd565b6001600160a01b03168152602001866001600160a01b03168152602001858152602001848152602001886001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611902919061327b565b81526020018281526020018381525097505050505050505092915050565b6119286127b3565b60008290506000816001600160a01b03166382480df96040518163ffffffff1660e01b8152600401602060405180830381865afa15801561196d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061199191906133bd565b6040517f48e5d9f80000000000000000000000000000000000000000000000000000000081526001600160a01b038083166004830152919250600091829182918291908716906348e5d9f890602401608060405180830381865afa1580156119fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a219190613716565b935093509350935060006040518060a001604052808663ffffffff1681526020018563ffffffff168152602001846bffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff168152602001886001600160a01b031663b53a6a71896040518263ffffffff1660e01b8152600401611ab191906001600160a01b0391909116815260200190565b602060405180830381865afa158015611ace573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af2919061327b565b81525090506040518060800160405280886001600160a01b031663829965cc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b64919061327b565b8152602001886001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ba7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bcb919061327b565b8152602001886001600160a01b031663ca5c7b916040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c32919061327b565b81526020019190915298975050505050505050565b60606000836001600160a01b031663081e3eda6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cad919061327b565b905060008167ffffffffffffffff811115611cca57611cca6128ea565b604051908082528060200260200182016040528015611d2657816020015b611d136040518060800160405280600081526020016000815260200160608152602001600081525090565b815260200190600190039081611ce85790505b50905060005b82811015611de257604051631526fe2760e01b8152600481018290526000906001600160a01b03881690631526fe279060240160c060405180830381865afa158015611d7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da091906133f2565b9050611db181606001518388610819565b838381518110611dc357611dc36132de565b6020026020010181905250508080611dda906133a2565b915050611d2c565b50949350505050565b611df36126d3565b60008290506000816001600160a01b03166372f702f36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5c91906133bd565b60408051600180825281830190925291925060009190602080830190803683370190505090508181600081518110611e9657611e966132de565b6001600160a01b039290921660209283029190910190910152604080516001808252818301909252600091816020016020820280368337019050509050600081600081518110611ee857611ee86132de565b602002602001019060020b908160020b8152505060006040518060a00160405280866001600160a01b031663ebe2b12b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f6b919061327b565b8152602001866001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd2919061327b565b8152602001866001600160a01b0316637b0a47ee6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612015573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612039919061327b565b8152602001866001600160a01b031663df136d656040518163ffffffff1660e01b8152600401602060405180830381865afa15801561207c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a0919061327b565b8152602001866001600160a01b03166363d38c3b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612107919061327b565b905290506000612116886122c0565b9050604051806101c0016040528060008152602001866001600160a01b03168152602001866001600160a01b0316815260200160006001600160a01b03168152602001896001600160a01b0316815260200160006001600160a01b03168152602001600015158152602001876001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e391906133bd565b6001600160a01b0316815260200160006001600160a01b03168152602001858152602001848152602001876001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561224b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226f919061327b565b815260208101939093526040909201529695505050505050565b6000612295828461376a565b9392505050565b600061229582846132aa565b600061229582846133da565b6000612295828461378c565b606060008290506000816001600160a01b031663d55a23f46040518163ffffffff1660e01b8152600401602060405180830381865afa158015612307573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061232b919061327b565b905060008167ffffffffffffffff811115612348576123486128ea565b60405190808252806020026020018201604052801561238157816020015b61236e61280a565b8152602001906001900390816123665790505b50905060005b82811015611de257604051632061aa2360e11b8152600481018290526000906001600160a01b038616906340c3544690602401602060405180830381865afa1580156123d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123fb91906133bd565b9050600081905060006040518060a00160405280836001600160a01b031663ebe2b12b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561244d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612471919061327b565b8152602001836001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124d8919061327b565b8152602001836001600160a01b0316637b0a47ee6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561251b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061253f919061327b565b8152602001836001600160a01b031663df136d656040518163ffffffff1660e01b8152600401602060405180830381865afa158015612582573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125a6919061327b565b8152602001836001600160a01b03166363d38c3b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260d919061327b565b81525090506040518060600160405280846001600160a01b03168152602001836001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa15801561266a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268e91906133bd565b6001600160a01b03168152602001828152508585815181106126b2576126b26132de565b602002602001018190525050505080806126cb906133a2565b915050612387565b604051806101c001604052806000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160001515815260200160006001600160a01b0316815260200160006001600160a01b031681526020016060815260200160608152602001600081526020016127a66040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b8152602001606081525090565b60405180608001604052806000815260200160008152602001600081526020016128056040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b905290565b604051806060016040528060006001600160a01b0316815260200160006001600160a01b031681526020016128056040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60006020828403121561287957600080fd5b5035919050565b6001600160a01b038116811461289557600080fd5b50565b80356128a381612880565b919050565b6000806000606084860312156128bd57600080fd5b8335925060208401356128cf81612880565b915060408401356128df81612880565b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715612923576129236128ea565b60405290565b6040805190810167ffffffffffffffff81118282101715612923576129236128ea565b604051601f8201601f1916810167ffffffffffffffff81118282101715612975576129756128ea565b604052919050565b600067ffffffffffffffff821115612997576129976128ea565b5060051b60200190565b600060208083850312156129b457600080fd5b823567ffffffffffffffff8111156129cb57600080fd5b8301601f810185136129dc57600080fd5b80356129ef6129ea8261297d565b61294c565b81815260059190911b82018301908381019087831115612a0e57600080fd5b928401925b82841015612a35578335612a2681612880565b82529284019290840190612a13565b979650505050505050565b60005b83811015612a5b578181015183820152602001612a43565b83811115612a6a576000848401525b50505050565b60008151808452612a88816020860160208601612a40565b601f01601f19169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015612b3657603f19898403018552815160806001600160a01b03825116855260ff898301511689860152878201518189870152612b0582870182612a70565b91505060608083015192508582038187015250612b228183612a70565b968901969450505090860190600101612ac3565b509098975050505050505050565b600080600060608486031215612b5957600080fd5b8335612b6481612880565b92506020840135915060408401356128df81612880565b600081518084526020808501945080840160005b83811015612bab57815187529582019590820190600101612b8f565b509495945050505050565b80518252602081015160208301526000604082015160806040850152612bdf6080850182612b7b565b606093840151949093019390935250919050565b6020815260006122956020830184612bb6565b600080600060608486031215612c1b57600080fd5b833567ffffffffffffffff811115612c3257600080fd5b8401601f81018613612c4357600080fd5b80356020612c536129ea8361297d565b82815260059290921b83018101918181019089841115612c7257600080fd5b938201935b83851015612c9057843582529382019390820190612c77565b9650612c9f9050878201612898565b9450505050612cb060408501612898565b90509250925092565b6020815260006122956020830184612b7b565b600060208284031215612cde57600080fd5b813561229581612880565b600081518084526020808501945080840160005b83811015612bab5781516001600160a01b031687529582019590820190600101612cfd565b600081518084526020808501945080840160005b83811015612bab57815160020b87529582019590820190600101612d36565b600081518084526020808501945080840160005b83811015612bab57815180516001600160a01b03908116895284820151168489015260409081015190612dc9818a018380518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b505060e0969096019590820190600101612d69565b6000610240825184526020830151612e0160208601826001600160a01b03169052565b506040830151612e1c60408601826001600160a01b03169052565b506060830151612e3760608601826001600160a01b03169052565b506080830151612e5260808601826001600160a01b03169052565b5060a0830151612e6d60a08601826001600160a01b03169052565b5060c0830151612e8160c086018215159052565b5060e0830151612e9c60e08601826001600160a01b03169052565b50610100838101516001600160a01b03169085015261012080840151818601839052612eca83870182612ce9565b925050506101408084015185830382870152612ee68382612d22565b6101608681015190880152610180808701518051828a015260208101516101a08a015260408101516101c08a015260608101516101e08a015260808101516102008a01529194509250905050506101a083015184820361022086015261056b8282612d55565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015612fa157603f19888603018452612f8f858351612dde565b94509285019290850190600101612f73565b5092979650505050505050565b60008060408385031215612fc157600080fd5b8235612fcc81612880565b91506020830135612fdc81612880565b809150509250929050565b600081518084526020808501945080840160005b83811015612bab57815180516dffffffffffffffffffffffffffff16885283015163ffffffff168388015260409096019590820190600101612ffb565b600081518084526020808501945080840160005b83811015612bab57815180516001600160a01b03168852830151838801526040909601959082019060010161304c565b602081526130966020820183516001600160a01b03169052565b602082015160408201526040820151606082015260608201516080820152608082015160a0820152600060a08301516130da60c08401826001600160801b03169052565b5060c08301516001600160801b03811660e08401525060e083015161010061310c818501836001600160a01b03169052565b840151610120848101919091528401516101606101408086018290529192509061313a610180860184612fe7565b90860151858203601f1901838701529092506131568382613038565b9695505050505050565b801515811461289557600080fd5b60008082840360e081121561318257600080fd5b60c081121561319057600080fd5b50613199612900565b83356131a481612880565b815260208401356131b481612880565b602082015260408401356131c781612880565b604082015260608401356131da81612880565b606082015260808401356131ed81612880565b608082015260a084013561320081613160565b60a08201529460c0939093013593505050565b6020815260006122956020830184612dde565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015612fa157603f19888603018452613269858351612bb6565b9450928501929085019060010161324d565b60006020828403121561328d57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000828210156132bc576132bc613294565b500390565b6000602082840312156132d357600080fd5b815161229581613160565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561330657600080fd5b815160ff8116811461229557600080fd5b60006020828403121561332957600080fd5b815167ffffffffffffffff8082111561334157600080fd5b818401915084601f83011261335557600080fd5b815181811115613367576133676128ea565b61337a601f8201601f191660200161294c565b915080825285602082850101111561339157600080fd5b611de2816020840160208601612a40565b60006000198214156133b6576133b6613294565b5060010190565b6000602082840312156133cf57600080fd5b815161229581612880565b600082198211156133ed576133ed613294565b500190565b600060c0828403121561340457600080fd5b60405160c0810181811067ffffffffffffffff82111715613427576134276128ea565b604052825161343581612880565b8152602083015161344581612880565b6020820152604083015161345881612880565b6040820152606083015161346b81612880565b6060820152608083015161347e81612880565b608082015260a083015161349181613160565b60a08201529392505050565b80516dffffffffffffffffffffffffffff811681146128a357600080fd5b805163ffffffff811681146128a357600080fd5b600080604083850312156134e257600080fd5b6134eb8361349d565b91506134f9602084016134bb565b90509250929050565b80516001600160801b03811681146128a357600080fd5b6000806040838503121561352c57600080fd5b61353583613502565b91506134f960208401613502565b6000806000806080858703121561355957600080fd5b8451935060208086015193506040808701519350606087015167ffffffffffffffff81111561358757600080fd5b8701601f8101891361359857600080fd5b80516135a66129ea8261297d565b81815260069190911b8201840190848101908b8311156135c557600080fd5b928501925b828410156136135784848d0312156135e25760008081fd5b6135ea612929565b6135f38561349d565b81526136008786016134bb565b81880152825292840192908501906135ca565b989b979a50959850505050505050565b6000602080838503121561363657600080fd5b825167ffffffffffffffff81111561364d57600080fd5b8301601f8101851361365e57600080fd5b805161366c6129ea8261297d565b81815260069190911b8201830190838101908783111561368b57600080fd5b928401925b82841015612a3557604084890312156136a95760008081fd5b6136b1612929565b84516136bc81612880565b81528486015186820152825260409093019290840190613690565b6000602082840312156136e957600080fd5b81518060020b811461229557600080fd5b80516bffffffffffffffffffffffff811681146128a357600080fd5b6000806000806080858703121561372c57600080fd5b613735856134bb565b9350613743602086016134bb565b9250613751604086016136fa565b915061375f606086016136fa565b905092959194509250565b60008261378757634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156137a6576137a6613294565b50029056fea2646970667358221220904db1418d2f8e4482dd005fec06ed709419b177980ec43da96d4e4b14e1705664736f6c634300080b0033
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.