ETH Price: $2,282.70 (+2.25%)

Contract

0x4181E561b42fDaD14c68b0794c215DeB9Bc80c8F
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Deposit183511252023-10-14 20:52:35329 days ago1697316755IN
0x4181E561...B9Bc80c8F
0 ETH0.002937726.00839599
Deposit183504382023-10-14 18:34:35329 days ago1697308475IN
0x4181E561...B9Bc80c8F
0 ETH0.002470535.26725281
Deposit183503582023-10-14 18:18:35329 days ago1697307515IN
0x4181E561...B9Bc80c8F
0 ETH0.002829216.03196664
Deposit183502032023-10-14 17:46:59329 days ago1697305619IN
0x4181E561...B9Bc80c8F
0 ETH0.001720495.02028658
Deposit183500352023-10-14 17:13:11329 days ago1697303591IN
0x4181E561...B9Bc80c8F
0 ETH0.001965325.73764125
Deposit183492992023-10-14 14:45:35329 days ago1697294735IN
0x4181E561...B9Bc80c8F
0 ETH0.002286995.1545016
Deposit183490972023-10-14 14:04:35329 days ago1697292275IN
0x4181E561...B9Bc80c8F
0 ETH0.002941676.37066218
Deposit183490212023-10-14 13:49:11329 days ago1697291351IN
0x4181E561...B9Bc80c8F
0 ETH0.002161855.65476659
Deposit183489772023-10-14 13:40:23329 days ago1697290823IN
0x4181E561...B9Bc80c8F
0 ETH0.002615296.26966569
Deposit183488972023-10-14 13:24:11329 days ago1697289851IN
0x4181E561...B9Bc80c8F
0 ETH0.002865576.10269842
Deposit183208942023-10-10 15:16:59333 days ago1696951019IN
0x4181E561...B9Bc80c8F
0 ETH0.004147699.09403125
Set Owner179856632023-08-24 16:10:23380 days ago1692893423IN
0x4181E561...B9Bc80c8F
0 ETH0.0008272929.53156062
Set Pool Manager179856572023-08-24 16:09:11380 days ago1692893351IN
0x4181E561...B9Bc80c8F
0 ETH0.0008396130
Set Pool Manager179856562023-08-24 16:08:59380 days ago1692893339IN
0x4181E561...B9Bc80c8F
0 ETH0.0007556130
Set Fee Manager179856462023-08-24 16:06:59380 days ago1692893219IN
0x4181E561...B9Bc80c8F
0 ETH0.0009003930
Set Extra Reward...179856452023-08-24 16:06:47380 days ago1692893207IN
0x4181E561...B9Bc80c8F
0 ETH0.0030005730
Set Vote Delegat...179856442023-08-24 16:06:35380 days ago1692893195IN
0x4181E561...B9Bc80c8F
0 ETH0.0014292930
Set Factories179856432023-08-24 16:06:23380 days ago1692893183IN
0x4181E561...B9Bc80c8F
0 ETH0.0021007830
Set Lock Reward ...179856422023-08-24 16:06:11380 days ago1692893171IN
0x4181E561...B9Bc80c8F
0 ETH0.0033867930
Set Mint Params179856412023-08-24 16:05:59380 days ago1692893159IN
0x4181E561...B9Bc80c8F
0 ETH0.0017017230
Set Earmark Dele...179846542023-08-24 12:46:47380 days ago1692881207IN
0x4181E561...B9Bc80c8F
0 ETH0.0009422420
0x61010060179846262023-08-24 12:41:11380 days ago1692880871IN
 Create: Booster
0 ETH0.1097985620

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Booster

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 800 runs

Other Settings:
default evmVersion
File 1 of 6 : Booster.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;

import "./interfaces/Interfaces.sol";
import "@openzeppelin/contracts-0.6/math/SafeMath.sol";
import "@openzeppelin/contracts-0.6/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts-0.6/utils/Address.sol";
import "@openzeppelin/contracts-0.6/token/ERC20/SafeERC20.sol";

/**
 * @title   Booster
 * @author  ConvexFinance -> WombexFinance
 * @notice  Main deposit contract; keeps track of pool info & user deposits; distributes rewards.
 * @dev     They say all paths lead to Rome, and the Booster is no different. This is where it all goes down.
 *          It is responsible for tracking all the pools, it collects rewards from all pools and redirects it.
 */
contract Booster{
    using SafeERC20 for IERC20;
    using Address for address;
    using SafeMath for uint256;

    uint256 public constant MAX_PENALTY_SHARE = 3000;
    uint256 public constant DENOMINATOR = 10000;

    address public immutable crv;
    address public immutable cvx;
    address public immutable weth;
    address public immutable voterProxy;

    address public owner;
    address public feeManager;
    address public poolManager;
    address public rewardFactory;
    address public tokenFactory;
    address public earmarkDelegate;
    address public crvLockRewards;
    address public cvxLocker;
    address public reservoirMinter;
    address public mintManager;

    mapping(address => bool) public voteDelegate;

    IExtraRewardsDistributor public extraRewardsDist;

    uint256 public penaltyShare = 0;
    mapping(uint256 => uint256) public customPenaltyShare;

    bool public earmarkOnDeposit;

    uint256 public minMintRatio;
    uint256 public maxMintRatio;
    uint256 public mintRatio;
    bool public paused;

    mapping(uint256 => uint256) public customMintRatio;

    bool public isShutdown;

    struct PoolInfo {
        address lptoken;
        address token;
        address gauge;
        address crvRewards;
        bool shutdown;
    }

    //index(pid) -> pool
    PoolInfo[] public poolInfo;
    mapping(address => bool) public votingMap;

    mapping(address => address[]) public lpPendingRewardTokens;
    mapping(address => mapping(address => uint256)) public lpPendingRewards;

    event Deposited(address indexed user, uint256 indexed poolid, uint256 amount);
    event Withdrawn(address indexed user, uint256 indexed poolid, uint256 amount);

    event PoolAdded(address indexed lpToken, address gauge, address token, address crvRewards, uint256 pid);
    event PoolShutdown(uint256 indexed poolId);
    event RewardMigrate(address indexed crvRewards, address indexed newBooster, uint256 indexed poolId);

    event OwnerUpdated(address newOwner);
    event FeeManagerUpdated(address newFeeManager);
    event PoolManagerUpdated(address newPoolManager);
    event FactoriesUpdated(address rewardFactory, address tokenFactory);
    event ExtraRewardsDistributorUpdated(address newDist);
    event LpPendingRewardTokensUpdated(address indexed lpToken, address[] pendingRewardTokens);
    event PenaltyShareUpdated(uint256 newPenalty);
    event VoteDelegateUpdated(address voteDelegate, bool enabled);
    event EarmarkDelegateUpdated(address newEarmarkDelegate);
    event VotingMapUpdated(address voting, bool valid);
    event LockRewardContractsUpdated(address lockRewards, address cvxLocker);
    event MintParamsUpdated(uint256 mintRatio, address reservoirMinter, address mintManager);
    event SetPaused(bool paused);
    event CustomMintRatioUpdated(uint256 indexed pid, uint256 mintRatio);
    event CustomPenaltyShareUpdated(uint256 indexed pid, uint256 penaltyShare);
    event SetEarmarkOnDeposit(bool earmarkOnDeposit);
    event FeeInfoUpdated(address feeDistro, address lockFees, address feeToken);
    event FeeInfoChanged(address feeToken, bool active);

    event EarmarkRewards(uint256 indexed pid, address indexed lpToken, address indexed rewardToken, uint256 amount);
    event EarmarkRewardsTransfer(uint256 indexed pid, address indexed lpToken, address indexed rewardToken, uint256 amount, address distro, bool queue);
    event RewardClaimed(uint256 indexed pid, address indexed user, uint256 amount, bool indexed lock, uint256 mintAmount, uint256 penalty);
    event MinterMint(address indexed recipient, uint256 amount);

    /**
     * @dev Constructor doing what constructors do. It is noteworthy that
     *      a lot of basic config is set to 0 - expecting subsequent calls to setFeeInfo etc.
     * @param _voterProxy             VoterProxy (locks the crv and adds to all gauges)
     * @param _reservoirMinter        Reservoir
     * @param _cvx                    CVX/WMX token
     * @param _crv                    CRV/WOM
     * @param _weth                   WETH
     * @param _minMintRatio           Min mint ratio
     * @param _maxMintRatio           Max mint ratio
     */
    constructor(
        address _voterProxy,
        address _reservoirMinter,
        address _cvx,
        address _crv,
        address _weth,
        uint256 _minMintRatio,
        uint256 _maxMintRatio
    ) public {
        voterProxy = _voterProxy;
        reservoirMinter = _reservoirMinter;
        cvx = _cvx;
        crv = _crv;
        weth = _weth;
        isShutdown = false;

        minMintRatio = _minMintRatio;
        maxMintRatio = _maxMintRatio;

        owner = msg.sender;
        feeManager = msg.sender;
        poolManager = msg.sender;

        emit OwnerUpdated(msg.sender);
        emit FeeManagerUpdated(msg.sender);
        emit PoolManagerUpdated(msg.sender);
    }


    /// SETTER SECTION ///

    /**
     * @notice Owner is responsible for setting initial config, updating vote delegate and shutting system
     */
    function setOwner(address _owner) external {
        require(msg.sender == owner, "!auth");
        owner = _owner;

        emit OwnerUpdated(_owner);
    }

    /**
     * @notice Fee Manager can update the fees (lockIncentive, stakeIncentive, earmarkIncentive, platformFee)
     */
    function setFeeManager(address _feeM) external {
        require(msg.sender == owner, "!auth");
        feeManager = _feeM;

        emit FeeManagerUpdated(_feeM);
    }

    /**
     * @notice Pool manager is responsible for adding new pools
     */
    function setPoolManager(address _poolM) external {
        require(msg.sender == poolManager || msg.sender == owner, "!auth");
        poolManager = _poolM;

        emit PoolManagerUpdated(_poolM);
    }

    /**
     * @notice Factories are used when deploying new pools.
     */
    function setFactories(address _rfactory, address _tfactory) external {
        require(msg.sender == owner, "!auth");
        require(rewardFactory == address(0), "!zero");

        //reward factory only allow this to be called once even if owner
        //removes ability to inject malicious staking contracts
        //token factory can also be immutable
        rewardFactory = _rfactory;
        tokenFactory = _tfactory;

        emit FactoriesUpdated(_rfactory, _tfactory);
    }

    /**
     * @notice Extra rewards distributor handles cvx/wmx penalty
     */
    function setExtraRewardsDistributor(address _dist) external {
        require(msg.sender==owner, "!auth");
        extraRewardsDist = IExtraRewardsDistributor(_dist);

        IERC20(cvx).safeApprove(_dist, 0);
        IERC20(cvx).safeApprove(_dist, type(uint256).max);

        emit ExtraRewardsDistributorUpdated(_dist);
    }

    /**
     * @notice Extra rewards distributor handles cvx/wmx penalty
     */
    function setRewardClaimedPenalty(uint256 _penaltyShare) external {
        require(msg.sender==owner, "!auth");
        require(_penaltyShare <= MAX_PENALTY_SHARE, ">max");
        penaltyShare = _penaltyShare;

        emit PenaltyShareUpdated(_penaltyShare);
    }

    function setRewardTokenPausedInPools(address[] memory _rewardPools, address _token, bool _paused) external {
        require(msg.sender==owner, "!auth");

        for (uint256 i = 0; i < _rewardPools.length; i++) {
            IRewards(_rewardPools[i]).setRewardTokenPaused(_token, _paused);
        }
    }

    /**
     * @notice Vote Delegate has the rights to cast votes on the VoterProxy via the Booster
     */
    function setVoteDelegate(address _voteDelegate, bool _enabled) external {
        require(msg.sender==owner, "!auth");
        voteDelegate[_voteDelegate] = _enabled;

        emit VoteDelegateUpdated(_voteDelegate, _enabled);
    }

    /**
     * @notice Vote Delegate has the rights to cast votes on the VoterProxy via the Booster
     */
    function setVotingValid(address _voting, bool _valid) external {
        require(msg.sender == owner || voteDelegate[msg.sender], "!auth");
        votingMap[_voting] = _valid;

        emit VotingMapUpdated(_voting, _valid);
    }

    /**
     * @notice Earmark Delegate has the rights to cast claim and distribute VoterProxy rewards
     */
    function setEarmarkDelegate(address _earmarkDelegate) external {
        require(msg.sender==owner, "!auth");
        earmarkDelegate = _earmarkDelegate;

        emit EarmarkDelegateUpdated(_earmarkDelegate);
    }

    /**
     * @notice Set tokens to cache pending rewards
     */
    function setLpPendingRewardTokens(address _lpToken, address[] memory _addresses) external {
        require(msg.sender==owner, "!auth");
        lpPendingRewardTokens[_lpToken] = _addresses;

        emit LpPendingRewardTokensUpdated(_lpToken, _addresses);
    }

    /**
     * @notice Set tokens to cache pending rewards
     */
    function updateLpPendingRewardTokensByGauge(uint256 _pid) external {
        require(msg.sender==owner, "!auth");
        PoolInfo storage p = poolInfo[_pid];
        lpPendingRewardTokens[p.lptoken] = IStaker(voterProxy).getGaugeRewardTokens(p.lptoken, p.gauge);

        emit LpPendingRewardTokensUpdated(p.lptoken, lpPendingRewardTokens[p.lptoken]);
    }

    /**
     * @notice Only called once, to set the address of cvxCrv/wmxWOM (lockRewards)
     */
    function setLockRewardContracts(address _crvLockRewards, address _cvxLocker) external {
        require(msg.sender == owner, "!auth");

        //reward contracts are immutable or else the owner
        //has a means to redeploy and mint cvx/wmx via rewardClaimed()
        if (crvLockRewards == address(0)){
            crvLockRewards = _crvLockRewards;
            cvxLocker = _cvxLocker;
            IERC20(cvx).approve(cvxLocker, type(uint256).max);
            emit LockRewardContractsUpdated(_crvLockRewards, _cvxLocker);
        }
    }

    /**
     * @notice Change mint ratio in boundaries
     */
    function setMintParams(uint256 _mintRatio, address _reservoirMinter, address _mintManager) external {
        require(msg.sender == owner, "!auth");
        if (_mintRatio != 0) {
            require(_mintRatio >= minMintRatio && _mintRatio <= maxMintRatio, "!boundaries");
        }

        mintRatio = _mintRatio;
        reservoirMinter = _reservoirMinter;
        mintManager = _mintManager;
        emit MintParamsUpdated(_mintRatio, _reservoirMinter, _mintManager);
    }

    /**
     * @notice Change mint ratio in boundaries
     */
    function setPaused(bool _paused) external {
        require(msg.sender == owner, "!auth");
        paused = _paused;
        emit SetPaused(_paused);
    }

    /**
     * @notice Change mint ratio for multiple pools
     */
    function setCustomMintRatioMultiple(uint256[] memory _pids, uint256[] memory _mintRatios) external {
        require(msg.sender == owner, "!auth");

        uint256 len = _pids.length;
        require(len == _mintRatios.length, "!len");

        for(uint256 i = 0; i < len; i++) {
            if (_mintRatios[i] != 0) {
                require(_mintRatios[i] >= minMintRatio && _mintRatios[i] <= maxMintRatio, "!boundaries");
            }

            customMintRatio[_pids[i]] = _mintRatios[i];
            emit CustomMintRatioUpdated(_pids[i], _mintRatios[i]);
        }
    }

    /**
     * @notice Change penalty share for multiple pools
     */
    function setCustomPenaltyShareMultiple(uint256[] memory _pids, uint256[] memory _penaltyShares) external {
        require(msg.sender == owner, "!auth");

        uint256 len = _pids.length;
        require(len == _penaltyShares.length, "!len");

        for(uint256 i = 0; i < len; i++) {
            customPenaltyShare[_pids[i]] = _penaltyShares[i];
            emit CustomPenaltyShareUpdated(_pids[i], _penaltyShares[i]);
        }
    }

    /**
     * @notice Owner can set earmarkOnDeposit
     * @param _earmarkOnDeposit   Call earmark on deposit or not
     */
    function setEarmarkOnDeposit(bool _earmarkOnDeposit) external{
        require(msg.sender == owner, "!auth");
        earmarkOnDeposit = _earmarkOnDeposit;
        emit SetEarmarkOnDeposit(_earmarkOnDeposit);
    }

    /// END SETTER SECTION ///

    /**
     * @notice Called by the PoolManager (i.e. PoolManagerProxy) to add a new pool - creates all the required
     *         contracts (DepositToken, RewardPool) and then adds to the list!
     */
    function addPool(address _lptoken, address _gauge) external returns (uint256) {
        //the next pool's pid
        uint256 pid = poolInfo.length;

        //create a tokenized deposit
        address token = ITokenFactory(tokenFactory).CreateDepositToken(_lptoken);
        //create a reward contract for crv rewards
        address newRewardPool = IRewardFactory(rewardFactory).CreateCrvRewards(pid,token,_lptoken);

        return addCreatedPool(_lptoken, _gauge, token, newRewardPool);
    }


    /**
     * @notice Called by the PoolManager (i.e. PoolManagerProxy) to add a new pool - creates all the required
     *         contracts (DepositToken, RewardPool) and then adds to the list!
     */
    function addCreatedPool(address _lptoken, address _gauge, address _token, address _crvRewards) public returns (uint256){
        require(msg.sender == poolManager && !isShutdown, "!add");
        require(_gauge != address(0) && _lptoken != address(0),"!param");

        //the next pool's pid
        uint256 pid = poolInfo.length;

        if (IRewards(_crvRewards).pid() != pid) {
            IRewards(_crvRewards).updateOperatorData(address(this), pid);
        }

        IERC20(_token).safeApprove(_crvRewards, 0);
        IERC20(_token).safeApprove(_crvRewards, type(uint256).max);

        //add the new pool
        poolInfo.push(
            PoolInfo({
                lptoken: _lptoken,
                token: _token,
                gauge: _gauge,
                crvRewards: _crvRewards,
                shutdown: false
            })
        );

        emit PoolAdded(_lptoken, _gauge, _token, _crvRewards, pid);
        return poolInfo.length.sub(1);
    }

    /**
     * @notice Shuts down the pool by withdrawing everything from the gauge to here (can later be
     *         claimed from depositors by using the withdraw fn) and marking it as shut down
     */
    function shutdownPool(uint256 _pid) external returns(bool) {
        require(msg.sender == poolManager, "!auth");
        PoolInfo storage pool = poolInfo[_pid];

        //withdraw from gauge
        IStaker(voterProxy).withdrawAllLp(pool.lptoken,pool.gauge);

        pool.shutdown = true;

        emit PoolShutdown(_pid);
        return true;
    }

    /**
     * @notice Shuts down the pool and sets shutdown flag even if withdrawAllLp failed.
     */
    function forceShutdownPool(uint256 _pid) external returns(bool){
        require(msg.sender==poolManager, "!auth");
        PoolInfo storage pool = poolInfo[_pid];

        //withdraw from gauge
        uint128 amount = getLpBalance(pool.gauge, pool.lptoken);
        try IStaker(voterProxy).withdrawLp(pool.lptoken, pool.gauge, amount) {} catch {}

        pool.shutdown = true;

        emit PoolShutdown(_pid);
        return true;
    }

    /**
     * @notice Shuts down the WHOLE SYSTEM by withdrawing all the LP tokens to here and then allowing
     *         for subsequent withdrawal by any depositors.
     */
    function shutdownSystem() external{
        require(msg.sender == owner, "!auth");
        isShutdown = true;

        for(uint i=0; i < poolInfo.length; i++){
            PoolInfo storage pool = poolInfo[i];
            if (pool.shutdown) continue;

            //withdraw from gauge
            uint128 amount = getLpBalance(pool.gauge, pool.lptoken);
            try IStaker(voterProxy).withdrawLp(pool.lptoken, pool.gauge, amount) {
                pool.shutdown = true;
            }catch{}
        }
    }

    function migrateRewards(address[] calldata _rewards, uint256[] calldata _pids, address _newBooster) external {
        require(msg.sender == owner, "!auth");
        require(isShutdown, "!shutdown");

        uint256 len = _rewards.length;
        require(len == _pids.length, "!length");

        for (uint256 i = 0; i < len; i++) {
            if (_rewards[i] == address(0)) {
                continue;
            }
            IRewards(_rewards[i]).updateOperatorData(_newBooster, _pids[i]);
            if (_rewards[i] != crvLockRewards) {
                address stakingToken = IRewards(_rewards[i]).stakingToken();
                ITokenMinter(stakingToken).updateOperator(_newBooster);
            }
            emit RewardMigrate(_rewards[i], _newBooster, _pids[i]);
        }
    }

    /**
     * @notice  Deposits an "_amount" to a given gauge (specified by _pid), mints a `DepositToken`
     *          and subsequently stakes that on BaseRewardPool
     */
    function deposit(uint256 _pid, uint256 _amount, bool _stake) public returns(bool){
        return depositFor(_pid, _amount, _stake, msg.sender);
    }

    /**
     * @notice  Deposits an "_amount" to a given gauge (specified by _pid), mints a `DepositToken`
     *          and subsequently stakes that on BaseRewardPool
     */
    function depositFor(uint256 _pid, uint256 _amount, bool _stake, address _receiver) public returns(bool){
        require(!isShutdown,"shutdown");
        require(!paused, "paused");
        PoolInfo storage pool = poolInfo[_pid];
        require(pool.shutdown == false, "closed");

        //send to proxy to stake
        address lptoken = pool.lptoken;
        IERC20(lptoken).safeTransferFrom(msg.sender, voterProxy, _amount);

        //stake
        address gauge = pool.gauge;
        require(gauge != address(0),"!gauge");

        uint256[] memory rewardBalancesBefore = getPendingRewards(lptoken);
        IStaker(voterProxy).deposit(lptoken, gauge);
        _writePendingRewards(lptoken, rewardBalancesBefore);

        if (earmarkOnDeposit) {
            IBoosterEarmark(earmarkDelegate).earmarkRewardsIfAvailable(_pid);
        }

        address token = pool.token;
        if(_stake){
            //mint here and send to rewards on user behalf
            ITokenMinter(token).mint(address(this), _amount);
            IRewards(pool.crvRewards).stakeFor(_receiver, _amount);
        }else{
            //add user balance directly
            ITokenMinter(token).mint(_receiver, _amount);
        }

        emit Deposited(_receiver, _pid, _amount);
        return true;
    }

    /**
     * @notice  Withdraws LP tokens from a given PID (& user).
     *          1. Burn the cvxLP/wmxLP balance from "_from" (implicit balance check)
     *          2. If pool !shutdown.. withdraw from gauge
     *          3. Transfer out the LP tokens
     */
    function _withdraw(uint256 _pid, uint256 _amount, address _from, address _to) internal {
        require(!paused, "paused");
        PoolInfo storage pool = poolInfo[_pid];
        address lptoken = pool.lptoken;
        address gauge = pool.gauge;

        //remove lp balance
        address token = pool.token;
        ITokenMinter(token).burn(_from,_amount);

        //pull from gauge if not shutdown
        // if shutdown tokens will be in this contract
        if (!pool.shutdown) {
            uint256[] memory rewardBalancesBefore = getPendingRewards(lptoken);
            IStaker(voterProxy).withdrawLp(lptoken, gauge, _amount);
            _writePendingRewards(lptoken, rewardBalancesBefore);

            if (earmarkOnDeposit) {
                IBoosterEarmark(earmarkDelegate).earmarkRewards(_pid);
            }
        }

        //return lp tokens
        IERC20(lptoken).safeTransfer(_to, _amount);

        emit Withdrawn(_to, _pid, _amount);
    }

    /**
     * @notice  Withdraw a given amount from a pool (must already been unstaked from the Reward Pool -
     *          BaseRewardPool uses withdrawAndUnwrap to get around this)
     */
    function withdraw(uint256 _pid, uint256 _amount) public returns(bool){
        _withdraw(_pid,_amount,msg.sender,msg.sender);
        return true;
    }

    /**
     * @notice Allows the actual BaseRewardPool to withdraw and send directly to the user
     */
    function withdrawTo(uint256 _pid, uint256 _amount, address _to) external returns(bool){
        address rewardContract = poolInfo[_pid].crvRewards;
        require(msg.sender == rewardContract,"!auth");

        _withdraw(_pid,_amount,msg.sender,_to);
        return true;
    }

    function getPendingRewardTokens(address _lptoken) public view returns (address[] memory tokens) {
        if (lpPendingRewardTokens[_lptoken].length > 0) {
            return lpPendingRewardTokens[_lptoken];
        } else {
            tokens = new address[](1);
            tokens[0] = crv;
        }
    }

    function getPendingRewards(address _lptoken) public view returns (uint256[] memory result) {
        address[] memory tokens = getPendingRewardTokens(_lptoken);
        uint256 len = tokens.length;
        result = new uint256[](len);
        for (uint256 i = 0; i < len; i++) {
            uint256 balance = IERC20(tokens[i]).balanceOf(voterProxy);
            if (tokens[i] == weth) {
                balance = balance.add(voterProxy.balance);
            }
            result[i] = balance;
        }
    }

    function _writePendingRewards(address _lptoken, uint256[] memory _rewardsBefore) internal {
        address[] memory tokens = getPendingRewardTokens(_lptoken);
        uint256 len = _rewardsBefore.length;
        for (uint256 i = 0; i < len; i++) {
            address token = tokens[i];
            uint256 balance = IERC20(token).balanceOf(voterProxy);
            if (token == weth) {
                balance = balance.add(voterProxy.balance);
            }
            lpPendingRewards[_lptoken][token] = lpPendingRewards[_lptoken][token].add(balance.sub(_rewardsBefore[i]));
        }
    }

    /**
     * @notice set valid vote hash on VoterProxy
     */
    function setVote(bytes32 _hash, bool valid) external returns(bool){
        require(voteDelegate[msg.sender], "!auth");

        IStaker(voterProxy).setVote(_hash, valid);
        return true;
    }

    /**
     * @notice Delegate address votes on gauge weight via VoterProxy
     */
    function voteExecute(address _voting, uint256 _value, bytes calldata _data) external payable returns(bytes memory result) {
        require(voteDelegate[msg.sender], "!auth");
        require(votingMap[_voting], "!voting");

        (, result) = IStaker(voterProxy).execute{value:_value}(_voting, _value, _data);
        return result;
    }

    function voterProxyClaimRewards(uint256 _pid, address[] memory _pendingTokens) external returns (uint256[] memory pendingRewards) {
        require(earmarkDelegate == msg.sender, "!auth");

        PoolInfo storage pool = poolInfo[_pid];
        address lptoken = pool.lptoken;

        IStaker(voterProxy).claimCrv(lptoken, pool.gauge);

        uint256 tLen = _pendingTokens.length;
        pendingRewards = new uint256[](tLen);

        for (uint256 i = 0; i < tLen; i++) {
            pendingRewards[i] = lpPendingRewards[lptoken][_pendingTokens[i]];
            if (lpPendingRewards[lptoken][_pendingTokens[i]] > 0) {
                lpPendingRewards[lptoken][_pendingTokens[i]] = 0;
            }
        }
    }

    function distributeRewards(
        uint256 _pid,
        address _lpToken,
        address _rewardToken,
        address[] memory _transferTo,
        uint256[] memory _transferAmount,
        bool[] memory _callQueue
    ) external {
        require(!paused, "paused");
        require(earmarkDelegate == msg.sender, "!auth");

        uint256 tLen = _transferTo.length;
        require(tLen == _transferAmount.length && tLen == _callQueue.length, "!len");

        uint256 sum = 0;
        for (uint256 i = 0; i < tLen; i++) {
            sum = sum.add(_transferAmount[i]);
            if (_callQueue[i]) {
                IRewards(_transferTo[i]).queueNewRewards(_rewardToken, _transferAmount[i]);
            } else {
                IERC20(_rewardToken).safeTransfer(_transferTo[i], _transferAmount[i]);
            }
            emit EarmarkRewardsTransfer(_pid, _lpToken, _rewardToken, _transferAmount[i], _transferTo[i], _callQueue[i]);
        }
        emit EarmarkRewards(_pid, _lpToken, _rewardToken, sum);
    }

    function approveDistribution(address _distro, address[] memory _distributionTokens, uint256 _amount) external {
        require(earmarkDelegate == msg.sender, "!auth");

        uint256 distTokensLen = _distributionTokens.length;
        for (uint256 i = 0; i < distTokensLen; i++) {
            IERC20(_distributionTokens[i]).safeApprove(_distro, 0);
            if (_amount > 0) {
                IERC20(_distributionTokens[i]).safeApprove(_distro, _amount);
            }
        }
    }

    function approvePoolsCrvRewardsDistribution(address _token) external {
        require(earmarkDelegate == msg.sender, "!auth");

        uint256 poolLen = poolInfo.length;
        for (uint256 i = 0; i < poolLen; i++) {
            IERC20(_token).safeApprove(poolInfo[i].crvRewards, 0);
            IERC20(_token).safeApprove(poolInfo[i].crvRewards, type(uint256).max);
        }
    }

    /**
     * @notice Callback from reward contract when crv/wom is received.
     * @dev    Goes off and mints a relative amount of CVX/WMX based on the distribution schedule.
     */
    function rewardClaimed(uint256 _pid, address _address, uint256 _amount, bool _lock) external returns(bool){
        require(!paused, "paused");
        address rewardContract = poolInfo[_pid].crvRewards;
        require(msg.sender == rewardContract || msg.sender == crvLockRewards, "!auth");

        uint256 mintAmount = _amount;
        uint256 poolMintRatio = customMintRatio[_pid];
        if (poolMintRatio == 0) {
            poolMintRatio = mintRatio;
        }
        if (poolMintRatio > 0) {
            mintAmount = mintAmount.mul(poolMintRatio).div(DENOMINATOR);
        }
        uint256 poolPenaltyShare = customPenaltyShare[_pid];
        if (poolPenaltyShare == 0) {
            poolPenaltyShare = penaltyShare;
        } else if (poolPenaltyShare == 1) {
            poolPenaltyShare = 0;
        }

        ITokenMinter tokenMinter = reservoirMinter == address(0) ? ITokenMinter(cvx) : ITokenMinter(reservoirMinter);
        uint256 penalty;
        if (_lock) {
            uint256 balanceBefore = IERC20(cvx).balanceOf(address(this));
            tokenMinter.mint(address(this), mintAmount);
            ICvxLocker(cvxLocker).lock(_address, IERC20(cvx).balanceOf(address(this)).sub(balanceBefore));
        } else {
            penalty = mintAmount.mul(poolPenaltyShare).div(DENOMINATOR);
            mintAmount = mintAmount.sub(penalty);
            //mint reward to user, except the penalty
            tokenMinter.mint(_address, mintAmount);
            if (penalty > 0) {
                uint256 balanceBefore = IERC20(cvx).balanceOf(address(this));
                tokenMinter.mint(address(this), penalty);
                extraRewardsDist.addReward(cvx, IERC20(cvx).balanceOf(address(this)).sub(balanceBefore));
            }
        }
        emit RewardClaimed(_pid, _address, _amount, _lock, mintAmount, penalty);
        return true;
    }

    /**
     * @notice Allows the owner to mint new `cvx` tokens and allocate them to a specified address.
     * @param _address The address to allocate the newly minted tokens to.
     * @param _amount The amount of `cvx` tokens to be minted.
     * @return A boolean indicating whether or not the operation was successful.
     */
    function minterMint(address _address, uint256 _amount) external returns(bool){
        require(msg.sender == mintManager, "!auth");
        ITokenMinter(cvx).mint(_address, _amount);
        emit MinterMint(_address, _amount);
        return true;
    }


    function getLpBalance(address _gauge, address _lptoken) public returns (uint128 amount) {
        uint256 mwPid = IStaker(voterProxy).lpTokenToPid(_gauge, _lptoken);
        (amount, , ,) = IMasterWombat(_gauge).userInfo(mwPid, voterProxy);
    }

    function poolLength() external view returns (uint256) {
        return poolInfo.length;
    }
}

File 2 of 6 : SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}

File 3 of 6 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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);
}

File 4 of 6 : SafeERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using SafeMath for uint256;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 5 of 6 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <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;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.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");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 6 of 6 : Interfaces.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;

interface IMasterWombat {
    function deposit(uint256 _pid, uint256 _amount) external;
    function balanceOf(address) external view returns(uint256);
    function userInfo(uint256, address) external view returns (uint128 amount, uint128 factor, uint128 rewardDebt, uint128 pendingWom);
    function withdraw(uint256 _pid, uint256 _amount) external;
    function poolLength() external view returns(uint256);
    function poolInfo(uint256 _pid) external view returns (address lpToken, uint96 allocPoint, IMasterWombatRewarder rewarder, uint256 sumOfFactors, uint104 accWomPerShare, uint104 accWomPerFactorShare, uint40 lastRewardTimestamp);
    function migrate(uint256[] calldata _pids) external view;
    function newMasterWombat() external view returns (address);
}

interface IMasterWombatRewarder {
    function rewardTokens() external view returns (address[] memory tokens);
}

interface IBooster {
    function owner() external view returns(address);
}

interface IVeWom {
    function mint(uint256 amount, uint256 lockDays) external returns (uint256 veWomAmount);
    function burn(uint256 slot) external;
    function vote(uint256, bool, bool) external; //voteId, support, executeIfDecided
}

interface IVoting{
    function vote(uint256, bool, bool) external; //voteId, support, executeIfDecided
    function getVote(uint256) external view returns(bool,bool,uint64,uint64,uint64,uint64,uint256,uint256,uint256,bytes memory);
    function vote_for_gauge_weights(address,uint256) external;
}

interface IMinter{
    function mint(address) external;
    function updateOperator() external;
    function operator() external returns(address);
}

interface ICvxLocker {
    function lock(address _account, uint256 _amount) external;
}

interface IStaker{
    function deposit(address, address) external returns (bool);
    function withdraw(address) external returns (uint256);
    function withdrawLp(address, address, uint256) external returns (bool);
    function withdrawAllLp(address, address) external returns (bool);
    function lock(uint256 _lockDays) external;
    function releaseLock(uint256 _slot) external returns(uint256);
    function getGaugeRewardTokens(address _lptoken, address _gauge) external returns (address[] memory tokens);
    function claimCrv(address, address) external returns (address[] memory tokens);
    function balanceOfPool(address, address) external view returns (uint256);
    function operator() external view returns (address);
    function execute(address _to, uint256 _value, bytes calldata _data) external payable returns (bool, bytes memory);
    function setVote(bytes32 hash, bool valid) external;
    function setOperator(address _operator) external;
    function setOwner(address _owner) external;
    function setDepositor(address _depositor) external;
    function lpTokenToPid(address _gauge, address _lptoken) external view returns (uint256);
    function lpTokenPidSet(address _gauge, address _lptoken) external view returns (bool);
}

interface IBoosterEarmark {
    function earmarkRewards(uint256 _pid) external;
    function earmarkRewardsIfAvailable(uint256 _pid) external;
    function earmarkIncentive() external view returns (uint256);
    function earmarkPeriod() external view returns (uint256);
    function distributionByTokenLength(address _token) external view returns (uint256);
    function distributionByTokens(address, uint256) external view returns (address, uint256, bool);
    function distributionTokenList() external view returns (address[] memory);
    function updateDistributionByTokens(address _token, address[] memory _distros, uint256[] memory _shares, bool[] memory _callQueue) external;
    function setEarmarkConfig(uint256 _earmarkIncentive, uint256 _earmarkPeriod) external;
    function transferOwnership(address newOwner) external;
    function addPool(address _lptoken, address _gauge) external returns (uint256);
    function addCreatedPool(address _lptoken, address _gauge, address _token, address _crvRewards) external returns (uint256);
}

interface IRewards{
    function pid() external view returns(uint256);
    function stake(address, uint256) external;
    function stakeFor(address, uint256) external;
    function withdraw(address, uint256) external;
    function exit(address) external;
    function getReward(address) external;
    function queueNewRewards(address, uint256) external;
    function notifyRewardAmount(uint256) external;
    function setRewardTokenPaused(address, bool) external;
    function updateOperatorData(address, uint256) external;
    function addExtraReward(address) external;
    function extraRewardsLength() external view returns (uint256);
    function stakingToken() external view returns (address);
    function rewardToken() external view returns(address);
    function earned(address account) external view returns (uint256);
    function setRatioData(uint256 duration_, uint256 newRewardRatio_) external;
}

interface ITokenMinter{
    function mint(address,uint256) external;
    function burn(address,uint256) external;
    function updateOperator(address) external;
}

interface IDeposit{
    function isShutdown() external view returns(bool);
    function balanceOf(address _account) external view returns(uint256);
    function totalSupply() external view returns(uint256);
    function poolInfo(uint256) external view returns(address,address,address,address,address, bool);
    function rewardClaimed(uint256,address,uint256,bool) external;
    function withdrawTo(uint256,uint256,address) external;
    function claimRewards(uint256,address) external returns(bool);
    function rewardArbitrator() external returns(address);
    function setGaugeRedirect(uint256 _pid) external returns(bool);
    function owner() external returns(address);
    function deposit(uint256 _pid, uint256 _amount, bool _stake) external returns(bool);
}

interface ICrvDeposit{
    function deposit(uint256, bool) external;
    function lockIncentive() external view returns(uint256);
}

interface IRewardFactory{
    function setAccess(address,bool) external;
    function CreateCrvRewards(uint256,address,address) external returns(address);
    function CreateTokenRewards(address,address,address) external returns(address);
    function activeRewardCount(address) external view returns(uint256);
    function addActiveReward(address,uint256) external returns(bool);
    function removeActiveReward(address,uint256) external returns(bool);
}

interface IStashFactory{
    function CreateStash(uint256,address,address,uint256) external returns(address);
}

interface ITokenFactory{
    function CreateDepositToken(address) external returns(address);
}

interface IPools{
    function addPool(address _lptoken, address _gauge, uint256 _stashVersion) external returns(bool);
    function forceAddPool(address _lptoken, address _gauge, uint256 _stashVersion) external returns(bool);
    function shutdownPool(uint256 _pid) external returns(bool);
    function poolInfo(uint256) external view returns(address,address,address,address,address,bool);
    function poolLength() external view returns (uint256);
    function gaugeMap(address) external view returns(bool);
    function setPoolManager(address _poolM) external;
}

interface IVestedEscrow{
    function fund(address[] calldata _recipient, uint256[] calldata _amount) external returns(bool);
}

interface IRewardDeposit {
    function addReward(address, uint256) external;
}

interface IWETH {
    function deposit() external payable;
}

interface IExtraRewardsDistributor {
    function addReward(address _token, uint256 _amount) external;
}

Settings
{
  "metadata": {
    "bytecodeHash": "none"
  },
  "optimizer": {
    "enabled": true,
    "runs": 800
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_voterProxy","type":"address"},{"internalType":"address","name":"_reservoirMinter","type":"address"},{"internalType":"address","name":"_cvx","type":"address"},{"internalType":"address","name":"_crv","type":"address"},{"internalType":"address","name":"_weth","type":"address"},{"internalType":"uint256","name":"_minMintRatio","type":"uint256"},{"internalType":"uint256","name":"_maxMintRatio","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintRatio","type":"uint256"}],"name":"CustomMintRatioUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"penaltyShare","type":"uint256"}],"name":"CustomPenaltyShareUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"poolid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newEarmarkDelegate","type":"address"}],"name":"EarmarkDelegateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"address","name":"lpToken","type":"address"},{"indexed":true,"internalType":"address","name":"rewardToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EarmarkRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"address","name":"lpToken","type":"address"},{"indexed":true,"internalType":"address","name":"rewardToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"distro","type":"address"},{"indexed":false,"internalType":"bool","name":"queue","type":"bool"}],"name":"EarmarkRewardsTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newDist","type":"address"}],"name":"ExtraRewardsDistributorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rewardFactory","type":"address"},{"indexed":false,"internalType":"address","name":"tokenFactory","type":"address"}],"name":"FactoriesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"feeToken","type":"address"},{"indexed":false,"internalType":"bool","name":"active","type":"bool"}],"name":"FeeInfoChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"feeDistro","type":"address"},{"indexed":false,"internalType":"address","name":"lockFees","type":"address"},{"indexed":false,"internalType":"address","name":"feeToken","type":"address"}],"name":"FeeInfoUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newFeeManager","type":"address"}],"name":"FeeManagerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"lockRewards","type":"address"},{"indexed":false,"internalType":"address","name":"cvxLocker","type":"address"}],"name":"LockRewardContractsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lpToken","type":"address"},{"indexed":false,"internalType":"address[]","name":"pendingRewardTokens","type":"address[]"}],"name":"LpPendingRewardTokensUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"mintRatio","type":"uint256"},{"indexed":false,"internalType":"address","name":"reservoirMinter","type":"address"},{"indexed":false,"internalType":"address","name":"mintManager","type":"address"}],"name":"MintParamsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"MinterMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newPenalty","type":"uint256"}],"name":"PenaltyShareUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lpToken","type":"address"},{"indexed":false,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"crvRewards","type":"address"},{"indexed":false,"internalType":"uint256","name":"pid","type":"uint256"}],"name":"PoolAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newPoolManager","type":"address"}],"name":"PoolManagerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"poolId","type":"uint256"}],"name":"PoolShutdown","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"bool","name":"lock","type":"bool"},{"indexed":false,"internalType":"uint256","name":"mintAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"penalty","type":"uint256"}],"name":"RewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"crvRewards","type":"address"},{"indexed":true,"internalType":"address","name":"newBooster","type":"address"},{"indexed":true,"internalType":"uint256","name":"poolId","type":"uint256"}],"name":"RewardMigrate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"earmarkOnDeposit","type":"bool"}],"name":"SetEarmarkOnDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"SetPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"voteDelegate","type":"address"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"VoteDelegateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"voting","type":"address"},{"indexed":false,"internalType":"bool","name":"valid","type":"bool"}],"name":"VotingMapUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"poolid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PENALTY_SHARE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_lptoken","type":"address"},{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_crvRewards","type":"address"}],"name":"addCreatedPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lptoken","type":"address"},{"internalType":"address","name":"_gauge","type":"address"}],"name":"addPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_distro","type":"address"},{"internalType":"address[]","name":"_distributionTokens","type":"address[]"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"approveDistribution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"approvePoolsCrvRewardsDistribution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"crv","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crvLockRewards","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"customMintRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"customPenaltyShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cvx","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cvxLocker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_stake","type":"bool"}],"name":"deposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_stake","type":"bool"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"depositFor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_lpToken","type":"address"},{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"address[]","name":"_transferTo","type":"address[]"},{"internalType":"uint256[]","name":"_transferAmount","type":"uint256[]"},{"internalType":"bool[]","name":"_callQueue","type":"bool[]"}],"name":"distributeRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"earmarkDelegate","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"earmarkOnDeposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"extraRewardsDist","outputs":[{"internalType":"contract IExtraRewardsDistributor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"forceShutdownPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"address","name":"_lptoken","type":"address"}],"name":"getLpBalance","outputs":[{"internalType":"uint128","name":"amount","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lptoken","type":"address"}],"name":"getPendingRewardTokens","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_lptoken","type":"address"}],"name":"getPendingRewards","outputs":[{"internalType":"uint256[]","name":"result","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isShutdown","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"lpPendingRewardTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"lpPendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_rewards","type":"address[]"},{"internalType":"uint256[]","name":"_pids","type":"uint256[]"},{"internalType":"address","name":"_newBooster","type":"address"}],"name":"migrateRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minMintRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"minterMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"penaltyShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"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":"bool","name":"shutdown","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reservoirMinter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_lock","type":"bool"}],"name":"rewardClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"},{"internalType":"uint256[]","name":"_mintRatios","type":"uint256[]"}],"name":"setCustomMintRatioMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"},{"internalType":"uint256[]","name":"_penaltyShares","type":"uint256[]"}],"name":"setCustomPenaltyShareMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_earmarkDelegate","type":"address"}],"name":"setEarmarkDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_earmarkOnDeposit","type":"bool"}],"name":"setEarmarkOnDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_dist","type":"address"}],"name":"setExtraRewardsDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rfactory","type":"address"},{"internalType":"address","name":"_tfactory","type":"address"}],"name":"setFactories","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeM","type":"address"}],"name":"setFeeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_crvLockRewards","type":"address"},{"internalType":"address","name":"_cvxLocker","type":"address"}],"name":"setLockRewardContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lpToken","type":"address"},{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"setLpPendingRewardTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintRatio","type":"uint256"},{"internalType":"address","name":"_reservoirMinter","type":"address"},{"internalType":"address","name":"_mintManager","type":"address"}],"name":"setMintParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_poolM","type":"address"}],"name":"setPoolManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_penaltyShare","type":"uint256"}],"name":"setRewardClaimedPenalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_rewardPools","type":"address[]"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setRewardTokenPausedInPools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bool","name":"valid","type":"bool"}],"name":"setVote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_voteDelegate","type":"address"},{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setVoteDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_voting","type":"address"},{"internalType":"bool","name":"_valid","type":"bool"}],"name":"setVotingValid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"shutdownPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shutdownSystem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updateLpPendingRewardTokensByGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"voteDelegate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_voting","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"voteExecute","outputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"voterProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address[]","name":"_pendingTokens","type":"address[]"}],"name":"voterProxyClaimRewards","outputs":[{"internalType":"uint256[]","name":"pendingRewards","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"votingMap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"withdrawTo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

6101006040526000600c553480156200001757600080fd5b506040516200622b3803806200622b833981810160405260e08110156200003d57600080fd5b50805160208083015160408085015160608087015160808089015160a0808b015160c09b8c01516001600160601b03198c881b811660e052600880546001600160a01b038d166001600160a01b03199182161790915589891b821690945286881b81169095529583901b909316909a526014805460ff19169055600f8290556010849055600080548b1633908117909155600180548c168217905560028054909b168117909a558551998a529451979895979396919590937f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b929181900390910190a16040805133815290517fe45f5e140399b0a7e12971ab020724b828fbed8ac408c420884dc7d1bbe506b49181900360200190a16040805133815290517f70a64736553c84939f57deec269299882abbbee8dc4f316eccbc6fce57e4d3cf9181900360200190a15050505050505060805160601c60a05160601c60c05160601c60e05160601c615fd06200025b60003980611fbc52806120505280612326528061239652806128d952806129a05280612c125280612e8752806137485280614154528061464252806149bd52806152b952806153a252806156c952806158f752806159c4525080612cde528061535052806159835250806118ae5280611bdf5280611c14528061247352806134e65280613b2d5280613b5b5280613c915280613e0a5280613f38525080612f4652806144655250615fd06000f3fe60806040526004361061047e5760003560e01c80637aef67151161025e578063bf86d69011610143578063e1024932116100bb578063ebe537741161008a578063edc431591161006f578063edc43159146115d7578063f6ed2017146117a9578063fb538246146117dc5761047e565b8063ebe5377414611598578063ed000462146115c25761047e565b8063e1024932146113e5578063e77772fe14611515578063ea6048451461152a578063eb511dd41461155d5761047e565b8063d055eac911610112578063dc4c90d3116100f7578063dc4c90d31461129d578063deaeacfd146112b2578063e0d85f1f146113aa5761047e565b8063d055eac91461124d578063d0fb0203146112885761047e565b8063bf86d6901461113b578063c7ed531214611150578063ca412f9214611165578063cb9dfb9c146112235761047e565b80639aa4c2e5116101d6578063a63634a1116101a5578063adf52fd41161018a578063adf52fd414611017578063b9b98b54146110d5578063be165abd146111085761047e565b8063a63634a114610fd8578063a9ffa1ca146110025761047e565b80639aa4c2e514610e185780639efe5d2014610e53578063a3ea45cc14610f58578063a40018ab14610f9f5761047e565b80638da5cb5b1161022d578063918f867411610212578063918f867414610dc2578063923c1d6114610dd757806394e70d7814610dec5761047e565b80638da5cb5b14610d6c5780638fc0b68514610d815761047e565b80637aef671514610cfa5780637b3370ce14610d2d5780637e4edf7014610d425780638d68f9ff14610d575761047e565b806328dbdff11161038457806343a0d066116102fc578063525c42d8116102cb57806360cafe84116102b057806360cafe8414610c705780636a4874a114610c9a5780636ab94fd614610caf5761047e565b8063525c42d814610c315780635c975abb14610c5b5761047e565b806343a0d06614610b81578063441a3e7014610bb9578063472d35b914610be95780634d8527b914610c1c5761047e565b8063354af919116103535780633a0bcd20116103385780633a0bcd2014610b425780633f9bcc6c14610b575780633fc8cef314610b6c5761047e565b8063354af91914610af2578063390e75f914610b075761047e565b806328dbdff114610976578063293932c014610a4a5780632ada885a14610aaa5780632ee9808d14610abf5761047e565b80631526fe27116104175780631ba980b3116103e657806321f314ca116103cb57806321f314ca146109135780632249f6131461094c578063245e4bf0146109615761047e565b80631ba980b3146108cc5780631fbd8974146108e15761047e565b80631526fe27146107c3578063168d3d6e1461082857806316c38b3c1461085957806317baa443146108855761047e565b8063099ae20811610453578063099ae208146106d757806312425eb51461071e57806313af40351461075157806314cd70e4146107845761047e565b806232880814610483578062bfa239146104c0578063081e3eda1461058057806309771b95146105a7575b600080fd5b34801561048f57600080fd5b506104be600480360360408110156104a657600080fd5b506001600160a01b0381358116916020013516611806565b005b3480156104cc57600080fd5b506104be600480360360608110156104e357600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561050d57600080fd5b82018360208201111561051f57600080fd5b803590602001918460208302840111600160201b8311171561054057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550509135925061196f915050565b34801561058c57600080fd5b50610595611a1b565b60408051918252519081900360200190f35b3480156105b357600080fd5b506104be600480360360408110156105ca57600080fd5b810190602081018135600160201b8111156105e457600080fd5b8201836020820111156105f657600080fd5b803590602001918460208302840111600160201b8311171561061757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561066657600080fd5b82018360208201111561067857600080fd5b803590602001918460208302840111600160201b8311171561069957600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611a21945050505050565b3480156106e357600080fd5b5061070a600480360360208110156106fa57600080fd5b50356001600160a01b0316611b5d565b604080519115158252519081900360200190f35b34801561072a57600080fd5b506104be6004803603602081101561074157600080fd5b50356001600160a01b0316611b72565b34801561075d57600080fd5b506104be6004803603602081101561077457600080fd5b50356001600160a01b0316611c7c565b34801561079057600080fd5b5061070a600480360360608110156107a757600080fd5b50803590602081013590604001356001600160a01b0316611d17565b3480156107cf57600080fd5b506107ed600480360360208110156107e657600080fd5b5035611d9b565b604080516001600160a01b03968716815294861660208601529285168484015293166060830152911515608082015290519081900360a00190f35b34801561083457600080fd5b5061083d611dee565b604080516001600160a01b039092168252519081900360200190f35b34801561086557600080fd5b506104be6004803603602081101561087c57600080fd5b50351515611dfd565b34801561089157600080fd5b5061070a600480360360808110156108a857600080fd5b508035906020810135906040810135151590606001356001600160a01b0316611e8b565b3480156108d857600080fd5b5061083d612324565b3480156108ed57600080fd5b5061070a6004803603604081101561090457600080fd5b50803590602001351515612348565b34801561091f57600080fd5b5061070a6004803603604081101561093657600080fd5b506001600160a01b038135169060200135612427565b34801561095857600080fd5b5061083d612548565b34801561096d57600080fd5b5061083d612557565b34801561098257600080fd5b506104be6004803603606081101561099957600080fd5b810190602081018135600160201b8111156109b357600080fd5b8201836020820111156109c557600080fd5b803590602001918460208302840111600160201b831117156109e657600080fd5b919390929091602081019035600160201b811115610a0357600080fd5b820183602082011115610a1557600080fd5b803590602001918460208302840111600160201b83111715610a3657600080fd5b9193509150356001600160a01b0316612566565b348015610a5657600080fd5b50610a8560048036036040811015610a6d57600080fd5b506001600160a01b03813581169160200135166128d4565b604080516fffffffffffffffffffffffffffffffff9092168252519081900360200190f35b348015610ab657600080fd5b5061083d612a29565b348015610acb57600080fd5b506104be60048036036020811015610ae257600080fd5b50356001600160a01b0316612a38565b348015610afe57600080fd5b506104be612b0a565b348015610b1357600080fd5b5061059560048036036040811015610b2a57600080fd5b506001600160a01b0381358116916020013516612cb0565b348015610b4e57600080fd5b5061070a612ccd565b348015610b6357600080fd5b50610595612cd6565b348015610b7857600080fd5b5061083d612cdc565b348015610b8d57600080fd5b5061070a60048036036060811015610ba457600080fd5b50803590602081013590604001351515612d00565b348015610bc557600080fd5b5061070a60048036036040811015610bdc57600080fd5b5080359060200135612d16565b348015610bf557600080fd5b506104be60048036036020811015610c0c57600080fd5b50356001600160a01b0316612d2d565b348015610c2857600080fd5b50610595612dc8565b348015610c3d57600080fd5b5061059560048036036020811015610c5457600080fd5b5035612dce565b348015610c6757600080fd5b5061070a612de0565b348015610c7c57600080fd5b5061070a60048036036020811015610c9357600080fd5b5035612de9565b348015610ca657600080fd5b5061083d612f44565b348015610cbb57600080fd5b5061059560048036036080811015610cd257600080fd5b506001600160a01b038135811691602081013582169160408201358116916060013516612f68565b348015610d0657600080fd5b506104be60048036036020811015610d1d57600080fd5b50356001600160a01b03166132d7565b348015610d3957600080fd5b5061083d613387565b348015610d4e57600080fd5b5061083d613396565b348015610d6357600080fd5b5061083d6133a5565b348015610d7857600080fd5b5061083d6133b4565b348015610d8d57600080fd5b506104be60048036036060811015610da457600080fd5b508035906001600160a01b03602082013581169160400135166133c3565b348015610dce57600080fd5b506105956134de565b348015610de357600080fd5b5061083d6134e4565b348015610df857600080fd5b506104be60048036036020811015610e0f57600080fd5b50351515613508565b348015610e2457600080fd5b506104be60048036036040811015610e3b57600080fd5b506001600160a01b0381358116916020013516613596565b348015610e5f57600080fd5b50610f0860048036036040811015610e7657600080fd5b81359190810190604081016020820135600160201b811115610e9757600080fd5b820183602082011115610ea957600080fd5b803590602001918460208302840111600160201b83111715610eca57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506136aa945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610f44578181015183820152602001610f2c565b505050509050019250505060405180910390f35b348015610f6457600080fd5b5061070a60048036036080811015610f7b57600080fd5b508035906001600160a01b03602082013516906040810135906060013515156139df565b348015610fab57600080fd5b5061083d60048036036040811015610fc257600080fd5b506001600160a01b03813516906020013561404b565b348015610fe457600080fd5b5061070a60048036036020811015610ffb57600080fd5b5035614080565b34801561100e57600080fd5b50610595614219565b34801561102357600080fd5b506104be6004803603604081101561103a57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561106457600080fd5b82018360208201111561107657600080fd5b803590602001918460208302840111600160201b8311171561109757600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061421f945050505050565b3480156110e157600080fd5b506104be600480360360208110156110f857600080fd5b50356001600160a01b0316614313565b34801561111457600080fd5b50610f086004803603602081101561112b57600080fd5b50356001600160a01b03166143ae565b34801561114757600080fd5b5061070a6144b6565b34801561115c57600080fd5b506105956144bf565b34801561117157600080fd5b506104be6004803603606081101561118857600080fd5b810190602081018135600160201b8111156111a257600080fd5b8201836020820111156111b457600080fd5b803590602001918460208302840111600160201b831117156111d557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550506001600160a01b03833516935050506020013515156144c5565b34801561122f57600080fd5b506104be6004803603602081101561124657600080fd5b50356145a8565b34801561125957600080fd5b506104be6004803603604081101561127057600080fd5b506001600160a01b038135169060200135151561481c565b34801561129457600080fd5b5061083d6148e1565b3480156112a957600080fd5b5061083d6148f0565b611335600480360360608110156112c857600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b8111156112f757600080fd5b82018360208201111561130957600080fd5b803590602001918460018302840111600160201b8311171561132a57600080fd5b5090925090506148ff565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561136f578181015183820152602001611357565b50505050905090810190601f16801561139c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156113b657600080fd5b506104be600480360360408110156113cd57600080fd5b506001600160a01b0381351690602001351515614b64565b3480156113f157600080fd5b506104be6004803603604081101561140857600080fd5b810190602081018135600160201b81111561142257600080fd5b82018360208201111561143457600080fd5b803590602001918460208302840111600160201b8311171561145557600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156114a457600080fd5b8201836020820111156114b657600080fd5b803590602001918460208302840111600160201b831117156114d757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550614c0f945050505050565b34801561152157600080fd5b5061083d614dd9565b34801561153657600080fd5b5061070a6004803603602081101561154d57600080fd5b50356001600160a01b0316614de8565b34801561156957600080fd5b506105956004803603604081101561158057600080fd5b506001600160a01b0381358116916020013516614dfd565b3480156115a457600080fd5b50610595600480360360208110156115bb57600080fd5b5035614f1d565b3480156115ce57600080fd5b50610595614f2f565b3480156115e357600080fd5b506104be600480360360c08110156115fa57600080fd5b8135916001600160a01b03602082013581169260408301359091169190810190608081016060820135600160201b81111561163457600080fd5b82018360208201111561164657600080fd5b803590602001918460208302840111600160201b8311171561166757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156116b657600080fd5b8201836020820111156116c857600080fd5b803590602001918460208302840111600160201b831117156116e957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561173857600080fd5b82018360208201111561174a57600080fd5b803590602001918460208302840111600160201b8311171561176b57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550614f35945050505050565b3480156117b557600080fd5b50610f08600480360360208110156117cc57600080fd5b50356001600160a01b0316615233565b3480156117e857600080fd5b506104be600480360360208110156117ff57600080fd5b50356153f4565b6000546001600160a01b0316331461184d576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6006546001600160a01b031661196b57600680546001600160a01b038085166001600160a01b03199283161790925560078054848416921691909117908190556040805163095ea7b360e01b815291831660048301526000196024830152517f00000000000000000000000000000000000000000000000000000000000000009092169163095ea7b3916044808201926020929091908290030181600087803b1580156118f957600080fd5b505af115801561190d573d6000803e3d6000fd5b505050506040513d602081101561192357600080fd5b5050604080516001600160a01b0380851682528316602082015281517fd612424d9ffea115aebe524be81722e3605348e7c2777bb90c3a998b1883e68b929181900390910190a15b5050565b6005546001600160a01b031633146119b6576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b815160005b81811015611a14576119f58560008684815181106119d557fe5b60200260200101516001600160a01b03166154b69092919063ffffffff16565b8215611a0c57611a0c85848684815181106119d557fe5b6001016119bb565b5050505050565b60155490565b6000546001600160a01b03163314611a68576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b815181518114611aa8576040805162461bcd60e51b8152602060048083019190915260248201526310b632b760e11b604482015290519081900360640190fd5b60005b81811015611b5757828181518110611abf57fe5b6020026020010151600d6000868481518110611ad757fe5b6020026020010151815260200190815260200160002081905550838181518110611afd57fe5b60200260200101517f1c73e186fc4df717b5c7115e26b47995d803602fdad67f60a43f4118cf4432cd848381518110611b3257fe5b60200260200101516040518082815260200191505060405180910390a2600101611aab565b50505050565b60166020526000908152604090205460ff1681565b6000546001600160a01b03163314611bb9576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600b80546001600160a01b0319166001600160a01b0383811691909117909155611c07907f0000000000000000000000000000000000000000000000000000000000000000168260006154b6565b611c3d6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016826000196154b6565b604080516001600160a01b038316815290517fbb9094bc5ccbce4f74fb9568f8ff632f531c31d68138e511d46837e17aa1a7829181900360200190a150565b6000546001600160a01b03163314611cc3576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600080546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b9181900360200190a150565b60008060158581548110611d2757fe5b60009182526020909120600360049092020101546001600160a01b03169050338114611d82576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b611d8e858533866155c9565b60019150505b9392505050565b60158181548110611da857fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b03928316945090821692821691811690600160a01b900460ff1685565b6006546001600160a01b031681565b6000546001600160a01b03163314611e44576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6012805482151560ff19909116811790915560408051918252517f3c70af01296aef045b2f5c9d3c30b05d4428fd257145b9c7fcd76418e65b59809181900360200190a150565b60145460009060ff1615611ee6576040805162461bcd60e51b815260206004820152600860248201527f73687574646f776e000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60125460ff1615611f27576040805162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b604482015290519081900360640190fd5b600060158681548110611f3657fe5b600091825260209091206004909102016003810154909150600160a01b900460ff1615611faa576040805162461bcd60e51b815260206004820152600660248201527f636c6f7365640000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b80546001600160a01b0316611fe181337f000000000000000000000000000000000000000000000000000000000000000089615857565b60028201546001600160a01b031680612041576040805162461bcd60e51b815260206004820152600660248201527f2167617567650000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b606061204c83615233565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f9609f0884846040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b0316815260200192505050602060405180830381600087803b1580156120ce57600080fd5b505af11580156120e2573d6000803e3d6000fd5b505050506040513d60208110156120f857600080fd5b50612105905083826158b1565b600e5460ff161561217657600554604080516347f084c160e11b8152600481018c905290516001600160a01b0390921691638fe109829160248082019260009290919082900301818387803b15801561215d57600080fd5b505af1158015612171573d6000803e3d6000fd5b505050505b60018401546001600160a01b0316871561226457604080516340c10f1960e01b8152306004820152602481018b905290516001600160a01b038316916340c10f1991604480830192600092919082900301818387803b1580156121d857600080fd5b505af11580156121ec573d6000803e3d6000fd5b505050506003850154604080516305dc812160e31b81526001600160a01b038a81166004830152602482018d905291519190921691632ee4090891604480830192600092919082900301818387803b15801561224757600080fd5b505af115801561225b573d6000803e3d6000fd5b505050506122d4565b806001600160a01b03166340c10f19888b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156122bb57600080fd5b505af11580156122cf573d6000803e3d6000fd5b505050505b604080518a815290518b916001600160a01b038a16917f73a19dd210f1a7f902193214c0ee91dd35ee5b4d920cba8d519eca65a7b488ca9181900360200190a35060019998505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b336000908152600a602052604081205460ff16612394576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631fbd897484846040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b15801561240457600080fd5b505af1158015612418573d6000803e3d6000fd5b50505050600190505b92915050565b6009546000906001600160a01b03163314612471576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166340c10f1984846040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156124e857600080fd5b505af11580156124fc573d6000803e3d6000fd5b50506040805185815290516001600160a01b03871693507fc782e36a0e2d25f83f7caeaaa575d3924bee6885514d62247e6ed913d282b5a292509081900360200190a250600192915050565b6005546001600160a01b031681565b6003546001600160a01b031681565b6000546001600160a01b031633146125ad576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b60145460ff16612604576040805162461bcd60e51b815260206004820152600960248201527f2173687574646f776e0000000000000000000000000000000000000000000000604482015290519081900360640190fd5b83828114612659576040805162461bcd60e51b815260206004820152600760248201527f216c656e67746800000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60005b818110156128cb57600087878381811061267257fe5b905060200201356001600160a01b03166001600160a01b03161415612696576128c3565b8686828181106126a257fe5b905060200201356001600160a01b03166001600160a01b031663fdcb11f7848787858181106126cd57fe5b905060200201356040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561271a57600080fd5b505af115801561272e573d6000803e3d6000fd5b50506006546001600160a01b03169150889050878381811061274c57fe5b905060200201356001600160a01b03166001600160a01b03161461285457600087878381811061277857fe5b905060200201356001600160a01b03166001600160a01b03166372f702f36040518163ffffffff1660e01b815260040160206040518083038186803b1580156127c057600080fd5b505afa1580156127d4573d6000803e3d6000fd5b505050506040513d60208110156127ea57600080fd5b50516040805163ac7475ed60e01b81526001600160a01b03878116600483015291519293509083169163ac7475ed9160248082019260009290919082900301818387803b15801561283a57600080fd5b505af115801561284e573d6000803e3d6000fd5b50505050505b84848281811061286057fe5b90506020020135836001600160a01b031688888481811061287d57fe5b905060200201356001600160a01b03166001600160a01b03167ff40c7a0f343f6610bca64a1e012d50397f9a0b69350e567256694bcafc16239060405160405180910390a45b60010161265c565b50505050505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663bca8b4d185856040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561295557600080fd5b505afa158015612969573d6000803e3d6000fd5b505050506040513d602081101561297f57600080fd5b5051604080516393f1a40b60e01b8152600481018390526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301529151929350908616916393f1a40b91604480820192608092909190829003018186803b1580156129f557600080fd5b505afa158015612a09573d6000803e3d6000fd5b505050506040513d6080811015612a1f57600080fd5b5051949350505050565b6008546001600160a01b031681565b6005546001600160a01b03163314612a7f576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b60155460005b81811015612b0557612ac460158281548110612a9d57fe5b600091825260208220600360049092020101546001600160a01b03868116929116906154b6565b612afd60158281548110612ad457fe5b60009182526020909120600360049092020101546001600160a01b0385811691166000196154b6565b600101612a85565b505050565b6000546001600160a01b03163314612b51576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6014805460ff1916600117905560005b601554811015612cad57600060158281548110612b7a57fe5b906000526020600020906004020190508060030160149054906101000a900460ff1615612ba75750612ca5565b60028101548154600091612bc7916001600160a01b0391821691166128d4565b825460028401546040805163a6c3ef8b60e01b81526001600160a01b03938416600482015291831660248301526fffffffffffffffffffffffffffffffff84166044830152519293507f00000000000000000000000000000000000000000000000000000000000000009091169163a6c3ef8b916064808201926020929091908290030181600087803b158015612c5d57600080fd5b505af1925050508015612c8257506040513d6020811015612c7d57600080fd5b505160015b612c8b57612ca2565b5060038201805460ff60a01b1916600160a01b1790555b50505b600101612b61565b50565b601860209081526000928352604080842090915290825290205481565b600e5460ff1681565b60115481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000612d0e84848433611e8b565b949350505050565b6000612d24838333336155c9565b50600192915050565b6000546001600160a01b03163314612d74576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517fe45f5e140399b0a7e12971ab020724b828fbed8ac408c420884dc7d1bbe506b49181900360200190a150565b60105481565b60136020526000908152604090205481565b60125460ff1681565b6002546000906001600160a01b03163314612e33576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600060158381548110612e4257fe5b6000918252602080832060049283020180546002820154604080516318a0b19b60e21b81526001600160a01b03938416968101969096529082166024860152519195507f00000000000000000000000000000000000000000000000000000000000000001693636282c66c936044808201949392918390030190829087803b158015612ecd57600080fd5b505af1158015612ee1573d6000803e3d6000fd5b505050506040513d6020811015612ef757600080fd5b505060038101805460ff60a01b1916600160a01b17905560405183907f2ccd633716c6ce12394d1c984ad04b6173d18aedc4f505d1537a94a98a07b6e790600090a260019150505b919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6002546000906001600160a01b031633148015612f88575060145460ff16155b612fc2576040805162461bcd60e51b815260206004808301919091526024820152630858591960e21b604482015290519081900360640190fd5b6001600160a01b03841615801590612fe257506001600160a01b03851615155b613033576040805162461bcd60e51b815260206004820152600660248201527f21706172616d0000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6000601580549050905080836001600160a01b031663f10684546040518163ffffffff1660e01b815260040160206040518083038186803b15801561307757600080fd5b505afa15801561308b573d6000803e3d6000fd5b505050506040513d60208110156130a157600080fd5b50511461310f576040805163fdcb11f760e01b81523060048201526024810183905290516001600160a01b0385169163fdcb11f791604480830192600092919082900301818387803b1580156130f657600080fd5b505af115801561310a573d6000803e3d6000fd5b505050505b6131246001600160a01b0385168460006154b6565b61313a6001600160a01b038516846000196154b6565b6040805160a0810182526001600160a01b0380891680835287821660208085018281528b85168688018181528b87166060808a0182815260006080808d018281526015805460018101825593529c5160049092027f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec47581018054938e166001600160a01b031994851617905597517f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec47689018054918e1691841691909117905594517f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec47788018054918d1691831691909117905590517f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec47890960180549b511515600160a01b0260ff60a01b1997909b169b9091169a909a17949094169790971790975587519081529182019290925280860193909352820185905292517ffdfab2aa700a35855347784fdefdfc91a6d986504c49be9ceca33889c3cd3796929181900390910190a26015546132cd906001615a78565b9695505050505050565b6002546001600160a01b03163314806132fa57506000546001600160a01b031633145b613333576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600280546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f70a64736553c84939f57deec269299882abbbee8dc4f316eccbc6fce57e4d3cf9181900360200190a150565b600b546001600160a01b031681565b6009546001600160a01b031681565b6007546001600160a01b031681565b6000546001600160a01b031681565b6000546001600160a01b0316331461340a576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b821561346357600f54831015801561342457506010548311155b613463576040805162461bcd60e51b815260206004820152600b60248201526a21626f756e64617269657360a81b604482015290519081900360640190fd5b6011839055600880546001600160a01b038085166001600160a01b031992831681179093556009805491851691909216811790915560408051868152602081019390935282810191909152517f0a096c0aecf0f3b11799a2c2e674b04613e0cdec8ce8854d5383cbdbcf10ee289181900360600190a1505050565b61271081565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000546001600160a01b0316331461354f576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600e805482151560ff19909116811790915560408051918252517f490649822a79e4ee774709c12ee8c45dd00c6c82574e88d29a61e0a52cbdeb2b9181900360200190a150565b6000546001600160a01b031633146135dd576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6003546001600160a01b03161561363b576040805162461bcd60e51b815260206004820152600560248201527f217a65726f000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600380546001600160a01b038085166001600160a01b031992831681179093556004805491851691909216811790915560408051928352602083019190915280517f3feb8124746f602faff9d5c0f596521feddb483bb9be2d16645f60d93fdb79b59281900390910190a15050565b6005546060906001600160a01b031633146136f4576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b60006015848154811061370357fe5b600091825260208220600491820201805460028201546040805163d7c01bd760e01b81526001600160a01b0393841695810186905291831660248301525192955092937f00000000000000000000000000000000000000000000000000000000000000009091169263d7c01bd7926044808301939282900301818387803b15801561378d57600080fd5b505af11580156137a1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156137ca57600080fd5b8101908080516040519392919084600160201b8211156137e957600080fd5b9083019060208201858111156137fe57600080fd5b82518660208202830111600160201b8211171561381a57600080fd5b82525081516020918201928201910280838360005b8381101561384757818101518382015260200161382f565b50505050905001604052505050506000845190508067ffffffffffffffff8111801561387257600080fd5b5060405190808252806020026020018201604052801561389c578160200160208202803683370190505b50935060005b818110156139d5576001600160a01b038316600090815260186020526040812087519091908890849081106138d357fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205485828151811061390857fe5b602002602001018181525050600060186000856001600160a01b03166001600160a01b03168152602001908152602001600020600088848151811061394957fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205411156139cd576001600160a01b0383166000908152601860205260408120875182908990859081106139a057fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055505b6001016138a2565b5050505092915050565b60125460009060ff1615613a23576040805162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b604482015290519081900360640190fd5b600060158681548110613a3257fe5b60009182526020909120600360049092020101546001600160a01b0316905033811480613a6957506006546001600160a01b031633145b613aa2576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600086815260136020526040902054849080613abd57506011545b8015613adc57613ad9612710613ad38484615ad5565b90615b2e565b91505b6000888152600d602052604090205480613af95750600c54613b06565b8060011415613b06575060005b6008546000906001600160a01b031615613b2b576008546001600160a01b0316613b4d565b7f00000000000000000000000000000000000000000000000000000000000000005b905060008715613d705760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613bc657600080fd5b505afa158015613bda573d6000803e3d6000fd5b505050506040513d6020811015613bf057600080fd5b5051604080516340c10f1960e01b81523060048201526024810189905290519192506001600160a01b038516916340c10f199160448082019260009290919082900301818387803b158015613c4457600080fd5b505af1158015613c58573d6000803e3d6000fd5b5050600754604080516370a0823160e01b815230600482015290516001600160a01b03928316945063282d3fdf93508f92613d0c9287927f0000000000000000000000000000000000000000000000000000000000000000909216916370a0823191602480820192602092909190829003018186803b158015613cda57600080fd5b505afa158015613cee573d6000803e3d6000fd5b505050506040513d6020811015613d0457600080fd5b505190615a78565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015613d5257600080fd5b505af1158015613d66573d6000803e3d6000fd5b5050505050613fe8565b613d80612710613ad38786615ad5565b9050613d8c8582615a78565b9450816001600160a01b03166340c10f198b876040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015613de557600080fd5b505af1158015613df9573d6000803e3d6000fd5b505050506000811115613fe85760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613e7557600080fd5b505afa158015613e89573d6000803e3d6000fd5b505050506040513d6020811015613e9f57600080fd5b5051604080516340c10f1960e01b81523060048201526024810185905290519192506001600160a01b038516916340c10f199160448082019260009290919082900301818387803b158015613ef357600080fd5b505af1158015613f07573d6000803e3d6000fd5b5050600b54604080516370a0823160e01b815230600482015290516001600160a01b039283169450639feb8f5093507f000000000000000000000000000000000000000000000000000000000000000092613f88928792918516916370a0823191602480820192602092909190829003018186803b158015613cda57600080fd5b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015613fce57600080fd5b505af1158015613fe2573d6000803e3d6000fd5b50505050505b604080518a8152602081018790528082018390529051891515916001600160a01b038d16918e917f6863e961e94fae560d4a81debbe4467e9665cb100d9d63a47fcacc0f6ee56e01919081900360600190a45060019a9950505050505050505050565b6017602052816000526040600020818154811061406457fe5b6000918252602090912001546001600160a01b03169150829050565b6002546000906001600160a01b031633146140ca576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6000601583815481106140d957fe5b6000918252602082206002600490920201908101548154919350614109916001600160a01b0391821691166128d4565b825460028401546040805163a6c3ef8b60e01b81526001600160a01b03938416600482015291831660248301526fffffffffffffffffffffffffffffffff84166044830152519293507f00000000000000000000000000000000000000000000000000000000000000009091169163a6c3ef8b916064808201926020929091908290030181600087803b15801561419f57600080fd5b505af19250505080156141c457506040513d60208110156141bf57600080fd5b505160015b6141cd576141cf565b505b60038201805460ff60a01b1916600160a01b17905560405184907f2ccd633716c6ce12394d1c984ad04b6173d18aedc4f505d1537a94a98a07b6e790600090a25060019392505050565b600c5481565b6000546001600160a01b03163314614266576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6001600160a01b0382166000908152601760209081526040909120825161428f92840190615ebe565b50816001600160a01b03167f03b37a0081df3aff519559174cfbd6b7d31a2f9637ee9e0b9cdc1b823da70e08826040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156142fc5781810151838201526020016142e4565b505050509050019250505060405180910390a25050565b6000546001600160a01b0316331461435a576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600580546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f3ff6a6529320681e8e174fe23dc044d6aa0f2860985ede0b11d95742766e0c8b9181900360200190a150565b6001600160a01b03811660009081526017602052604090205460609015614443576001600160a01b0382166000908152601760209081526040918290208054835181840281018401909452808452909183018282801561443757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311614419575b50505050509050612f3f565b60408051600180825281830190925290602080830190803683370190505090507f00000000000000000000000000000000000000000000000000000000000000008160008151811061449157fe5b60200260200101906001600160a01b031690816001600160a01b031681525050919050565b60145460ff1681565b610bb881565b6000546001600160a01b0316331461450c576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b60005b8351811015611b575783818151811061452457fe5b60200260200101516001600160a01b03166326a5233684846040518363ffffffff1660e01b815260040180836001600160a01b03168152602001821515815260200192505050600060405180830381600087803b15801561458457600080fd5b505af1158015614598573d6000803e3d6000fd5b50506001909201915061450f9050565b6000546001600160a01b031633146145ef576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6000601582815481106145fe57fe5b6000918252602082206004918202018054600282015460408051635c5655a360e01b81526001600160a01b03938416958101959095529082166024850152519194507f00000000000000000000000000000000000000000000000000000000000000001692635c5655a3926044808201939182900301818387803b15801561468557600080fd5b505af1158015614699573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156146c257600080fd5b8101908080516040519392919084600160201b8211156146e157600080fd5b9083019060208201858111156146f657600080fd5b82518660208202830111600160201b8211171561471257600080fd5b82525081516020918201928201910280838360005b8381101561473f578181015183820152602001614727565b5050505091909101604090815286546001600160a01b0316600090815260176020908152919020865161477c97919650910193509150615ebe9050565b5080546001600160a01b0316600081815260176020908152604091829020825182815281549281018390527f03b37a0081df3aff519559174cfbd6b7d31a2f9637ee9e0b9cdc1b823da70e0893919290918291908201908490801561480a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116147ec575b50509250505060405180910390a25050565b6000546001600160a01b03163314806148445750336000908152600a602052604090205460ff165b61487d576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6001600160a01b038216600081815260166020908152604091829020805460ff191685151590811790915582519384529083015280517f08483fb557efc9c2df1bd3b6643408a6c1da02a85d7b84d10933facca2f054929281900390910190a15050565b6001546001600160a01b031681565b6002546001600160a01b031681565b336000908152600a602052604090205460609060ff1661494e576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6001600160a01b03851660009081526016602052604090205460ff166149bb576040805162461bcd60e51b815260206004820152600760248201527f21766f74696e6700000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b61d27f685878787876040518663ffffffff1660e01b815260040180856001600160a01b03168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050955050505050506000604051808303818588803b158015614a6657600080fd5b505af1158015614a7a573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f191682016040908152811015614aa457600080fd5b815160208301805160405192949293830192919084600160201b821115614aca57600080fd5b908301906020820185811115614adf57600080fd5b8251600160201b811182820188101715614af857600080fd5b82525081516020918201929091019080838360005b83811015614b25578181015183820152602001614b0d565b50505050905090810190601f168015614b525780820380516001836020036101000a031916815260200191505b50604052509198975050505050505050565b6000546001600160a01b03163314614bab576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6001600160a01b0382166000818152600a6020908152604091829020805460ff191685151590811790915582519384529083015280517fcb4632aa94a57cabbc5cffdf9f2665ebe316944545b1f942336ef1af7205ea469281900390910190a15050565b6000546001600160a01b03163314614c56576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b815181518114614c96576040805162461bcd60e51b8152602060048083019190915260248201526310b632b760e11b604482015290519081900360640190fd5b60005b81811015611b5757828181518110614cad57fe5b6020026020010151600014614d3557600f54838281518110614ccb57fe5b602002602001015110158015614cf65750601054838281518110614ceb57fe5b602002602001015111155b614d35576040805162461bcd60e51b815260206004820152600b60248201526a21626f756e64617269657360a81b604482015290519081900360640190fd5b828181518110614d4157fe5b602002602001015160136000868481518110614d5957fe5b6020026020010151815260200190815260200160002081905550838181518110614d7f57fe5b60200260200101517f9003d8c07d4c7e4d0072b82a27b1b3212f918279194b26ee52e38b917eb0924f848381518110614db457fe5b60200260200101516040518082815260200191505060405180910390a2600101614c99565b6004546001600160a01b031681565b600a6020526000908152604090205460ff1681565b6015546004805460408051630452a26760e21b81526001600160a01b03878116948201949094529051600094938593169163114a899c91602480830192602092919082900301818787803b158015614e5457600080fd5b505af1158015614e68573d6000803e3d6000fd5b505050506040513d6020811015614e7e57600080fd5b505160035460408051632f7260f160e01b8152600481018690526001600160a01b038085166024830152898116604483015291519394506000939190921691632f7260f191606480830192602092919082900301818787803b158015614ee357600080fd5b505af1158015614ef7573d6000803e3d6000fd5b505050506040513d6020811015614f0d57600080fd5b505190506132cd86868484612f68565b600d6020526000908152604090205481565b600f5481565b60125460ff1615614f76576040805162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b604482015290519081900360640190fd5b6005546001600160a01b03163314614fbd576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b8251825181148015614fcf5750815181145b615009576040805162461bcd60e51b8152602060048083019190915260248201526310b632b760e11b604482015290519081900360640190fd5b6000805b828110156151dc5761503b85828151811061502457fe5b602002602001015183615b9590919063ffffffff16565b915083818151811061504957fe5b6020026020010151156150f05785818151811061506257fe5b60200260200101516001600160a01b03166304d0c2c58887848151811061508557fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156150d357600080fd5b505af11580156150e7573d6000803e3d6000fd5b50505050615134565b6151348682815181106150ff57fe5b602002602001015186838151811061511357fe5b6020026020010151896001600160a01b0316615bef9092919063ffffffff16565b866001600160a01b0316886001600160a01b03168a7f1cae44de2209e08e758dcf27f2f188e08823def8d2fd696825fdb3297ab1522288858151811061517657fe5b60200260200101518a868151811061518a57fe5b602002602001015189878151811061519e57fe5b602002602001015160405180848152602001836001600160a01b031681526020018215158152602001935050505060405180910390a460010161500d565b50856001600160a01b0316876001600160a01b0316897fbfae22d78b70dbd404b2f03b2a20d9b182e9e96bc4ed0da9271d50f60299c029846040518082815260200191505060405180910390a45050505050505050565b60608061523f836143ae565b80519091508067ffffffffffffffff8111801561525b57600080fd5b50604051908082528060200260200182016040528015615285578160200160208202803683370190505b50925060005b818110156153ec5760008382815181106152a157fe5b60200260200101516001600160a01b03166370a082317f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561531557600080fd5b505afa158015615329573d6000803e3d6000fd5b505050506040513d602081101561533f57600080fd5b505184519091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169085908490811061537d57fe5b60200260200101516001600160a01b031614156153cb576153c8816001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001631615b95565b90505b808583815181106153d857fe5b60209081029190910101525060010161528b565b505050919050565b6000546001600160a01b0316331461543b576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b610bb881111561547b576040805162461bcd60e51b8152602060048083019190915260248201526307cdac2f60e31b604482015290519081900360640190fd5b600c8190556040805182815290517faa05eb3e1da9d3f481c26c4083425708104d8acf8f72369ab94ad2f7148ba99b9181900360200190a150565b80158061553c575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b15801561550e57600080fd5b505afa158015615522573d6000803e3d6000fd5b505050506040513d602081101561553857600080fd5b5051155b6155775760405162461bcd60e51b8152600401808060200182810382526036815260200180615f8e6036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052612b05908490615c3d565b60125460ff161561560a576040805162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b604482015290519081900360640190fd5b60006015858154811061561957fe5b60009182526020822060049182020180546002820154600183015460408051632770a7eb60e21b81526001600160a01b038b811697820197909752602481018c90529051949750928516959185169416928392639dc29fac92604480830193919282900301818387803b15801561568f57600080fd5b505af11580156156a3573d6000803e3d6000fd5b505050506003840154600160a01b900460ff166157f95760606156c584615233565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a6c3ef8b85858b6040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b031681526020018281526020019350505050602060405180830381600087803b15801561574f57600080fd5b505af1158015615763573d6000803e3d6000fd5b505050506040513d602081101561577957600080fd5b50615786905084826158b1565b600e5460ff16156157f7576005546040805163cc956f3f60e01b8152600481018c905290516001600160a01b039092169163cc956f3f9160248082019260009290919082900301818387803b1580156157de57600080fd5b505af11580156157f2573d6000803e3d6000fd5b505050505b505b61580d6001600160a01b0384168689615bef565b60408051888152905189916001600160a01b038816917f92ccf450a286a957af52509bc1c9939d1a6a481783e142e41e2499f0bb66ebc69181900360200190a35050505050505050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611b57908590615c3d565b60606158bc836143ae565b825190915060005b81811015611a145760008382815181106158da57fe5b602002602001015190506000816001600160a01b03166370a082317f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561595357600080fd5b505afa158015615967573d6000803e3d6000fd5b505050506040513d602081101561597d57600080fd5b505190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0390811690831614156159ed576159ea816001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001631615b95565b90505b615a42615a168785815181106159ff57fe5b602002602001015183615a7890919063ffffffff16565b6001600160a01b03808a1660009081526018602090815260408083209388168352929052205490615b95565b6001600160a01b0380891660009081526018602090815260408083209690931682529490945290922091909155506001016158c4565b600082821115615acf576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600082615ae457506000612421565b82820282848281615af157fe5b0414611d945760405162461bcd60e51b8152600401808060200182810382526021815260200180615f436021913960400191505060405180910390fd5b6000808211615b84576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381615b8d57fe5b049392505050565b600082820183811015611d94576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612b059084905b6060615c92826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316615cee9092919063ffffffff16565b805190915015612b0557808060200190516020811015615cb157600080fd5b5051612b055760405162461bcd60e51b815260040180806020018281038252602a815260200180615f64602a913960400191505060405180910390fd5b6060612d0e848460008585615d0285615e14565b615d53576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310615d925780518252601f199092019160209182019101615d73565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114615df4576040519150601f19603f3d011682016040523d82523d6000602084013e615df9565b606091505b5091509150615e09828286615e1a565b979650505050505050565b3b151590565b60608315615e29575081611d94565b825115615e395782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015615e83578181015183820152602001615e6b565b50505050905090810190601f168015615eb05780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b828054828255906000526020600020908101928215615f13579160200282015b82811115615f1357825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190615ede565b50615f1f929150615f23565b5090565b5b80821115615f1f5780546001600160a01b0319168155600101615f2456fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a164736f6c634300060c000a00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec100000000000000000000000096ff1506f7ac06b95486e09529c7efb9dfef601e000000000000000000000000fa66478296841b636d72a3b31da9cdc77e902bf1000000000000000000000000c0b314a8c08637685fc3dafc477b92028c540cfb000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000000003a98

Deployed Bytecode

0x60806040526004361061047e5760003560e01c80637aef67151161025e578063bf86d69011610143578063e1024932116100bb578063ebe537741161008a578063edc431591161006f578063edc43159146115d7578063f6ed2017146117a9578063fb538246146117dc5761047e565b8063ebe5377414611598578063ed000462146115c25761047e565b8063e1024932146113e5578063e77772fe14611515578063ea6048451461152a578063eb511dd41461155d5761047e565b8063d055eac911610112578063dc4c90d3116100f7578063dc4c90d31461129d578063deaeacfd146112b2578063e0d85f1f146113aa5761047e565b8063d055eac91461124d578063d0fb0203146112885761047e565b8063bf86d6901461113b578063c7ed531214611150578063ca412f9214611165578063cb9dfb9c146112235761047e565b80639aa4c2e5116101d6578063a63634a1116101a5578063adf52fd41161018a578063adf52fd414611017578063b9b98b54146110d5578063be165abd146111085761047e565b8063a63634a114610fd8578063a9ffa1ca146110025761047e565b80639aa4c2e514610e185780639efe5d2014610e53578063a3ea45cc14610f58578063a40018ab14610f9f5761047e565b80638da5cb5b1161022d578063918f867411610212578063918f867414610dc2578063923c1d6114610dd757806394e70d7814610dec5761047e565b80638da5cb5b14610d6c5780638fc0b68514610d815761047e565b80637aef671514610cfa5780637b3370ce14610d2d5780637e4edf7014610d425780638d68f9ff14610d575761047e565b806328dbdff11161038457806343a0d066116102fc578063525c42d8116102cb57806360cafe84116102b057806360cafe8414610c705780636a4874a114610c9a5780636ab94fd614610caf5761047e565b8063525c42d814610c315780635c975abb14610c5b5761047e565b806343a0d06614610b81578063441a3e7014610bb9578063472d35b914610be95780634d8527b914610c1c5761047e565b8063354af919116103535780633a0bcd20116103385780633a0bcd2014610b425780633f9bcc6c14610b575780633fc8cef314610b6c5761047e565b8063354af91914610af2578063390e75f914610b075761047e565b806328dbdff114610976578063293932c014610a4a5780632ada885a14610aaa5780632ee9808d14610abf5761047e565b80631526fe27116104175780631ba980b3116103e657806321f314ca116103cb57806321f314ca146109135780632249f6131461094c578063245e4bf0146109615761047e565b80631ba980b3146108cc5780631fbd8974146108e15761047e565b80631526fe27146107c3578063168d3d6e1461082857806316c38b3c1461085957806317baa443146108855761047e565b8063099ae20811610453578063099ae208146106d757806312425eb51461071e57806313af40351461075157806314cd70e4146107845761047e565b806232880814610483578062bfa239146104c0578063081e3eda1461058057806309771b95146105a7575b600080fd5b34801561048f57600080fd5b506104be600480360360408110156104a657600080fd5b506001600160a01b0381358116916020013516611806565b005b3480156104cc57600080fd5b506104be600480360360608110156104e357600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561050d57600080fd5b82018360208201111561051f57600080fd5b803590602001918460208302840111600160201b8311171561054057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550509135925061196f915050565b34801561058c57600080fd5b50610595611a1b565b60408051918252519081900360200190f35b3480156105b357600080fd5b506104be600480360360408110156105ca57600080fd5b810190602081018135600160201b8111156105e457600080fd5b8201836020820111156105f657600080fd5b803590602001918460208302840111600160201b8311171561061757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561066657600080fd5b82018360208201111561067857600080fd5b803590602001918460208302840111600160201b8311171561069957600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611a21945050505050565b3480156106e357600080fd5b5061070a600480360360208110156106fa57600080fd5b50356001600160a01b0316611b5d565b604080519115158252519081900360200190f35b34801561072a57600080fd5b506104be6004803603602081101561074157600080fd5b50356001600160a01b0316611b72565b34801561075d57600080fd5b506104be6004803603602081101561077457600080fd5b50356001600160a01b0316611c7c565b34801561079057600080fd5b5061070a600480360360608110156107a757600080fd5b50803590602081013590604001356001600160a01b0316611d17565b3480156107cf57600080fd5b506107ed600480360360208110156107e657600080fd5b5035611d9b565b604080516001600160a01b03968716815294861660208601529285168484015293166060830152911515608082015290519081900360a00190f35b34801561083457600080fd5b5061083d611dee565b604080516001600160a01b039092168252519081900360200190f35b34801561086557600080fd5b506104be6004803603602081101561087c57600080fd5b50351515611dfd565b34801561089157600080fd5b5061070a600480360360808110156108a857600080fd5b508035906020810135906040810135151590606001356001600160a01b0316611e8b565b3480156108d857600080fd5b5061083d612324565b3480156108ed57600080fd5b5061070a6004803603604081101561090457600080fd5b50803590602001351515612348565b34801561091f57600080fd5b5061070a6004803603604081101561093657600080fd5b506001600160a01b038135169060200135612427565b34801561095857600080fd5b5061083d612548565b34801561096d57600080fd5b5061083d612557565b34801561098257600080fd5b506104be6004803603606081101561099957600080fd5b810190602081018135600160201b8111156109b357600080fd5b8201836020820111156109c557600080fd5b803590602001918460208302840111600160201b831117156109e657600080fd5b919390929091602081019035600160201b811115610a0357600080fd5b820183602082011115610a1557600080fd5b803590602001918460208302840111600160201b83111715610a3657600080fd5b9193509150356001600160a01b0316612566565b348015610a5657600080fd5b50610a8560048036036040811015610a6d57600080fd5b506001600160a01b03813581169160200135166128d4565b604080516fffffffffffffffffffffffffffffffff9092168252519081900360200190f35b348015610ab657600080fd5b5061083d612a29565b348015610acb57600080fd5b506104be60048036036020811015610ae257600080fd5b50356001600160a01b0316612a38565b348015610afe57600080fd5b506104be612b0a565b348015610b1357600080fd5b5061059560048036036040811015610b2a57600080fd5b506001600160a01b0381358116916020013516612cb0565b348015610b4e57600080fd5b5061070a612ccd565b348015610b6357600080fd5b50610595612cd6565b348015610b7857600080fd5b5061083d612cdc565b348015610b8d57600080fd5b5061070a60048036036060811015610ba457600080fd5b50803590602081013590604001351515612d00565b348015610bc557600080fd5b5061070a60048036036040811015610bdc57600080fd5b5080359060200135612d16565b348015610bf557600080fd5b506104be60048036036020811015610c0c57600080fd5b50356001600160a01b0316612d2d565b348015610c2857600080fd5b50610595612dc8565b348015610c3d57600080fd5b5061059560048036036020811015610c5457600080fd5b5035612dce565b348015610c6757600080fd5b5061070a612de0565b348015610c7c57600080fd5b5061070a60048036036020811015610c9357600080fd5b5035612de9565b348015610ca657600080fd5b5061083d612f44565b348015610cbb57600080fd5b5061059560048036036080811015610cd257600080fd5b506001600160a01b038135811691602081013582169160408201358116916060013516612f68565b348015610d0657600080fd5b506104be60048036036020811015610d1d57600080fd5b50356001600160a01b03166132d7565b348015610d3957600080fd5b5061083d613387565b348015610d4e57600080fd5b5061083d613396565b348015610d6357600080fd5b5061083d6133a5565b348015610d7857600080fd5b5061083d6133b4565b348015610d8d57600080fd5b506104be60048036036060811015610da457600080fd5b508035906001600160a01b03602082013581169160400135166133c3565b348015610dce57600080fd5b506105956134de565b348015610de357600080fd5b5061083d6134e4565b348015610df857600080fd5b506104be60048036036020811015610e0f57600080fd5b50351515613508565b348015610e2457600080fd5b506104be60048036036040811015610e3b57600080fd5b506001600160a01b0381358116916020013516613596565b348015610e5f57600080fd5b50610f0860048036036040811015610e7657600080fd5b81359190810190604081016020820135600160201b811115610e9757600080fd5b820183602082011115610ea957600080fd5b803590602001918460208302840111600160201b83111715610eca57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506136aa945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610f44578181015183820152602001610f2c565b505050509050019250505060405180910390f35b348015610f6457600080fd5b5061070a60048036036080811015610f7b57600080fd5b508035906001600160a01b03602082013516906040810135906060013515156139df565b348015610fab57600080fd5b5061083d60048036036040811015610fc257600080fd5b506001600160a01b03813516906020013561404b565b348015610fe457600080fd5b5061070a60048036036020811015610ffb57600080fd5b5035614080565b34801561100e57600080fd5b50610595614219565b34801561102357600080fd5b506104be6004803603604081101561103a57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561106457600080fd5b82018360208201111561107657600080fd5b803590602001918460208302840111600160201b8311171561109757600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061421f945050505050565b3480156110e157600080fd5b506104be600480360360208110156110f857600080fd5b50356001600160a01b0316614313565b34801561111457600080fd5b50610f086004803603602081101561112b57600080fd5b50356001600160a01b03166143ae565b34801561114757600080fd5b5061070a6144b6565b34801561115c57600080fd5b506105956144bf565b34801561117157600080fd5b506104be6004803603606081101561118857600080fd5b810190602081018135600160201b8111156111a257600080fd5b8201836020820111156111b457600080fd5b803590602001918460208302840111600160201b831117156111d557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550506001600160a01b03833516935050506020013515156144c5565b34801561122f57600080fd5b506104be6004803603602081101561124657600080fd5b50356145a8565b34801561125957600080fd5b506104be6004803603604081101561127057600080fd5b506001600160a01b038135169060200135151561481c565b34801561129457600080fd5b5061083d6148e1565b3480156112a957600080fd5b5061083d6148f0565b611335600480360360608110156112c857600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b8111156112f757600080fd5b82018360208201111561130957600080fd5b803590602001918460018302840111600160201b8311171561132a57600080fd5b5090925090506148ff565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561136f578181015183820152602001611357565b50505050905090810190601f16801561139c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156113b657600080fd5b506104be600480360360408110156113cd57600080fd5b506001600160a01b0381351690602001351515614b64565b3480156113f157600080fd5b506104be6004803603604081101561140857600080fd5b810190602081018135600160201b81111561142257600080fd5b82018360208201111561143457600080fd5b803590602001918460208302840111600160201b8311171561145557600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156114a457600080fd5b8201836020820111156114b657600080fd5b803590602001918460208302840111600160201b831117156114d757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550614c0f945050505050565b34801561152157600080fd5b5061083d614dd9565b34801561153657600080fd5b5061070a6004803603602081101561154d57600080fd5b50356001600160a01b0316614de8565b34801561156957600080fd5b506105956004803603604081101561158057600080fd5b506001600160a01b0381358116916020013516614dfd565b3480156115a457600080fd5b50610595600480360360208110156115bb57600080fd5b5035614f1d565b3480156115ce57600080fd5b50610595614f2f565b3480156115e357600080fd5b506104be600480360360c08110156115fa57600080fd5b8135916001600160a01b03602082013581169260408301359091169190810190608081016060820135600160201b81111561163457600080fd5b82018360208201111561164657600080fd5b803590602001918460208302840111600160201b8311171561166757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156116b657600080fd5b8201836020820111156116c857600080fd5b803590602001918460208302840111600160201b831117156116e957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561173857600080fd5b82018360208201111561174a57600080fd5b803590602001918460208302840111600160201b8311171561176b57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550614f35945050505050565b3480156117b557600080fd5b50610f08600480360360208110156117cc57600080fd5b50356001600160a01b0316615233565b3480156117e857600080fd5b506104be600480360360208110156117ff57600080fd5b50356153f4565b6000546001600160a01b0316331461184d576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6006546001600160a01b031661196b57600680546001600160a01b038085166001600160a01b03199283161790925560078054848416921691909117908190556040805163095ea7b360e01b815291831660048301526000196024830152517f000000000000000000000000fa66478296841b636d72a3b31da9cdc77e902bf19092169163095ea7b3916044808201926020929091908290030181600087803b1580156118f957600080fd5b505af115801561190d573d6000803e3d6000fd5b505050506040513d602081101561192357600080fd5b5050604080516001600160a01b0380851682528316602082015281517fd612424d9ffea115aebe524be81722e3605348e7c2777bb90c3a998b1883e68b929181900390910190a15b5050565b6005546001600160a01b031633146119b6576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b815160005b81811015611a14576119f58560008684815181106119d557fe5b60200260200101516001600160a01b03166154b69092919063ffffffff16565b8215611a0c57611a0c85848684815181106119d557fe5b6001016119bb565b5050505050565b60155490565b6000546001600160a01b03163314611a68576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b815181518114611aa8576040805162461bcd60e51b8152602060048083019190915260248201526310b632b760e11b604482015290519081900360640190fd5b60005b81811015611b5757828181518110611abf57fe5b6020026020010151600d6000868481518110611ad757fe5b6020026020010151815260200190815260200160002081905550838181518110611afd57fe5b60200260200101517f1c73e186fc4df717b5c7115e26b47995d803602fdad67f60a43f4118cf4432cd848381518110611b3257fe5b60200260200101516040518082815260200191505060405180910390a2600101611aab565b50505050565b60166020526000908152604090205460ff1681565b6000546001600160a01b03163314611bb9576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600b80546001600160a01b0319166001600160a01b0383811691909117909155611c07907f000000000000000000000000fa66478296841b636d72a3b31da9cdc77e902bf1168260006154b6565b611c3d6001600160a01b037f000000000000000000000000fa66478296841b636d72a3b31da9cdc77e902bf116826000196154b6565b604080516001600160a01b038316815290517fbb9094bc5ccbce4f74fb9568f8ff632f531c31d68138e511d46837e17aa1a7829181900360200190a150565b6000546001600160a01b03163314611cc3576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600080546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b9181900360200190a150565b60008060158581548110611d2757fe5b60009182526020909120600360049092020101546001600160a01b03169050338114611d82576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b611d8e858533866155c9565b60019150505b9392505050565b60158181548110611da857fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b03928316945090821692821691811690600160a01b900460ff1685565b6006546001600160a01b031681565b6000546001600160a01b03163314611e44576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6012805482151560ff19909116811790915560408051918252517f3c70af01296aef045b2f5c9d3c30b05d4428fd257145b9c7fcd76418e65b59809181900360200190a150565b60145460009060ff1615611ee6576040805162461bcd60e51b815260206004820152600860248201527f73687574646f776e000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60125460ff1615611f27576040805162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b604482015290519081900360640190fd5b600060158681548110611f3657fe5b600091825260209091206004909102016003810154909150600160a01b900460ff1615611faa576040805162461bcd60e51b815260206004820152600660248201527f636c6f7365640000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b80546001600160a01b0316611fe181337f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec189615857565b60028201546001600160a01b031680612041576040805162461bcd60e51b815260206004820152600660248201527f2167617567650000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b606061204c83615233565b90507f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec16001600160a01b031663f9609f0884846040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b0316815260200192505050602060405180830381600087803b1580156120ce57600080fd5b505af11580156120e2573d6000803e3d6000fd5b505050506040513d60208110156120f857600080fd5b50612105905083826158b1565b600e5460ff161561217657600554604080516347f084c160e11b8152600481018c905290516001600160a01b0390921691638fe109829160248082019260009290919082900301818387803b15801561215d57600080fd5b505af1158015612171573d6000803e3d6000fd5b505050505b60018401546001600160a01b0316871561226457604080516340c10f1960e01b8152306004820152602481018b905290516001600160a01b038316916340c10f1991604480830192600092919082900301818387803b1580156121d857600080fd5b505af11580156121ec573d6000803e3d6000fd5b505050506003850154604080516305dc812160e31b81526001600160a01b038a81166004830152602482018d905291519190921691632ee4090891604480830192600092919082900301818387803b15801561224757600080fd5b505af115801561225b573d6000803e3d6000fd5b505050506122d4565b806001600160a01b03166340c10f19888b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156122bb57600080fd5b505af11580156122cf573d6000803e3d6000fd5b505050505b604080518a815290518b916001600160a01b038a16917f73a19dd210f1a7f902193214c0ee91dd35ee5b4d920cba8d519eca65a7b488ca9181900360200190a35060019998505050505050505050565b7f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec181565b336000908152600a602052604081205460ff16612394576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b7f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec16001600160a01b0316631fbd897484846040518363ffffffff1660e01b815260040180838152602001821515815260200192505050600060405180830381600087803b15801561240457600080fd5b505af1158015612418573d6000803e3d6000fd5b50505050600190505b92915050565b6009546000906001600160a01b03163314612471576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b7f000000000000000000000000fa66478296841b636d72a3b31da9cdc77e902bf16001600160a01b03166340c10f1984846040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156124e857600080fd5b505af11580156124fc573d6000803e3d6000fd5b50506040805185815290516001600160a01b03871693507fc782e36a0e2d25f83f7caeaaa575d3924bee6885514d62247e6ed913d282b5a292509081900360200190a250600192915050565b6005546001600160a01b031681565b6003546001600160a01b031681565b6000546001600160a01b031633146125ad576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b60145460ff16612604576040805162461bcd60e51b815260206004820152600960248201527f2173687574646f776e0000000000000000000000000000000000000000000000604482015290519081900360640190fd5b83828114612659576040805162461bcd60e51b815260206004820152600760248201527f216c656e67746800000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60005b818110156128cb57600087878381811061267257fe5b905060200201356001600160a01b03166001600160a01b03161415612696576128c3565b8686828181106126a257fe5b905060200201356001600160a01b03166001600160a01b031663fdcb11f7848787858181106126cd57fe5b905060200201356040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561271a57600080fd5b505af115801561272e573d6000803e3d6000fd5b50506006546001600160a01b03169150889050878381811061274c57fe5b905060200201356001600160a01b03166001600160a01b03161461285457600087878381811061277857fe5b905060200201356001600160a01b03166001600160a01b03166372f702f36040518163ffffffff1660e01b815260040160206040518083038186803b1580156127c057600080fd5b505afa1580156127d4573d6000803e3d6000fd5b505050506040513d60208110156127ea57600080fd5b50516040805163ac7475ed60e01b81526001600160a01b03878116600483015291519293509083169163ac7475ed9160248082019260009290919082900301818387803b15801561283a57600080fd5b505af115801561284e573d6000803e3d6000fd5b50505050505b84848281811061286057fe5b90506020020135836001600160a01b031688888481811061287d57fe5b905060200201356001600160a01b03166001600160a01b03167ff40c7a0f343f6610bca64a1e012d50397f9a0b69350e567256694bcafc16239060405160405180910390a45b60010161265c565b50505050505050565b6000807f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec16001600160a01b031663bca8b4d185856040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561295557600080fd5b505afa158015612969573d6000803e3d6000fd5b505050506040513d602081101561297f57600080fd5b5051604080516393f1a40b60e01b8152600481018390526001600160a01b037f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec1811660248301529151929350908616916393f1a40b91604480820192608092909190829003018186803b1580156129f557600080fd5b505afa158015612a09573d6000803e3d6000fd5b505050506040513d6080811015612a1f57600080fd5b5051949350505050565b6008546001600160a01b031681565b6005546001600160a01b03163314612a7f576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b60155460005b81811015612b0557612ac460158281548110612a9d57fe5b600091825260208220600360049092020101546001600160a01b03868116929116906154b6565b612afd60158281548110612ad457fe5b60009182526020909120600360049092020101546001600160a01b0385811691166000196154b6565b600101612a85565b505050565b6000546001600160a01b03163314612b51576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6014805460ff1916600117905560005b601554811015612cad57600060158281548110612b7a57fe5b906000526020600020906004020190508060030160149054906101000a900460ff1615612ba75750612ca5565b60028101548154600091612bc7916001600160a01b0391821691166128d4565b825460028401546040805163a6c3ef8b60e01b81526001600160a01b03938416600482015291831660248301526fffffffffffffffffffffffffffffffff84166044830152519293507f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec19091169163a6c3ef8b916064808201926020929091908290030181600087803b158015612c5d57600080fd5b505af1925050508015612c8257506040513d6020811015612c7d57600080fd5b505160015b612c8b57612ca2565b5060038201805460ff60a01b1916600160a01b1790555b50505b600101612b61565b50565b601860209081526000928352604080842090915290825290205481565b600e5460ff1681565b60115481565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6000612d0e84848433611e8b565b949350505050565b6000612d24838333336155c9565b50600192915050565b6000546001600160a01b03163314612d74576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517fe45f5e140399b0a7e12971ab020724b828fbed8ac408c420884dc7d1bbe506b49181900360200190a150565b60105481565b60136020526000908152604090205481565b60125460ff1681565b6002546000906001600160a01b03163314612e33576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600060158381548110612e4257fe5b6000918252602080832060049283020180546002820154604080516318a0b19b60e21b81526001600160a01b03938416968101969096529082166024860152519195507f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec11693636282c66c936044808201949392918390030190829087803b158015612ecd57600080fd5b505af1158015612ee1573d6000803e3d6000fd5b505050506040513d6020811015612ef757600080fd5b505060038101805460ff60a01b1916600160a01b17905560405183907f2ccd633716c6ce12394d1c984ad04b6173d18aedc4f505d1537a94a98a07b6e790600090a260019150505b919050565b7f000000000000000000000000c0b314a8c08637685fc3dafc477b92028c540cfb81565b6002546000906001600160a01b031633148015612f88575060145460ff16155b612fc2576040805162461bcd60e51b815260206004808301919091526024820152630858591960e21b604482015290519081900360640190fd5b6001600160a01b03841615801590612fe257506001600160a01b03851615155b613033576040805162461bcd60e51b815260206004820152600660248201527f21706172616d0000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6000601580549050905080836001600160a01b031663f10684546040518163ffffffff1660e01b815260040160206040518083038186803b15801561307757600080fd5b505afa15801561308b573d6000803e3d6000fd5b505050506040513d60208110156130a157600080fd5b50511461310f576040805163fdcb11f760e01b81523060048201526024810183905290516001600160a01b0385169163fdcb11f791604480830192600092919082900301818387803b1580156130f657600080fd5b505af115801561310a573d6000803e3d6000fd5b505050505b6131246001600160a01b0385168460006154b6565b61313a6001600160a01b038516846000196154b6565b6040805160a0810182526001600160a01b0380891680835287821660208085018281528b85168688018181528b87166060808a0182815260006080808d018281526015805460018101825593529c5160049092027f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec47581018054938e166001600160a01b031994851617905597517f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec47689018054918e1691841691909117905594517f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec47788018054918d1691831691909117905590517f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec47890960180549b511515600160a01b0260ff60a01b1997909b169b9091169a909a17949094169790971790975587519081529182019290925280860193909352820185905292517ffdfab2aa700a35855347784fdefdfc91a6d986504c49be9ceca33889c3cd3796929181900390910190a26015546132cd906001615a78565b9695505050505050565b6002546001600160a01b03163314806132fa57506000546001600160a01b031633145b613333576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600280546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f70a64736553c84939f57deec269299882abbbee8dc4f316eccbc6fce57e4d3cf9181900360200190a150565b600b546001600160a01b031681565b6009546001600160a01b031681565b6007546001600160a01b031681565b6000546001600160a01b031681565b6000546001600160a01b0316331461340a576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b821561346357600f54831015801561342457506010548311155b613463576040805162461bcd60e51b815260206004820152600b60248201526a21626f756e64617269657360a81b604482015290519081900360640190fd5b6011839055600880546001600160a01b038085166001600160a01b031992831681179093556009805491851691909216811790915560408051868152602081019390935282810191909152517f0a096c0aecf0f3b11799a2c2e674b04613e0cdec8ce8854d5383cbdbcf10ee289181900360600190a1505050565b61271081565b7f000000000000000000000000fa66478296841b636d72a3b31da9cdc77e902bf181565b6000546001600160a01b0316331461354f576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600e805482151560ff19909116811790915560408051918252517f490649822a79e4ee774709c12ee8c45dd00c6c82574e88d29a61e0a52cbdeb2b9181900360200190a150565b6000546001600160a01b031633146135dd576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6003546001600160a01b03161561363b576040805162461bcd60e51b815260206004820152600560248201527f217a65726f000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600380546001600160a01b038085166001600160a01b031992831681179093556004805491851691909216811790915560408051928352602083019190915280517f3feb8124746f602faff9d5c0f596521feddb483bb9be2d16645f60d93fdb79b59281900390910190a15050565b6005546060906001600160a01b031633146136f4576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b60006015848154811061370357fe5b600091825260208220600491820201805460028201546040805163d7c01bd760e01b81526001600160a01b0393841695810186905291831660248301525192955092937f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec19091169263d7c01bd7926044808301939282900301818387803b15801561378d57600080fd5b505af11580156137a1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156137ca57600080fd5b8101908080516040519392919084600160201b8211156137e957600080fd5b9083019060208201858111156137fe57600080fd5b82518660208202830111600160201b8211171561381a57600080fd5b82525081516020918201928201910280838360005b8381101561384757818101518382015260200161382f565b50505050905001604052505050506000845190508067ffffffffffffffff8111801561387257600080fd5b5060405190808252806020026020018201604052801561389c578160200160208202803683370190505b50935060005b818110156139d5576001600160a01b038316600090815260186020526040812087519091908890849081106138d357fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205485828151811061390857fe5b602002602001018181525050600060186000856001600160a01b03166001600160a01b03168152602001908152602001600020600088848151811061394957fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205411156139cd576001600160a01b0383166000908152601860205260408120875182908990859081106139a057fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055505b6001016138a2565b5050505092915050565b60125460009060ff1615613a23576040805162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b604482015290519081900360640190fd5b600060158681548110613a3257fe5b60009182526020909120600360049092020101546001600160a01b0316905033811480613a6957506006546001600160a01b031633145b613aa2576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600086815260136020526040902054849080613abd57506011545b8015613adc57613ad9612710613ad38484615ad5565b90615b2e565b91505b6000888152600d602052604090205480613af95750600c54613b06565b8060011415613b06575060005b6008546000906001600160a01b031615613b2b576008546001600160a01b0316613b4d565b7f000000000000000000000000fa66478296841b636d72a3b31da9cdc77e902bf15b905060008715613d705760007f000000000000000000000000fa66478296841b636d72a3b31da9cdc77e902bf16001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613bc657600080fd5b505afa158015613bda573d6000803e3d6000fd5b505050506040513d6020811015613bf057600080fd5b5051604080516340c10f1960e01b81523060048201526024810189905290519192506001600160a01b038516916340c10f199160448082019260009290919082900301818387803b158015613c4457600080fd5b505af1158015613c58573d6000803e3d6000fd5b5050600754604080516370a0823160e01b815230600482015290516001600160a01b03928316945063282d3fdf93508f92613d0c9287927f000000000000000000000000fa66478296841b636d72a3b31da9cdc77e902bf1909216916370a0823191602480820192602092909190829003018186803b158015613cda57600080fd5b505afa158015613cee573d6000803e3d6000fd5b505050506040513d6020811015613d0457600080fd5b505190615a78565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015613d5257600080fd5b505af1158015613d66573d6000803e3d6000fd5b5050505050613fe8565b613d80612710613ad38786615ad5565b9050613d8c8582615a78565b9450816001600160a01b03166340c10f198b876040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015613de557600080fd5b505af1158015613df9573d6000803e3d6000fd5b505050506000811115613fe85760007f000000000000000000000000fa66478296841b636d72a3b31da9cdc77e902bf16001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613e7557600080fd5b505afa158015613e89573d6000803e3d6000fd5b505050506040513d6020811015613e9f57600080fd5b5051604080516340c10f1960e01b81523060048201526024810185905290519192506001600160a01b038516916340c10f199160448082019260009290919082900301818387803b158015613ef357600080fd5b505af1158015613f07573d6000803e3d6000fd5b5050600b54604080516370a0823160e01b815230600482015290516001600160a01b039283169450639feb8f5093507f000000000000000000000000fa66478296841b636d72a3b31da9cdc77e902bf192613f88928792918516916370a0823191602480820192602092909190829003018186803b158015613cda57600080fd5b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015613fce57600080fd5b505af1158015613fe2573d6000803e3d6000fd5b50505050505b604080518a8152602081018790528082018390529051891515916001600160a01b038d16918e917f6863e961e94fae560d4a81debbe4467e9665cb100d9d63a47fcacc0f6ee56e01919081900360600190a45060019a9950505050505050505050565b6017602052816000526040600020818154811061406457fe5b6000918252602090912001546001600160a01b03169150829050565b6002546000906001600160a01b031633146140ca576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6000601583815481106140d957fe5b6000918252602082206002600490920201908101548154919350614109916001600160a01b0391821691166128d4565b825460028401546040805163a6c3ef8b60e01b81526001600160a01b03938416600482015291831660248301526fffffffffffffffffffffffffffffffff84166044830152519293507f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec19091169163a6c3ef8b916064808201926020929091908290030181600087803b15801561419f57600080fd5b505af19250505080156141c457506040513d60208110156141bf57600080fd5b505160015b6141cd576141cf565b505b60038201805460ff60a01b1916600160a01b17905560405184907f2ccd633716c6ce12394d1c984ad04b6173d18aedc4f505d1537a94a98a07b6e790600090a25060019392505050565b600c5481565b6000546001600160a01b03163314614266576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6001600160a01b0382166000908152601760209081526040909120825161428f92840190615ebe565b50816001600160a01b03167f03b37a0081df3aff519559174cfbd6b7d31a2f9637ee9e0b9cdc1b823da70e08826040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156142fc5781810151838201526020016142e4565b505050509050019250505060405180910390a25050565b6000546001600160a01b0316331461435a576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b600580546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f3ff6a6529320681e8e174fe23dc044d6aa0f2860985ede0b11d95742766e0c8b9181900360200190a150565b6001600160a01b03811660009081526017602052604090205460609015614443576001600160a01b0382166000908152601760209081526040918290208054835181840281018401909452808452909183018282801561443757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311614419575b50505050509050612f3f565b60408051600180825281830190925290602080830190803683370190505090507f000000000000000000000000c0b314a8c08637685fc3dafc477b92028c540cfb8160008151811061449157fe5b60200260200101906001600160a01b031690816001600160a01b031681525050919050565b60145460ff1681565b610bb881565b6000546001600160a01b0316331461450c576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b60005b8351811015611b575783818151811061452457fe5b60200260200101516001600160a01b03166326a5233684846040518363ffffffff1660e01b815260040180836001600160a01b03168152602001821515815260200192505050600060405180830381600087803b15801561458457600080fd5b505af1158015614598573d6000803e3d6000fd5b50506001909201915061450f9050565b6000546001600160a01b031633146145ef576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6000601582815481106145fe57fe5b6000918252602082206004918202018054600282015460408051635c5655a360e01b81526001600160a01b03938416958101959095529082166024850152519194507f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec11692635c5655a3926044808201939182900301818387803b15801561468557600080fd5b505af1158015614699573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156146c257600080fd5b8101908080516040519392919084600160201b8211156146e157600080fd5b9083019060208201858111156146f657600080fd5b82518660208202830111600160201b8211171561471257600080fd5b82525081516020918201928201910280838360005b8381101561473f578181015183820152602001614727565b5050505091909101604090815286546001600160a01b0316600090815260176020908152919020865161477c97919650910193509150615ebe9050565b5080546001600160a01b0316600081815260176020908152604091829020825182815281549281018390527f03b37a0081df3aff519559174cfbd6b7d31a2f9637ee9e0b9cdc1b823da70e0893919290918291908201908490801561480a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116147ec575b50509250505060405180910390a25050565b6000546001600160a01b03163314806148445750336000908152600a602052604090205460ff165b61487d576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6001600160a01b038216600081815260166020908152604091829020805460ff191685151590811790915582519384529083015280517f08483fb557efc9c2df1bd3b6643408a6c1da02a85d7b84d10933facca2f054929281900390910190a15050565b6001546001600160a01b031681565b6002546001600160a01b031681565b336000908152600a602052604090205460609060ff1661494e576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6001600160a01b03851660009081526016602052604090205460ff166149bb576040805162461bcd60e51b815260206004820152600760248201527f21766f74696e6700000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b7f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec16001600160a01b031663b61d27f685878787876040518663ffffffff1660e01b815260040180856001600160a01b03168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050955050505050506000604051808303818588803b158015614a6657600080fd5b505af1158015614a7a573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f191682016040908152811015614aa457600080fd5b815160208301805160405192949293830192919084600160201b821115614aca57600080fd5b908301906020820185811115614adf57600080fd5b8251600160201b811182820188101715614af857600080fd5b82525081516020918201929091019080838360005b83811015614b25578181015183820152602001614b0d565b50505050905090810190601f168015614b525780820380516001836020036101000a031916815260200191505b50604052509198975050505050505050565b6000546001600160a01b03163314614bab576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b6001600160a01b0382166000818152600a6020908152604091829020805460ff191685151590811790915582519384529083015280517fcb4632aa94a57cabbc5cffdf9f2665ebe316944545b1f942336ef1af7205ea469281900390910190a15050565b6000546001600160a01b03163314614c56576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b815181518114614c96576040805162461bcd60e51b8152602060048083019190915260248201526310b632b760e11b604482015290519081900360640190fd5b60005b81811015611b5757828181518110614cad57fe5b6020026020010151600014614d3557600f54838281518110614ccb57fe5b602002602001015110158015614cf65750601054838281518110614ceb57fe5b602002602001015111155b614d35576040805162461bcd60e51b815260206004820152600b60248201526a21626f756e64617269657360a81b604482015290519081900360640190fd5b828181518110614d4157fe5b602002602001015160136000868481518110614d5957fe5b6020026020010151815260200190815260200160002081905550838181518110614d7f57fe5b60200260200101517f9003d8c07d4c7e4d0072b82a27b1b3212f918279194b26ee52e38b917eb0924f848381518110614db457fe5b60200260200101516040518082815260200191505060405180910390a2600101614c99565b6004546001600160a01b031681565b600a6020526000908152604090205460ff1681565b6015546004805460408051630452a26760e21b81526001600160a01b03878116948201949094529051600094938593169163114a899c91602480830192602092919082900301818787803b158015614e5457600080fd5b505af1158015614e68573d6000803e3d6000fd5b505050506040513d6020811015614e7e57600080fd5b505160035460408051632f7260f160e01b8152600481018690526001600160a01b038085166024830152898116604483015291519394506000939190921691632f7260f191606480830192602092919082900301818787803b158015614ee357600080fd5b505af1158015614ef7573d6000803e3d6000fd5b505050506040513d6020811015614f0d57600080fd5b505190506132cd86868484612f68565b600d6020526000908152604090205481565b600f5481565b60125460ff1615614f76576040805162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b604482015290519081900360640190fd5b6005546001600160a01b03163314614fbd576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b8251825181148015614fcf5750815181145b615009576040805162461bcd60e51b8152602060048083019190915260248201526310b632b760e11b604482015290519081900360640190fd5b6000805b828110156151dc5761503b85828151811061502457fe5b602002602001015183615b9590919063ffffffff16565b915083818151811061504957fe5b6020026020010151156150f05785818151811061506257fe5b60200260200101516001600160a01b03166304d0c2c58887848151811061508557fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156150d357600080fd5b505af11580156150e7573d6000803e3d6000fd5b50505050615134565b6151348682815181106150ff57fe5b602002602001015186838151811061511357fe5b6020026020010151896001600160a01b0316615bef9092919063ffffffff16565b866001600160a01b0316886001600160a01b03168a7f1cae44de2209e08e758dcf27f2f188e08823def8d2fd696825fdb3297ab1522288858151811061517657fe5b60200260200101518a868151811061518a57fe5b602002602001015189878151811061519e57fe5b602002602001015160405180848152602001836001600160a01b031681526020018215158152602001935050505060405180910390a460010161500d565b50856001600160a01b0316876001600160a01b0316897fbfae22d78b70dbd404b2f03b2a20d9b182e9e96bc4ed0da9271d50f60299c029846040518082815260200191505060405180910390a45050505050505050565b60608061523f836143ae565b80519091508067ffffffffffffffff8111801561525b57600080fd5b50604051908082528060200260200182016040528015615285578160200160208202803683370190505b50925060005b818110156153ec5760008382815181106152a157fe5b60200260200101516001600160a01b03166370a082317f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec16040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561531557600080fd5b505afa158015615329573d6000803e3d6000fd5b505050506040513d602081101561533f57600080fd5b505184519091506001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2169085908490811061537d57fe5b60200260200101516001600160a01b031614156153cb576153c8816001600160a01b037f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec11631615b95565b90505b808583815181106153d857fe5b60209081029190910101525060010161528b565b505050919050565b6000546001600160a01b0316331461543b576040805162461bcd60e51b8152602060048201526005602482015264042c2eae8d60db1b604482015290519081900360640190fd5b610bb881111561547b576040805162461bcd60e51b8152602060048083019190915260248201526307cdac2f60e31b604482015290519081900360640190fd5b600c8190556040805182815290517faa05eb3e1da9d3f481c26c4083425708104d8acf8f72369ab94ad2f7148ba99b9181900360200190a150565b80158061553c575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b15801561550e57600080fd5b505afa158015615522573d6000803e3d6000fd5b505050506040513d602081101561553857600080fd5b5051155b6155775760405162461bcd60e51b8152600401808060200182810382526036815260200180615f8e6036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052612b05908490615c3d565b60125460ff161561560a576040805162461bcd60e51b81526020600482015260066024820152651c185d5cd95960d21b604482015290519081900360640190fd5b60006015858154811061561957fe5b60009182526020822060049182020180546002820154600183015460408051632770a7eb60e21b81526001600160a01b038b811697820197909752602481018c90529051949750928516959185169416928392639dc29fac92604480830193919282900301818387803b15801561568f57600080fd5b505af11580156156a3573d6000803e3d6000fd5b505050506003840154600160a01b900460ff166157f95760606156c584615233565b90507f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec16001600160a01b031663a6c3ef8b85858b6040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b031681526020018281526020019350505050602060405180830381600087803b15801561574f57600080fd5b505af1158015615763573d6000803e3d6000fd5b505050506040513d602081101561577957600080fd5b50615786905084826158b1565b600e5460ff16156157f7576005546040805163cc956f3f60e01b8152600481018c905290516001600160a01b039092169163cc956f3f9160248082019260009290919082900301818387803b1580156157de57600080fd5b505af11580156157f2573d6000803e3d6000fd5b505050505b505b61580d6001600160a01b0384168689615bef565b60408051888152905189916001600160a01b038816917f92ccf450a286a957af52509bc1c9939d1a6a481783e142e41e2499f0bb66ebc69181900360200190a35050505050505050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611b57908590615c3d565b60606158bc836143ae565b825190915060005b81811015611a145760008382815181106158da57fe5b602002602001015190506000816001600160a01b03166370a082317f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec16040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561595357600080fd5b505afa158015615967573d6000803e3d6000fd5b505050506040513d602081101561597d57600080fd5b505190507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0390811690831614156159ed576159ea816001600160a01b037f00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec11631615b95565b90505b615a42615a168785815181106159ff57fe5b602002602001015183615a7890919063ffffffff16565b6001600160a01b03808a1660009081526018602090815260408083209388168352929052205490615b95565b6001600160a01b0380891660009081526018602090815260408083209690931682529490945290922091909155506001016158c4565b600082821115615acf576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600082615ae457506000612421565b82820282848281615af157fe5b0414611d945760405162461bcd60e51b8152600401808060200182810382526021815260200180615f436021913960400191505060405180910390fd5b6000808211615b84576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381615b8d57fe5b049392505050565b600082820183811015611d94576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612b059084905b6060615c92826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316615cee9092919063ffffffff16565b805190915015612b0557808060200190516020811015615cb157600080fd5b5051612b055760405162461bcd60e51b815260040180806020018281038252602a815260200180615f64602a913960400191505060405180910390fd5b6060612d0e848460008585615d0285615e14565b615d53576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310615d925780518252601f199092019160209182019101615d73565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114615df4576040519150601f19603f3d011682016040523d82523d6000602084013e615df9565b606091505b5091509150615e09828286615e1a565b979650505050505050565b3b151590565b60608315615e29575081611d94565b825115615e395782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015615e83578181015183820152602001615e6b565b50505050905090810190601f168015615eb05780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b828054828255906000526020600020908101928215615f13579160200282015b82811115615f1357825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190615ede565b50615f1f929150615f23565b5090565b5b80821115615f1f5780546001600160a01b0319168155600101615f2456fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a164736f6c634300060c000a

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec100000000000000000000000096ff1506f7ac06b95486e09529c7efb9dfef601e000000000000000000000000fa66478296841b636d72a3b31da9cdc77e902bf1000000000000000000000000c0b314a8c08637685fc3dafc477b92028c540cfb000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000000003a98

-----Decoded View---------------
Arg [0] : _voterProxy (address): 0x24D2f6be2bF9cdf3627f720cf09D4551580C1eC1
Arg [1] : _reservoirMinter (address): 0x96Ff1506F7aC06B95486E09529c7eFb9DfEF601E
Arg [2] : _cvx (address): 0xFa66478296841b636D72a3B31Da9CDc77E902bf1
Arg [3] : _crv (address): 0xc0B314a8c08637685Fc3daFC477b92028c540CFB
Arg [4] : _weth (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [5] : _minMintRatio (uint256): 1000
Arg [6] : _maxMintRatio (uint256): 15000

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 00000000000000000000000024d2f6be2bf9cdf3627f720cf09d4551580c1ec1
Arg [1] : 00000000000000000000000096ff1506f7ac06b95486e09529c7efb9dfef601e
Arg [2] : 000000000000000000000000fa66478296841b636d72a3b31da9cdc77e902bf1
Arg [3] : 000000000000000000000000c0b314a8c08637685fc3dafc477b92028c540cfb
Arg [4] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [5] : 00000000000000000000000000000000000000000000000000000000000003e8
Arg [6] : 0000000000000000000000000000000000000000000000000000000000003a98


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
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.