ETH Price: $2,999.72 (-1.83%)
Gas: 3 Gwei

Contract

0x819d4D3061EDcdac17ba34EC95c2e6520882f79b
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Initiate Withdra...152569172022-08-01 13:26:46706 days ago1659360406IN
0x819d4D30...20882f79b
0 ETH0.0140670611.26585864
Initiate Withdra...152569002022-08-01 13:23:49706 days ago1659360229IN
0x819d4D30...20882f79b
0 ETH0.0180320914.24608213
Claim Rewards152368422022-07-29 10:30:52709 days ago1659090652IN
0x819d4D30...20882f79b
0 ETH0.012263111
Initiate Deposit151918382022-07-22 10:31:10716 days ago1658485870IN
0x819d4D30...20882f79b
0 ETH0.003444249
Claim Rewards151918362022-07-22 10:30:57716 days ago1658485857IN
0x819d4D30...20882f79b
0 ETH0.014015078
Open Position151467462022-07-15 10:35:53723 days ago1657881353IN
0x819d4D30...20882f79b
0 ETH0.0071604110.91099643
Initiate Deposit151467432022-07-15 10:35:39723 days ago1657881339IN
0x819d4D30...20882f79b
0 ETH0.0041355310.62546812
Claim Rewards151467242022-07-15 10:31:18723 days ago1657881078IN
0x819d4D30...20882f79b
0 ETH0.0212206612.09287593
Initiate Withdra...151018872022-07-08 12:23:41730 days ago1657283021IN
0x819d4D30...20882f79b
0 ETH0.023482517.99927497
Initiate Withdra...151018582022-07-08 12:17:43730 days ago1657282663IN
0x819d4D30...20882f79b
0 ETH0.0290046419.40209922
Initiate Withdra...151018042022-07-08 12:07:02730 days ago1657282022IN
0x819d4D30...20882f79b
0 ETH0.0056950619.97939512
Open Position151014142022-07-08 10:37:24730 days ago1657276644IN
0x819d4D30...20882f79b
0 ETH0.006150789.3723546
Initiate Deposit151014122022-07-08 10:37:14730 days ago1657276634IN
0x819d4D30...20882f79b
0 ETH0.0040922710.514303
Claim Rewards151014092022-07-08 10:36:37730 days ago1657276597IN
0x819d4D30...20882f79b
0 ETH0.016052739.15055263
Open Position150889472022-07-06 12:33:48732 days ago1657110828IN
0x819d4D30...20882f79b
0 ETH0.0086909513.69989864
Open Position150615112022-07-02 6:38:25736 days ago1656743905IN
0x819d4D30...20882f79b
0 ETH0.005391218.43473026
Initiate Deposit150615012022-07-02 6:36:11736 days ago1656743771IN
0x819d4D30...20882f79b
0 ETH0.003392228.97961266
Open Position150562262022-07-01 11:01:21737 days ago1656673281IN
0x819d4D30...20882f79b
0 ETH0.0137491120.95042111
Initiate Deposit150562192022-07-01 10:59:49737 days ago1656673189IN
0x819d4D30...20882f79b
0 ETH0.007488519.24026797
Claim Rewards150562172022-07-01 10:59:19737 days ago1656673159IN
0x819d4D30...20882f79b
0 ETH0.0377639222.21994278
Open Position150399102022-06-28 13:36:08740 days ago1656423368IN
0x819d4D30...20882f79b
0 ETH0.0518116281.67271961
Open Position150399042022-06-28 13:33:53740 days ago1656423233IN
0x819d4D30...20882f79b
0 ETH0.0415742863.35409613
Initiate Deposit150398992022-06-28 13:32:43740 days ago1656423163IN
0x819d4D30...20882f79b
0 ETH0.0277833170.97356355
Open Position150237242022-06-25 12:37:48743 days ago1656160668IN
0x819d4D30...20882f79b
0 ETH0.0300348543.80947229
Initiate Deposit150237062022-06-25 12:32:27743 days ago1656160347IN
0x819d4D30...20882f79b
0 ETH0.0195735750.00146996
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ConvexFraxPoolTradeExecutor

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 100 runs

Other Settings:
default evmVersion
File 1 of 16 : ConvexFraxPoolTradeExecutor.sol
//SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.0;

import "../../BaseTradeExecutor.sol";
import {ConvexPositionHandler} from "./ConvexPositionHandler.sol";

/// @title ConvexTradeExecutor
/// @author PradeepSelva
/// @notice A contract to execute strategy's trade, on Convex (frax)
contract ConvexFraxPoolTradeExecutor is
    BaseTradeExecutor,
    ConvexPositionHandler
{
    /// @notice event emitted when harvester is updated
    event UpdatedHarvester(
        address indexed oldHandler,
        address indexed newHandler
    );
    /// @notice event emitted when slippage is updated
    event UpdatedSlippage(
        uint256 indexed oldSlippage,
        uint256 indexed newSlippage
    );

    /// @notice creates a new ConvexTradeExecutor with required state
    /// @param _harvester address of harvester
    /// @param _vault address of vault
    constructor(address _harvester, address _vault) BaseTradeExecutor(_vault) {
        ConvexPositionHandler._configHandler(
            _harvester,
            BaseTradeExecutor.vaultWantToken()
        );
    }

    /*///////////////////////////////////////////////////////////////
                         VIEW FUNCTONS
  //////////////////////////////////////////////////////////////*/
    /// @notice This gives the total funds in the contract in terms of want token
    /// @return totalBalance Total balance of contract in want token
    /// @return blockNumber Current block number
    function totalFunds() public view override returns (uint256, uint256) {
        return ConvexPositionHandler.positionInWantToken();
    }

    /*///////////////////////////////////////////////////////////////
                    STATE MODIFICATION FUNCTIONS
  //////////////////////////////////////////////////////////////*/

    /// @notice Keeper function to set max accepted slippage of swaps
    /// @param _slippage Max accepted slippage during harvesting
    function setSlippage(uint256 _slippage) external onlyGovernance {
        uint256 oldSlippage = ConvexPositionHandler.maxSlippage;

        ConvexPositionHandler._setSlippage(_slippage);
        emit UpdatedSlippage(oldSlippage, _slippage);
    }

    /// @notice Governance function to set how position value should be calculated, i.e using virtual price or calc withdraw
    /// @param _useVirtualPriceForPosValue bool signifying if virtual price should be used to calculate position value
    function setUseVirtualPriceForPosValue(bool _useVirtualPriceForPosValue)
        external
        onlyGovernance
    {
        ConvexPositionHandler._setUseVirtualPriceForPosValue(
            _useVirtualPriceForPosValue
        );
    }

    /// @param _harvester address of harvester
    function setHandler(address _harvester) external onlyGovernance {
        address oldHarvester = address(ConvexPositionHandler.harvester);

        ConvexPositionHandler._configHandler(_harvester, vaultWantToken());
        emit UpdatedHarvester(oldHarvester, _harvester);
    }

    /*///////////////////////////////////////////////////////////////
                    DEPOSIT / WITHDRAW FUNCTIONS
  //////////////////////////////////////////////////////////////*/

    /// @notice To deposit into the Curve Pool
    /// @dev Converts USDC to lp tokens via Curve
    /// @param _data Encoded AmountParams as _data with USDC amount
    function _initateDeposit(bytes calldata _data) internal override {
        ConvexPositionHandler._deposit(_data);
        BaseTradeExecutor.confirmDeposit();
    }

    /// @notice To withdraw from ConvexHandler
    /// @dev  Converts Curve Lp Tokens  back to USDC.
    ///  @param _data Encoded WithdrawParams as _data with USDC token amount
    function _initiateWithdraw(bytes calldata _data) internal override {
        ConvexPositionHandler._withdraw(_data);
        BaseTradeExecutor.confirmWithdraw();
    }

    /// @notice Functionlity to execute after deposit is completed
    /// @dev This is not required in ConvexTradeExecutor, hence empty. This follows the BaseTradeExecutor interface
    function _confirmDeposit() internal override {}

    /// @notice Functionlity to execute after withdraw is completed
    /// @dev This is not required in ConvexTradeExecutor, hence empty. This follows the BaseTradeExecutor interface
    function _confirmWithdraw() internal override {}

    /*///////////////////////////////////////////////////////////////
                    OPEN / CLOSE FUNCTIONS
  //////////////////////////////////////////////////////////////*/

    /// @notice To open staking position in Convex
    /// @dev stakes the specified Curve Lp Tokens into Convex's UST3-Wormhole pool
    /// @param _data Encoded AmountParams as _data with LP Token amount
    function openPosition(bytes calldata _data) public onlyKeeper {
        ConvexPositionHandler._openPosition(_data);
    }

    /// @notice To close Convex Staking Position
    /// @dev Unstakes from Convex position and gives back them as Curve Lp Tokens along with rewards like CRV, CVX.
    /// @param _data Encoded AmountParams as _data with LP token amount
    function closePosition(bytes calldata _data) public onlyKeeper {
        ConvexPositionHandler._closePosition(_data);
    }

    /*///////////////////////////////////////////////////////////////
                    REWARDS FUNCTION
   //////////////////////////////////////////////////////////////*/
    /// @notice To claim rewards from Convex Staking position
    /// @dev Claims Convex Staking position rewards, and converts them to wantToken i.e., USDC.
    /// @param _data is not needed here (empty param, to satisfy interface)
    function claimRewards(bytes calldata _data) public onlyKeeper {
        ConvexPositionHandler._claimRewards(_data);
    }
}

File 2 of 16 : BaseTradeExecutor.sol
//SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import "../interfaces/ITradeExecutor.sol";
import "../interfaces/IVault.sol";

abstract contract BaseTradeExecutor is ITradeExecutor {
    uint256 internal constant MAX_INT = type(uint256).max;

    ActionStatus public override depositStatus;
    ActionStatus public override withdrawalStatus;

    address public override vault;

    constructor(address _vault) {
        vault = _vault;
        IERC20(vaultWantToken()).approve(vault, MAX_INT);
    }

    function vaultWantToken() public view returns (address) {
        return IVault(vault).wantToken();
    }

    function governance() public view returns (address) {
        return IVault(vault).governance();
    }

    function keeper() public view returns (address) {
        return IVault(vault).keeper();
    }

    modifier onlyGovernance() {
        require(msg.sender == governance(), "ONLY_GOV");
        _;
    }

    modifier onlyKeeper() {
        require(msg.sender == keeper(), "ONLY_KEEPER");
        _;
    }

    function sweep(address _token) public onlyGovernance {
        IERC20(_token).transfer(
            governance(),
            IERC20(_token).balanceOf(address(this))
        );
    }

    function initiateDeposit(bytes calldata _data) public override onlyKeeper {
        require(!depositStatus.inProcess, "DEPOSIT_IN_PROGRESS");
        depositStatus.inProcess = true;
        _initateDeposit(_data);
    }

    function confirmDeposit() public override onlyKeeper {
        require(depositStatus.inProcess, "DEPOSIT_COMPLETED");
        depositStatus.inProcess = false;
        _confirmDeposit();
    }

    function initiateWithdraw(bytes calldata _data) public override onlyKeeper {
        require(!withdrawalStatus.inProcess, "WITHDRAW_IN_PROGRESS");
        withdrawalStatus.inProcess = true;
        _initiateWithdraw(_data);
    }

    function confirmWithdraw() public override onlyKeeper {
        require(withdrawalStatus.inProcess, "WITHDRAW_COMPLETED");
        withdrawalStatus.inProcess = false;
        _confirmWithdraw();
    }

    /// Internal Funcs

    function _initateDeposit(bytes calldata _data) internal virtual;

    function _confirmDeposit() internal virtual;

    function _initiateWithdraw(bytes calldata _data) internal virtual;

    function _confirmWithdraw() internal virtual;
}

File 3 of 16 : ConvexPositionHandler.sol
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
pragma abicoder v2;

import "../../../interfaces/BasePositionHandler.sol";
import "../../../library/Math.sol";

import "../interfaces/IConvexRewards.sol";
import "../interfaces/IConvexBooster.sol";
import "../interfaces/ICurvePool.sol";
import "../interfaces/ICurveDepositZapper.sol";
import "../interfaces/IHarvester.sol";

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

/// @title ConvexPositionHandler
/// @author PradeepSelva & BapireddyK;
/// @notice A Position handler to handle Convex for Frax Pool
contract ConvexPositionHandler is BasePositionHandler {
    using SafeERC20 for IERC20;

    /*///////////////////////////////////////////////////////////////
                            ENUMS
  //////////////////////////////////////////////////////////////*/
    enum FraxPoolCoinIndexes {
        FRAX,
        DAI,
        USDC,
        USDT
    }

    /*///////////////////////////////////////////////////////////////
                          STRUCTS FOR DECODING
  //////////////////////////////////////////////////////////////*/
    struct AmountParams {
        uint256 _amount;
    }

    /*///////////////////////////////////////////////////////////////
                          GLOBAL IMMUTABLES
  //////////////////////////////////////////////////////////////*/
    /// @dev the max basis points used as normalizing factor.
    uint256 public immutable MAX_BPS = 10000;
    /// @dev the normalization factor for amounts
    uint256 public constant NORMALIZATION_FACTOR = 1e30;

    /*///////////////////////////////////////////////////////////////
                          GLOBAL MUTABLES
  //////////////////////////////////////////////////////////////*/
    /// @notice the max permitted slippage for swaps
    uint256 public maxSlippage = 30;
    /// @notice the latest amount of rewards claimed and harvested
    uint256 public latestHarvestedRewards;
    /// @notice the total cummulative rewards earned so far
    uint256 public totalCummulativeRewards;
    /// @notice governance handled variable, that tells how to calculate position in want token
    /// @dev this is done to account for cases of depeg
    bool public useVirtualPriceForPosValue = true;

    /*///////////////////////////////////////////////////////////////
                            EXTERNAL CONTRACTS
  //////////////////////////////////////////////////////////////*/
    /// @notice The want token that is deposited and withdrawn
    IERC20 public wantToken;
    /// @notice Curve LP Tokens that are converted and staked on Convex
    IERC20 public lpToken = IERC20(0xd632f22692FaC7611d2AA1C0D552930D43CAEd3B);

    /// @notice Harvester that harvests rewards claimed from Convex
    IHarvester public harvester;

    /// @notice convex Frax base reward pool
    IConvexRewards public constant baseRewardPool =
        IConvexRewards(0xB900EF131301B307dB5eFcbed9DBb50A3e209B2e);
    /// @notice curve's Frax Pool
    ICurvePool public constant fraxPool =
        ICurvePool(0xd632f22692FaC7611d2AA1C0D552930D43CAEd3B);
    /// @notice curve 3 pool zap
    ICurveDepositZapper public constant curve3PoolZap =
        ICurveDepositZapper(0xA79828DF1850E8a3A3064576f380D90aECDD3359);
    /// @notice convex booster
    IConvexBooster public constant convexBooster =
        IConvexBooster(0xF403C135812408BFbE8713b5A23a04b3D48AAE31);

    /*///////////////////////////////////////////////////////////////
                          INITIALIZING
    //////////////////////////////////////////////////////////////*/
    /// @notice configures ConvexPositionHandler with the required state
    /// @param _harvester address of harvester
    /// @param _wantToken address of want token
    function _configHandler(address _harvester, address _wantToken) internal {
        wantToken = IERC20(_wantToken);
        harvester = IHarvester(_harvester);

        // Assign virtual price of fraxpool
        prevSharePrice = fraxPool.get_virtual_price();

        // Approve max LP tokens to convex booster
        lpToken.approve(address(convexBooster), type(uint256).max);

        // Approve max want tokens to zapper.
        wantToken.approve(address(curve3PoolZap), type(uint256).max);

        // Approve max lp tokens to zapper
        lpToken.approve(address(curve3PoolZap), type(uint256).max);
    }

    /*///////////////////////////////////////////////////////////////
                          VIEW FUNCTIONS
  //////////////////////////////////////////////////////////////*/

    /**
   @notice To get the total balances of the contract in want token price
   @return totalBalance Total balance of contract in want token
   @return blockNumber Current block number
   */
    function positionInWantToken()
        public
        view
        override
        returns (uint256, uint256)
    {
        (
            uint256 stakedLpBalance,
            uint256 lpTokenBalance,
            uint256 usdcBalance
        ) = _getTotalBalancesInWantToken(useVirtualPriceForPosValue);

        return (stakedLpBalance + lpTokenBalance + usdcBalance, block.number);
    }

    /*///////////////////////////////////////////////////////////////
                      DEPOSIT / WITHDRAW LOGIC
  //////////////////////////////////////////////////////////////*/

    /**
   @notice To deposit into the Curve Pool
   @dev Converts USDC to lp tokens via Curve
   @param _data Encoded AmountParams as _data with USDC amount
   */
    function _deposit(bytes calldata _data) internal override {
        AmountParams memory depositParams = abi.decode(_data, (AmountParams));
        require(
            depositParams._amount <= wantToken.balanceOf(address(this)),
            "invalid deposit amount"
        );

        _convertUSDCIntoLpToken(depositParams._amount);

        emit Deposit(depositParams._amount);
    }

    /**
   @notice To withdraw from ConvexHandler
   @dev  Converts Curve Lp Tokens  back to USDC.
   @param _data Encoded WithdrawParams as _data with USDC token amount
   */
    function _withdraw(bytes calldata _data) internal override {
        // _amount here is the maxWithdraw
        AmountParams memory withdrawParams = abi.decode(_data, (AmountParams));
        (
            uint256 stakedLpBalance,
            uint256 lpTokenBalance,
            uint256 usdcBalance
        ) = _getTotalBalancesInWantToken(false);
        uint256 totalBalance = (stakedLpBalance + lpTokenBalance + usdcBalance);

        // if _amount is more than balance, then withdraw entire balance
        if (withdrawParams._amount > totalBalance) {
            withdrawParams._amount = totalBalance;
        }

        // calculate maximum amount that can be withdrawn
        uint256 amountToWithdraw = withdrawParams._amount;
        uint256 usdcValueOfLpTokensToConvert = 0;

        // if usdc token balance is insufficient
        if (amountToWithdraw > usdcBalance) {
            usdcValueOfLpTokensToConvert = amountToWithdraw - usdcBalance;

            if (usdcValueOfLpTokensToConvert > lpTokenBalance) {
                uint256 amountToUnstake = usdcValueOfLpTokensToConvert -
                    lpTokenBalance;
                // unstake convex position partially
                // this is min between actual staked balance and calculated amount, to ensure overflow
                uint256 lpTokensToUnstake = Math.min(
                    _USDCValueInLpToken(amountToUnstake),
                    baseRewardPool.balanceOf(address(this))
                );

                require(
                    baseRewardPool.withdrawAndUnwrap(lpTokensToUnstake, true),
                    "could not unstake"
                );
            }
        }

        // usdcValueOfLpTokensToConvert's value converted to Lp Tokens
        // this is min between converted value and lp token balance, to ensure overflow
        uint256 lpTokensToConvert = Math.min(
            _USDCValueInLpToken(usdcValueOfLpTokensToConvert),
            lpToken.balanceOf(address(this))
        );
        // if lp tokens are required to convert, then convert to usdc and update amountToWithdraw
        if (lpTokensToConvert > 0) {
            _convertLpTokenIntoUSDC(lpTokensToConvert);
        }

        emit Withdraw(withdrawParams._amount);
    }

    /*///////////////////////////////////////////////////////////////
                      OPEN / CLOSE LOGIC
  //////////////////////////////////////////////////////////////*/

    /**
   @notice To open staking position in Convex
   @dev stakes the specified Curve Lp Tokens into Convex's Frax pool
   @param _data Encoded AmountParams as _data with LP Token amount
   */
    function _openPosition(bytes calldata _data) internal override {
        AmountParams memory openPositionParams = abi.decode(
            _data,
            (AmountParams)
        );

        require(
            openPositionParams._amount <= lpToken.balanceOf(address(this)),
            "INSUFFICIENT_BALANCE"
        );

        require(
            convexBooster.deposit(
                baseRewardPool.pid(),
                openPositionParams._amount,
                true
            ),
            "CONVEX_STAKING_FAILED"
        );
    }

    /**
   @notice To close Convex Staking Position
   @dev Unstakes from Convex position and gives back them as Curve Lp Tokens along with rewards like CRV, CVX.
   @param _data Encoded AmountParams as _data with LP token amount
   */
    function _closePosition(bytes calldata _data) internal override {
        AmountParams memory closePositionParams = abi.decode(
            _data,
            (AmountParams)
        );

        require(
            closePositionParams._amount <=
                baseRewardPool.balanceOf(address(this)),
            "AMOUNT_EXCEEDS_BALANCE"
        );

        if (closePositionParams._amount > 0) {
            /// Unstake _amount and claim rewards from convex
            baseRewardPool.withdrawAndUnwrap(closePositionParams._amount, true);
        } else {
            /// Unstake entire balance if closePositionParams._amount is 0
            baseRewardPool.withdrawAllAndUnwrap(true);
        }
    }

    /*///////////////////////////////////////////////////////////////
                      REWARDS LOGIC
  //////////////////////////////////////////////////////////////*/
    /// @notice variable to track previous share price of LP token
    uint256 public prevSharePrice = type(uint256).max;

    /**
   @notice To claim rewards from Convex Staking position
   @dev Claims Convex Staking position rewards, and converts them to wantToken i.e., USDC.
   @param _data is not needed here (empty param, to satisfy interface)
   */
    function _claimRewards(bytes calldata _data) internal override {
        require(baseRewardPool.getReward(), "reward claim failed");

        uint256 initialUSDCBalance = wantToken.balanceOf(address(this));

        // get list of tokens to transfer to harvester
        address[] memory rewardTokens = harvester.rewardTokens();
        //transfer them
        uint256 balance;
        for (uint256 i = 0; i < rewardTokens.length; i++) {
            balance = IERC20(rewardTokens[i]).balanceOf(address(this));

            if (balance > 0) {
                IERC20(rewardTokens[i]).safeTransfer(
                    address(harvester),
                    balance
                );
            }
        }

        // convert all rewards to usdc
        harvester.harvest();

        // get curve lp rewards
        uint256 currentSharePrice = fraxPool.get_virtual_price();
        if (currentSharePrice > prevSharePrice) {
            // claim any gain on lp token yields
            uint256 contractLpTokenBalance = lpToken.balanceOf(address(this));
            uint256 totalLpBalance = contractLpTokenBalance +
                baseRewardPool.balanceOf(address(this));
            uint256 yieldEarned = (currentSharePrice - prevSharePrice) *
                totalLpBalance;

            uint256 lpTokenEarned = yieldEarned / currentSharePrice;

            // If lpTokenEarned is more than lpToken balance in contract, unstake the difference
            if (lpTokenEarned > contractLpTokenBalance) {
                baseRewardPool.withdrawAndUnwrap(
                    lpTokenEarned - contractLpTokenBalance,
                    true
                );
            }
            // convert lp token to usdc
            _convertLpTokenIntoUSDC(lpTokenEarned);
        }
        prevSharePrice = currentSharePrice;

        latestHarvestedRewards =
            wantToken.balanceOf(address(this)) -
            initialUSDCBalance;
        totalCummulativeRewards += latestHarvestedRewards;

        emit Claim(latestHarvestedRewards);
    }

    /*///////////////////////////////////////////////////////////////
                          HELPER FUNCTIONS
  //////////////////////////////////////////////////////////////*/

    /// @notice To get total contract balances in terms of want token
    /// @dev Gets lp token balance from contract, staked position on convex, and converts all of them to usdc. And gives balance as want token.
    /// @param useVirtualPrice to check if balances shoudl be based on virtual price
    /// @return stakedLpBalance balance of staked LP tokens in terms of want token
    /// @return lpTokenBalance balance of LP tokens in contract
    /// @return usdcBalance usdc balance in contract
    function _getTotalBalancesInWantToken(bool useVirtualPrice)
        internal
        view
        returns (
            uint256 stakedLpBalance,
            uint256 lpTokenBalance,
            uint256 usdcBalance
        )
    {
        uint256 stakedLpBalanceRaw = baseRewardPool.balanceOf(address(this));
        uint256 lpTokenBalanceRaw = lpToken.balanceOf(address(this));

        uint256 totalLpBalance = stakedLpBalanceRaw + lpTokenBalanceRaw;

        // Here, in order to prevent price manipulation attacks via curve pools,
        // When getting total position value -> its calculated based on virtual price
        // During withdrawal -> calc_withdraw_one_coin() is used to get an actual estimate of USDC received if we were to remove liquidity
        // The following checks account for this
        uint256 totalLpBalanceInUSDC = useVirtualPrice
            ? _lpTokenValueInUSDCfromVirtualPrice(totalLpBalance)
            : _lpTokenValueInUSDC(totalLpBalance);

        lpTokenBalance = useVirtualPrice
            ? _lpTokenValueInUSDCfromVirtualPrice(lpTokenBalanceRaw)
            : _lpTokenValueInUSDC(lpTokenBalanceRaw);

        stakedLpBalance = totalLpBalanceInUSDC - lpTokenBalance;
        usdcBalance = wantToken.balanceOf(address(this));
    }

    /**
   @notice Helper to convert Lp tokens into USDC
   @dev Burns LpTokens on Frax pool on curve to get USDC
   @param _amount amount of Lp tokens to burn to get USDC
   @return receivedWantTokens amount of want tokens received after converting Lp tokens
   */
    function _convertLpTokenIntoUSDC(uint256 _amount)
        internal
        returns (uint256 receivedWantTokens)
    {
        int128 usdcIndexInPool = int128(
            int256(uint256(FraxPoolCoinIndexes.USDC))
        );

        // estimate amount of USDC received based on stable peg i.e., 1FXS = 1 3Pool LP Token
        uint256 expectedWantTokensOut = (_amount *
            fraxPool.get_virtual_price()) / NORMALIZATION_FACTOR; // 30 = normalizing 18 decimals for virutal price + 18 decimals for LP token - 6 decimals for want token
        // burn Lp tokens to receive USDC with a slippage of `maxSlippage`
        receivedWantTokens = curve3PoolZap.remove_liquidity_one_coin(
            address(fraxPool),
            _amount,
            usdcIndexInPool,
            (expectedWantTokensOut * (MAX_BPS - maxSlippage)) / (MAX_BPS)
        );
    }

    /**
   @notice Helper to convert USDC into Lp tokens
   @dev Provides USDC liquidity on Frax pool on curve to get Lp Tokens
   @param _amount amount of USDC to deposit to get Lp Tokens
   @return receivedLpTokens amount of LP tokens received after converting USDC
   */
    function _convertUSDCIntoLpToken(uint256 _amount)
        internal
        returns (uint256 receivedLpTokens)
    {
        uint256[4] memory liquidityAmounts = [0, 0, _amount, 0];

        // estimate amount of Lp Tokens based on stable peg i.e., 1FXS = 1 3Pool LP Token
        uint256 expectedLpOut = (_amount * NORMALIZATION_FACTOR) /
            fraxPool.get_virtual_price(); // 30 = normalizing 18 decimals for virutal price + 18 decimals for LP token - 6 decimals for want token
        // Provide USDC liquidity to receive Lp tokens with a slippage of `maxSlippage`
        receivedLpTokens = curve3PoolZap.add_liquidity(
            address(fraxPool),
            liquidityAmounts,
            (expectedLpOut * (MAX_BPS - maxSlippage)) / (MAX_BPS)
        );
    }

    /**
   @notice to get value of an amount in USDC
   @param _value value to be converted
   @return estimatedLpTokenAmount estimated amount of lp tokens if (_value) amount of USDC is converted
   */
    function _lpTokenValueInUSDC(uint256 _value)
        internal
        view
        returns (uint256)
    {
        if (_value == 0) return 0;

        return
            curve3PoolZap.calc_withdraw_one_coin(
                address(fraxPool),
                _value,
                int128(int256(uint256(FraxPoolCoinIndexes.USDC)))
            );
    }

    /**
   @notice to get value of an amount in USDC based on virtual price
   @param _value value to be converted
   @return estimatedLpTokenAmount lp tokens value in USDC based on its virtual price 
   */
    function _lpTokenValueInUSDCfromVirtualPrice(uint256 _value)
        internal
        view
        returns (uint256)
    {
        return (fraxPool.get_virtual_price() * _value) / NORMALIZATION_FACTOR;
    }

    /**
   @notice to get value of an amount in Lp Tokens
   @param _value value to be converted
   @return estimatedUSDCAmount estimated amount of USDC if (_value) amount of LP Tokens is converted
   */
    function _USDCValueInLpToken(uint256 _value)
        internal
        view
        returns (uint256)
    {
        if (_value == 0) return 0;

        return
            curve3PoolZap.calc_token_amount(
                address(fraxPool),
                [0, 0, _value, 0],
                true
            );
    }

    /**
   @notice Keeper function to set max accepted slippage of swaps
   @param _slippage Max accepted slippage during harvesting
   */
    function _setSlippage(uint256 _slippage) internal {
        maxSlippage = _slippage;
    }

    /// @notice Governance function to set how position value should be calculated, i.e using virtual price or calc withdraw
    /// @param _useVirtualPriceForPosValue bool signifying if virtual price should be used to calculate position value
    function _setUseVirtualPriceForPosValue(bool _useVirtualPriceForPosValue)
        internal
    {
        useVirtualPriceForPosValue = _useVirtualPriceForPosValue;
    }
}

File 4 of 16 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

File 5 of 16 : ITradeExecutor.sol
//SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.4;

interface ITradeExecutor {
    struct ActionStatus {
        bool inProcess;
        address from;
    }

    function vault() external view returns (address);

    function depositStatus() external returns (bool, address);

    function withdrawalStatus() external returns (bool, address);

    function initiateDeposit(bytes calldata _data) external;

    function confirmDeposit() external;

    function initiateWithdraw(bytes calldata _data) external;

    function confirmWithdraw() external;

    function totalFunds()
        external
        view
        returns (uint256 posValue, uint256 lastUpdatedBlock);
}

File 6 of 16 : IVault.sol
/// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;

interface IVault {
    function keeper() external view returns (address);

    function governance() external view returns (address);

    function wantToken() external view returns (address);

    function deposit(uint256 amountIn, address receiver)
        external
        returns (uint256 shares);

    function withdraw(uint256 sharesIn, address receiver)
        external
        returns (uint256 amountOut);
}

File 7 of 16 : BasePositionHandler.sol
/// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;

abstract contract BasePositionHandler {
    /// @notice To be emitted when a deposit is made by position handler
    /// @param amount The amount of tokens deposited
    event Deposit(uint256 indexed amount);

    /// @notice To be emitted when a withdraw is made by position handler
    /// @param amount The amount of tokens withdrawn
    event Withdraw(uint256 indexed amount);

    /// @notice To be emitted with rewards are claimed by position handler
    /// @param amount The amount that was withdrawn
    event Claim(uint256 indexed amount);

    /// @notice struct to store data related to position
    /// @param posValue The value of the position in vault wantToken
    /// @param lastUpdatedBlock The block number of last update in position value
    struct Position {
        uint256 posValue;
        uint256 lastUpdatedBlock;
    }

    function positionInWantToken()
        external
        view
        virtual
        returns (uint256, uint256);

    function _openPosition(bytes calldata _data) internal virtual;

    function _closePosition(bytes calldata _data) internal virtual;

    function _deposit(bytes calldata _data) internal virtual;

    function _withdraw(bytes calldata _data) internal virtual;

    function _claimRewards(bytes calldata _data) internal virtual;
}

File 8 of 16 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }
}

File 9 of 16 : IConvexRewards.sol
/// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;

//sample convex reward contracts interface
interface IConvexRewards {
    // pid of pool
    function pid() external view returns (uint256);

    // earned rewards
    function earned(address account) external view returns (uint256);

    //get balance of an address
    function balanceOf(address _account) external view returns (uint256);

    //withdraw to a convex tokenized deposit
    function withdraw(uint256 _amount, bool _claim) external returns (bool);

    //withdraw directly to curve LP token
    function withdrawAndUnwrap(uint256 _amount, bool _claim)
        external
        returns (bool);

    //claim rewards
    function getReward() external returns (bool);

    //stake a convex tokenized deposit
    function stake(uint256 _amount) external returns (bool);

    //stake a convex tokenized deposit for another address(transfering ownership)
    function stakeFor(address _account, uint256 _amount)
        external
        returns (bool);

    function stakeAll() external returns (bool);

    function withdrawAll(bool claim) external;

    function withdrawAllAndUnwrap(bool claim) external;
}

File 10 of 16 : IConvexBooster.sol
/// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;

interface IConvexBooster {
    //deposit into convex, receive a tokenized deposit.  parameter to stake immediately
    function deposit(
        uint256 _pid,
        uint256 _amount,
        bool _stake
    ) external returns (bool);

    //burn a tokenized deposit to receive curve lp tokens back
    function withdraw(uint256 _pid, uint256 _amount) external returns (bool);
}

File 11 of 16 : ICurvePool.sol
/// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;

interface ICurvePool {
    function exchange(
        int128 i,
        int128 j,
        uint256 _dx,
        uint256 _min_dy,
        address _receiver
    ) external returns (uint256);

    function remove_liquidity_one_coin(
        uint256 _token_amount,
        int128 i,
        uint256 min_amount
    ) external returns (uint256);

    function add_liquidity(uint256[4] memory amounts, uint256 min_mint_amount)
        external
        returns (uint256);

    function get_dy(
        int128 i,
        int128 j,
        uint256 _dx
    ) external view returns (uint256);

    function calc_token_amount(uint256[4] memory _amounts, bool _is_deposit)
        external
        view
        returns (uint256);

    function get_virtual_price() external view returns (uint256);

    function balanceOf(address) external view returns (uint256);

    function approve(address spender, uint256 amount) external returns (bool);
}

File 12 of 16 : ICurveDepositZapper.sol
/// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;

interface ICurveDepositZapper {
    function calc_withdraw_one_coin(
        address _pool,
        uint256 _token_amount,
        int128 i
    ) external view returns (uint256);

    function calc_token_amount(
        address _pool,
        uint256[4] memory _amounts,
        bool _is_deposit
    ) external view returns (uint256);

    function remove_liquidity_one_coin(
        address _pool,
        uint256 _burn_amount,
        int128 i,
        uint256 _min_amount
    ) external returns (uint256);

    function add_liquidity(
        address _pool,
        uint256[4] memory _deposit_amounts,
        uint256 _min_mint_amount
    ) external returns (uint256);
}

File 13 of 16 : IHarvester.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.0;
import "../../../interfaces/IVault.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

interface IHarvester {
    function crv() external view returns (IERC20);

    function cvx() external view returns (IERC20);

    function _3crv() external view returns (IERC20);

    function snx() external view returns (IERC20);

    function vault() external view returns (IVault);

    // Swap tokens to wantToken
    function harvest() external;

    function sweep(address _token) external;

    function setSlippage(uint256 _slippage) external;

    function rewardTokens() external view returns (address[] memory);
}

File 14 of 16 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

File 15 of 16 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

File 16 of 16 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

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

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

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

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

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

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_harvester","type":"address"},{"internalType":"address","name":"_vault","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldHandler","type":"address"},{"indexed":true,"internalType":"address","name":"newHandler","type":"address"}],"name":"UpdatedHarvester","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldSlippage","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newSlippage","type":"uint256"}],"name":"UpdatedSlippage","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"MAX_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NORMALIZATION_FACTOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseRewardPool","outputs":[{"internalType":"contract IConvexRewards","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"closePosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"confirmDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"confirmWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"convexBooster","outputs":[{"internalType":"contract IConvexBooster","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curve3PoolZap","outputs":[{"internalType":"contract ICurveDepositZapper","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositStatus","outputs":[{"internalType":"bool","name":"inProcess","type":"bool"},{"internalType":"address","name":"from","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fraxPool","outputs":[{"internalType":"contract ICurvePool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvester","outputs":[{"internalType":"contract IHarvester","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"initiateDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"initiateWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"keeper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestHarvestedRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSlippage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"openPosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"positionInWantToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"prevSharePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_harvester","type":"address"}],"name":"setHandler","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_slippage","type":"uint256"}],"name":"setSlippage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_useVirtualPriceForPosValue","type":"bool"}],"name":"setUseVirtualPriceForPosValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalCummulativeRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFunds","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"useVirtualPriceForPosValue","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultWantToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wantToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalStatus","outputs":[{"internalType":"bool","name":"inProcess","type":"bool"},{"internalType":"address","name":"from","type":"address"}],"stateMutability":"view","type":"function"}]

60a0604052612710608052601e6003556006805460ff19166001179055600780546001600160a01b03191673d632f22692fac7611d2aa1c0d552930d43caed3b1790556000196009553480156200005557600080fd5b506040516200305e3803806200305e8339810160408190526200007891620004cf565b600280546001600160a01b0319166001600160a01b038316179055806200009e6200015d565b60025460405163095ea7b360e01b81526001600160a01b039182166004820152600019602482015291169063095ea7b390604401602060405180830381600087803b158015620000ed57600080fd5b505af115801562000102573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000128919062000506565b50506200015582620001446200015d60201b620006361760201c565b620001e360201b62000b751760201c565b505062000541565b600254604080516301a47c0960e71b815290516000926001600160a01b03169163d23e0480916004808301926020929190829003018186803b158015620001a357600080fd5b505afa158015620001b8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001de9190620004ab565b905090565b60068054610100600160a81b0319166101006001600160a01b038481169190910291909117909155600880546001600160a01b03191691841691909117905560408051630176f71760e71b8152905173d632f22692fac7611d2aa1c0d552930d43caed3b9163bb7b8b80916004808301926020929190829003018186803b1580156200026e57600080fd5b505afa15801562000283573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002a9919062000528565b60095560075460405163095ea7b360e01b815273f403c135812408bfbe8713b5a23a04b3d48aae31600482015260001960248201526001600160a01b039091169063095ea7b390604401602060405180830381600087803b1580156200030e57600080fd5b505af115801562000323573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000349919062000506565b5060065460405163095ea7b360e01b815273a79828df1850e8a3a3064576f380d90aecdd3359600482015260001960248201526101009091046001600160a01b03169063095ea7b390604401602060405180830381600087803b158015620003b057600080fd5b505af1158015620003c5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003eb919062000506565b5060075460405163095ea7b360e01b815273a79828df1850e8a3a3064576f380d90aecdd3359600482015260001960248201526001600160a01b039091169063095ea7b390604401602060405180830381600087803b1580156200044e57600080fd5b505af115801562000463573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000489919062000506565b505050565b80516001600160a01b0381168114620004a657600080fd5b919050565b600060208284031215620004bd578081fd5b620004c8826200048e565b9392505050565b60008060408385031215620004e2578081fd5b620004ed836200048e565b9150620004fd602084016200048e565b90509250929050565b60006020828403121562000518578081fd5b81518015158114620004c8578182fd5b6000602082840312156200053a578081fd5b5051919050565b608051612ae5620005796000396000818161043d0152818161210d015281816121310152818161239501526123b90152612ae56000f3fe608060405234801561001057600080fd5b50600436106101bb5760003560e01c8063968ed600116100fa578063d23e04801161009d578063d23e0480146103af578063e01fed65146103c7578063e190febc146103d0578063e2df600f146103e3578063e662822e146103f6578063f0fa55a9146103ff578063f302e4bd14610412578063fbfa77cf14610425578063fd967f471461043857600080fd5b8063968ed600146103075780639934bbd714610324578063999d5c6914610337578063a30035b51461033f578063aced16611461035c578063b4bc9d3314610364578063bac426d01461037f578063cb71299f1461039257600080fd5b8063414de39011610162578063414de3901461028d578063458c40d8146102a0578063475a91d1146102b35780634bdaeac1146102c85780635aa6e675146102db5780635fcbd285146102e357806368124f9a146102f65780638c04166f146102fe57600080fd5b806301681a62146101c05780630f149cce146101d55780630fab63ab1461021657806325b0088514610238578063260e18db1461024057806329d5a45c146102575780632b0949ea1461025f5780632cdacb5014610272575b600080fd5b6101d36101ce3660046125fa565b61045f565b005b6000546101f29060ff81169061010090046001600160a01b031682565b6040805192151583526001600160a01b039091166020830152015b60405180910390f35b61022b600080516020612a9083398151915281565b60405161020d919061283b565b6101d36105a6565b61024960045481565b60405190815260200161020d565b61022b610636565b6101d361026d36600461271e565b6106b8565b61022b73f403c135812408bfbe8713b5a23a04b3d48aae3181565b6101d361029b36600461271e565b6106fa565b6101d36102ae3660046126e6565b610792565b61022b600080516020612a7083398151915281565b60085461022b906001600160a01b031681565b61022b6107de565b60075461022b906001600160a01b031681565b6101d3610823565b61024960035481565b61030f6108b2565b6040805192835260208301919091520161020d565b6101d361033236600461271e565b6108c5565b61030f61095d565b60065461034c9060ff1681565b604051901515815260200161020d565b61022b61099e565b61022b73a79828df1850e8a3a3064576f380d90aecdd335981565b6101d361038d3660046125fa565b6109e3565b6001546101f29060ff81169061010090046001600160a01b031682565b60065461022b9061010090046001600160a01b031681565b61024960055481565b6101d36103de36600461271e565b610a7c565b6101d36103f136600461271e565b610abe565b61024960095481565b6101d361040d3660046127cc565b610b00565b61024968327cb2734119d3b7a9601e1b81565b60025461022b906001600160a01b031681565b6102497f000000000000000000000000000000000000000000000000000000000000000081565b6104676107de565b6001600160a01b0316336001600160a01b0316146104a05760405162461bcd60e51b8152600401610497906128f3565b60405180910390fd5b806001600160a01b031663a9059cbb6104b76107de565b6040516370a0823160e01b81526001600160a01b038516906370a08231906104e390309060040161283b565b60206040518083038186803b1580156104fb57600080fd5b505afa15801561050f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053391906127e4565b6040518363ffffffff1660e01b81526004016105509291906128a7565b602060405180830381600087803b15801561056a57600080fd5b505af115801561057e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a29190612702565b5050565b6105ae61099e565b6001600160a01b0316336001600160a01b0316146105de5760405162461bcd60e51b815260040161049790612915565b60005460ff166106245760405162461bcd60e51b815260206004820152601160248201527011115413d4d25517d0d3d3541311551151607a1b6044820152606401610497565b6000805460ff1916905561063480565b565b600254604080516301a47c0960e71b815290516000926001600160a01b03169163d23e0480916004808301926020929190829003018186803b15801561067b57600080fd5b505afa15801561068f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b39190612616565b905090565b6106c061099e565b6001600160a01b0316336001600160a01b0316146106f05760405162461bcd60e51b815260040161049790612915565b6105a28282610e0d565b61070261099e565b6001600160a01b0316336001600160a01b0316146107325760405162461bcd60e51b815260040161049790612915565b60015460ff161561077c5760405162461bcd60e51b815260206004820152601460248201527357495448445241575f494e5f50524f475245535360601b6044820152606401610497565b6001805460ff1916811790556105a28282611048565b61079a6107de565b6001600160a01b0316336001600160a01b0316146107ca5760405162461bcd60e51b8152600401610497906128f3565b6006805460ff191682151517905550565b50565b60025460408051635aa6e67560e01b815290516000926001600160a01b031691635aa6e675916004808301926020929190829003018186803b15801561067b57600080fd5b61082b61099e565b6001600160a01b0316336001600160a01b03161461085b5760405162461bcd60e51b815260040161049790612915565b60015460ff166108a25760405162461bcd60e51b815260206004820152601260248201527115d2551211149055d7d0d3d354131155115160721b6044820152606401610497565b6001805460ff1916905561063480565b6000806108bd61095d565b915091509091565b6108cd61099e565b6001600160a01b0316336001600160a01b0316146108fd5760405162461bcd60e51b815260040161049790612915565b60005460ff16156109465760405162461bcd60e51b81526020600482015260136024820152724445504f5349545f494e5f50524f475245535360681b6044820152606401610497565b6000805460ff191660011790556105a2828261105a565b60065460009081908190819081906109779060ff1661106c565b9194509250905080610989838561296b565b610993919061296b565b954395509350505050565b6002546040805163aced166160e01b815290516000926001600160a01b03169163aced1661916004808301926020929190829003018186803b15801561067b57600080fd5b6109eb6107de565b6001600160a01b0316336001600160a01b031614610a1b5760405162461bcd60e51b8152600401610497906128f3565b6008546001600160a01b0316610a3882610a33610636565b610b75565b816001600160a01b0316816001600160a01b03167f71cae61980b6821adcf07fefce6282528bb04dd92867e49a61deda83fe65c08260405160405180910390a35050565b610a8461099e565b6001600160a01b0316336001600160a01b031614610ab45760405162461bcd60e51b815260040161049790612915565b6105a2828261126c565b610ac661099e565b6001600160a01b0316336001600160a01b031614610af65760405162461bcd60e51b815260040161049790612915565b6105a2828261192c565b610b086107de565b6001600160a01b0316336001600160a01b031614610b385760405162461bcd60e51b8152600401610497906128f3565b600354610b4482600355565b604051829082907f282c65286b5ce3db38b8527661b948d366f1642008bb1f38bfe820cad1003a4290600090a35050565b60068054610100600160a81b0319166101006001600160a01b038481169190910291909117909155600880546001600160a01b03191691841691909117905560408051630176f71760e71b81529051600080516020612a908339815191529163bb7b8b80916004808301926020929190829003018186803b158015610bf957600080fd5b505afa158015610c0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3191906127e4565b60095560075460405163095ea7b360e01b81526001600160a01b039091169063095ea7b390610c7c9073f403c135812408bfbe8713b5a23a04b3d48aae3190600019906004016128a7565b602060405180830381600087803b158015610c9657600080fd5b505af1158015610caa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cce9190612702565b5060065460405163095ea7b360e01b81526101009091046001600160a01b03169063095ea7b390610d1b9073a79828df1850e8a3a3064576f380d90aecdd335990600019906004016128a7565b602060405180830381600087803b158015610d3557600080fd5b505af1158015610d49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6d9190612702565b5060075460405163095ea7b360e01b81526001600160a01b039091169063095ea7b390610db69073a79828df1850e8a3a3064576f380d90aecdd335990600019906004016128a7565b602060405180830381600087803b158015610dd057600080fd5b505af1158015610de4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e089190612702565b505050565b6000610e1b8284018461278b565b6007546040516370a0823160e01b81529192506001600160a01b0316906370a0823190610e4c90309060040161283b565b60206040518083038186803b158015610e6457600080fd5b505afa158015610e78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9c91906127e4565b81511115610ee35760405162461bcd60e51b8152602060048201526014602482015273494e53554646494349454e545f42414c414e434560601b6044820152606401610497565b73f403c135812408bfbe8713b5a23a04b3d48aae316001600160a01b03166343a0d066600080516020612a708339815191526001600160a01b031663f10684546040518163ffffffff1660e01b815260040160206040518083038186803b158015610f4d57600080fd5b505afa158015610f61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8591906127e4565b835160405160e084901b6001600160e01b03191681526004810192909252602482015260016044820152606401602060405180830381600087803b158015610fcc57600080fd5b505af1158015610fe0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110049190612702565b610e085760405162461bcd60e51b815260206004820152601560248201527410d3d395915617d4d51052d25391d7d19052531151605a1b6044820152606401610497565b6110528282611b01565b6105a2610823565b6110648282611d66565b6105a26105a6565b600080600080600080516020612a708339815191526001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016110ac919061283b565b60206040518083038186803b1580156110c457600080fd5b505afa1580156110d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fc91906127e4565b6007546040516370a0823160e01b81529192506000916001600160a01b03909116906370a082319061113290309060040161283b565b60206040518083038186803b15801561114a57600080fd5b505afa15801561115e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118291906127e4565b90506000611190828461296b565b90506000876111a7576111a282611e7f565b6111b0565b6111b082611f33565b9050876111c5576111c083611e7f565b6111ce565b6111ce83611f33565b95506111da86826129c2565b6006546040516370a0823160e01b815291985061010090046001600160a01b0316906370a082319061121090309060040161283b565b60206040518083038186803b15801561122857600080fd5b505afa15801561123c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126091906127e4565b96989597505050505050565b600080516020612a708339815191526001600160a01b0316633d18b9126040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156112b557600080fd5b505af11580156112c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ed9190612702565b61132f5760405162461bcd60e51b81526020600482015260136024820152721c995dd85c990818db185a5b4819985a5b1959606a1b6044820152606401610497565b6006546040516370a0823160e01b815260009161010090046001600160a01b0316906370a082319061136590309060040161283b565b60206040518083038186803b15801561137d57600080fd5b505afa158015611391573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b591906127e4565b90506000600860009054906101000a90046001600160a01b03166001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b15801561140757600080fd5b505afa15801561141b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114439190810190612632565b90506000805b82518110156115645782818151811061147257634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016114a5919061283b565b60206040518083038186803b1580156114bd57600080fd5b505afa1580156114d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f591906127e4565b91508115611552576008548351611552916001600160a01b031690849086908590811061153257634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b0316611fd69092919063ffffffff16565b8061155c81612a05565b915050611449565b50600860009054906101000a90046001600160a01b03166001600160a01b0316634641257d6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156115b557600080fd5b505af11580156115c9573d6000803e3d6000fd5b505050506000600080516020612a908339815191526001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b15801561161657600080fd5b505afa15801561162a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164e91906127e4565b9050600954811115611848576007546040516370a0823160e01b81526000916001600160a01b0316906370a082319061168b90309060040161283b565b60206040518083038186803b1580156116a357600080fd5b505afa1580156116b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116db91906127e4565b6040516370a0823160e01b8152909150600090600080516020612a70833981519152906370a082319061171290309060040161283b565b60206040518083038186803b15801561172a57600080fd5b505afa15801561173e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176291906127e4565b61176c908361296b565b90506000816009548561177f91906129c2565b61178991906129a3565b905060006117978583612983565b90508381111561183957600080516020612a7083398151915263c32e72026117bf86846129c2565b6040516001600160e01b031960e084901b168152600481019190915260016024820152604401602060405180830381600087803b1580156117ff57600080fd5b505af1158015611813573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118379190612702565b505b6118428161202c565b50505050505b60098190556006546040516370a0823160e01b8152859161010090046001600160a01b0316906370a082319061188290309060040161283b565b60206040518083038186803b15801561189a57600080fd5b505afa1580156118ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d291906127e4565b6118dc91906129c2565b6004819055600580546000906118f390849061296b565b90915550506004546040517f7bb2b3c10797baccb6f8c4791f1edd6ca2f0d028ee0eda64b01a9a57e3a653f790600090a2505050505050565b600061193a8284018461278b565b6040516370a0823160e01b8152909150600080516020612a70833981519152906370a082319061196e90309060040161283b565b60206040518083038186803b15801561198657600080fd5b505afa15801561199a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119be91906127e4565b81511115611a075760405162461bcd60e51b8152602060048201526016602482015275414d4f554e545f455843454544535f42414c414e434560501b6044820152606401610497565b805115611a9d578051604051636197390160e11b8152600481019190915260016024820152600080516020612a708339815191529063c32e720290604401602060405180830381600087803b158015611a5f57600080fd5b505af1158015611a73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a979190612702565b50505050565b6040516324f81cd160e11b815260016004820152600080516020612a70833981519152906349f039a290602401600060405180830381600087803b158015611ae457600080fd5b505af1158015611af8573d6000803e3d6000fd5b50505050505050565b6000611b0f8284018461278b565b90506000806000611b20600061106c565b91945092509050600081611b34848661296b565b611b3e919061296b565b90508085600001511115611b50578085525b8451600083821115611cde57611b6684836129c2565b905084811115611cde576000611b7c86836129c2565b90506000611c12611b8c83612205565b6040516370a0823160e01b8152600080516020612a70833981519152906370a0823190611bbd90309060040161283b565b60206040518083038186803b158015611bd557600080fd5b505afa158015611be9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0d91906127e4565b61227c565b604051636197390160e11b81526004810182905260016024820152909150600080516020612a708339815191529063c32e720290604401602060405180830381600087803b158015611c6357600080fd5b505af1158015611c77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c9b9190612702565b611cdb5760405162461bcd60e51b8152602060048201526011602482015270636f756c64206e6f7420756e7374616b6560781b6044820152606401610497565b50505b6000611d1c611cec83612205565b6007546040516370a0823160e01b81526001600160a01b03909116906370a0823190611bbd90309060040161283b565b90508015611d2f57611d2d8161202c565b505b87516040517f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d90600090a250505050505050505050565b6000611d748284018461278b565b6006546040516370a0823160e01b815291925061010090046001600160a01b0316906370a0823190611daa90309060040161283b565b60206040518083038186803b158015611dc257600080fd5b505afa158015611dd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dfa91906127e4565b81511115611e435760405162461bcd60e51b81526020600482015260166024820152751a5b9d985b1a590819195c1bdcda5d08185b5bdd5b9d60521b6044820152606401610497565b8051611e4e90612294565b5080516040517f4d6ce1e535dbade1c23defba91e23b8f791ce5edc0cc320257a2b364e4e3842690600090a2505050565b600081611e8e57506000919050565b6040516341b028f360e01b8152600080516020612a908339815191526004820152602481018390526002604482015273a79828df1850e8a3a3064576f380d90aecdd3359906341b028f3906064015b60206040518083038186803b158015611ef557600080fd5b505afa158015611f09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2d91906127e4565b92915050565b600068327cb2734119d3b7a9601e1b82600080516020612a908339815191526001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b158015611f8a57600080fd5b505afa158015611f9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc291906127e4565b611fcc91906129a3565b611f2d9190612983565b610e088363a9059cbb60e01b8484604051602401611ff59291906128a7565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612414565b60008060029050600068327cb2734119d3b7a9601e1b600080516020612a908339815191526001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b15801561208957600080fd5b505afa15801561209d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c191906127e4565b6120cb90866129a3565b6120d59190612983565b905073a79828df1850e8a3a3064576f380d90aecdd33596001600160a01b03166329ed2862600080516020612a9083398151915286857f00000000000000000000000000000000000000000000000000000000000000006003547f000000000000000000000000000000000000000000000000000000000000000061215a91906129c2565b61216490886129a3565b61216e9190612983565b6040516001600160e01b031960e087901b1681526001600160a01b0390941660048501526024840192909252600f0b604483015260648201526084015b602060405180830381600087803b1580156121c557600080fd5b505af11580156121d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121fd91906127e4565b949350505050565b60008161221457506000919050565b6040805160808101825260008082526020820181905281830185905260608201529051630861cdef60e41b815273a79828df1850e8a3a3064576f380d90aecdd33599163861cdef091611edd91600080516020612a908339815191529160019060040161284f565b600081831061228b578161228d565b825b9392505050565b60008060405180608001604052806000815260200160008152602001848152602001600081525090506000600080516020612a908339815191526001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b15801561230657600080fd5b505afa15801561231a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233e91906127e4565b61235468327cb2734119d3b7a9601e1b866129a3565b61235e9190612983565b905073a79828df1850e8a3a3064576f380d90aecdd33596001600160a01b031663384e03db600080516020612a90833981519152847f00000000000000000000000000000000000000000000000000000000000000006003547f00000000000000000000000000000000000000000000000000000000000000006123e291906129c2565b6123ec90876129a3565b6123f69190612983565b6040518463ffffffff1660e01b81526004016121ab9392919061287c565b6000612469826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166124e69092919063ffffffff16565b805190915015610e0857808060200190518101906124879190612702565b610e085760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610497565b60606121fd8484600085856001600160a01b0385163b6125485760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610497565b600080866001600160a01b03168587604051612564919061281f565b60006040518083038185875af1925050503d80600081146125a1576040519150601f19603f3d011682016040523d82523d6000602084013e6125a6565b606091505b50915091506125b68282866125c1565b979650505050505050565b606083156125d057508161228d565b8251156125e05782518084602001fd5b8160405162461bcd60e51b815260040161049791906128c0565b60006020828403121561260b578081fd5b813561228d81612a4c565b600060208284031215612627578081fd5b815161228d81612a4c565b60006020808385031215612644578182fd5b825167ffffffffffffffff8082111561265b578384fd5b818501915085601f83011261266e578384fd5b81518181111561268057612680612a36565b8060051b915061269184830161293a565b8181528481019084860184860187018a10156126ab578788fd5b8795505b838610156126d957805194506126c485612a4c565b848352600195909501949186019186016126af565b5098975050505050505050565b6000602082840312156126f7578081fd5b813561228d81612a61565b600060208284031215612713578081fd5b815161228d81612a61565b60008060208385031215612730578081fd5b823567ffffffffffffffff80821115612747578283fd5b818501915085601f83011261275a578283fd5b813581811115612768578384fd5b866020828501011115612779578384fd5b60209290920196919550909350505050565b60006020828403121561279c578081fd5b6040516020810181811067ffffffffffffffff821117156127bf576127bf612a36565b6040529135825250919050565b6000602082840312156127dd578081fd5b5035919050565b6000602082840312156127f5578081fd5b5051919050565b8060005b6004811015611a97578151845260209384019390910190600101612800565b600082516128318184602087016129d9565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b038416815260c0810161286c60208301856127fc565b82151560a0830152949350505050565b6001600160a01b038416815260c0810161289960208301856127fc565b8260a0830152949350505050565b6001600160a01b03929092168252602082015260400190565b60208152600082518060208401526128df8160408501602087016129d9565b601f01601f19169190910160400192915050565b60208082526008908201526727a7262cafa3a7ab60c11b604082015260600190565b6020808252600b908201526a27a7262cafa5a2a2a822a960a91b604082015260600190565b604051601f8201601f1916810167ffffffffffffffff8111828210171561296357612963612a36565b604052919050565b6000821982111561297e5761297e612a20565b500190565b60008261299e57634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156129bd576129bd612a20565b500290565b6000828210156129d4576129d4612a20565b500390565b60005b838110156129f45781810151838201526020016129dc565b83811115611a975750506000910152565b6000600019821415612a1957612a19612a20565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146107db57600080fd5b80151581146107db57600080fdfe000000000000000000000000b900ef131301b307db5efcbed9dbb50a3e209b2e000000000000000000000000d632f22692fac7611d2aa1c0d552930d43caed3ba264697066735822122058e2975a36b82c9027fbd14dfc0139e0d82393adfb781345cd5376f82f7ec54264736f6c634300080400330000000000000000000000002022c855ceefd7759dbbb5bb7a8f14c82688646a0000000000000000000000003c4fe0db16c9b521480c43856ba3196a9fa50e08

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101bb5760003560e01c8063968ed600116100fa578063d23e04801161009d578063d23e0480146103af578063e01fed65146103c7578063e190febc146103d0578063e2df600f146103e3578063e662822e146103f6578063f0fa55a9146103ff578063f302e4bd14610412578063fbfa77cf14610425578063fd967f471461043857600080fd5b8063968ed600146103075780639934bbd714610324578063999d5c6914610337578063a30035b51461033f578063aced16611461035c578063b4bc9d3314610364578063bac426d01461037f578063cb71299f1461039257600080fd5b8063414de39011610162578063414de3901461028d578063458c40d8146102a0578063475a91d1146102b35780634bdaeac1146102c85780635aa6e675146102db5780635fcbd285146102e357806368124f9a146102f65780638c04166f146102fe57600080fd5b806301681a62146101c05780630f149cce146101d55780630fab63ab1461021657806325b0088514610238578063260e18db1461024057806329d5a45c146102575780632b0949ea1461025f5780632cdacb5014610272575b600080fd5b6101d36101ce3660046125fa565b61045f565b005b6000546101f29060ff81169061010090046001600160a01b031682565b6040805192151583526001600160a01b039091166020830152015b60405180910390f35b61022b600080516020612a9083398151915281565b60405161020d919061283b565b6101d36105a6565b61024960045481565b60405190815260200161020d565b61022b610636565b6101d361026d36600461271e565b6106b8565b61022b73f403c135812408bfbe8713b5a23a04b3d48aae3181565b6101d361029b36600461271e565b6106fa565b6101d36102ae3660046126e6565b610792565b61022b600080516020612a7083398151915281565b60085461022b906001600160a01b031681565b61022b6107de565b60075461022b906001600160a01b031681565b6101d3610823565b61024960035481565b61030f6108b2565b6040805192835260208301919091520161020d565b6101d361033236600461271e565b6108c5565b61030f61095d565b60065461034c9060ff1681565b604051901515815260200161020d565b61022b61099e565b61022b73a79828df1850e8a3a3064576f380d90aecdd335981565b6101d361038d3660046125fa565b6109e3565b6001546101f29060ff81169061010090046001600160a01b031682565b60065461022b9061010090046001600160a01b031681565b61024960055481565b6101d36103de36600461271e565b610a7c565b6101d36103f136600461271e565b610abe565b61024960095481565b6101d361040d3660046127cc565b610b00565b61024968327cb2734119d3b7a9601e1b81565b60025461022b906001600160a01b031681565b6102497f000000000000000000000000000000000000000000000000000000000000271081565b6104676107de565b6001600160a01b0316336001600160a01b0316146104a05760405162461bcd60e51b8152600401610497906128f3565b60405180910390fd5b806001600160a01b031663a9059cbb6104b76107de565b6040516370a0823160e01b81526001600160a01b038516906370a08231906104e390309060040161283b565b60206040518083038186803b1580156104fb57600080fd5b505afa15801561050f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053391906127e4565b6040518363ffffffff1660e01b81526004016105509291906128a7565b602060405180830381600087803b15801561056a57600080fd5b505af115801561057e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a29190612702565b5050565b6105ae61099e565b6001600160a01b0316336001600160a01b0316146105de5760405162461bcd60e51b815260040161049790612915565b60005460ff166106245760405162461bcd60e51b815260206004820152601160248201527011115413d4d25517d0d3d3541311551151607a1b6044820152606401610497565b6000805460ff1916905561063480565b565b600254604080516301a47c0960e71b815290516000926001600160a01b03169163d23e0480916004808301926020929190829003018186803b15801561067b57600080fd5b505afa15801561068f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b39190612616565b905090565b6106c061099e565b6001600160a01b0316336001600160a01b0316146106f05760405162461bcd60e51b815260040161049790612915565b6105a28282610e0d565b61070261099e565b6001600160a01b0316336001600160a01b0316146107325760405162461bcd60e51b815260040161049790612915565b60015460ff161561077c5760405162461bcd60e51b815260206004820152601460248201527357495448445241575f494e5f50524f475245535360601b6044820152606401610497565b6001805460ff1916811790556105a28282611048565b61079a6107de565b6001600160a01b0316336001600160a01b0316146107ca5760405162461bcd60e51b8152600401610497906128f3565b6006805460ff191682151517905550565b50565b60025460408051635aa6e67560e01b815290516000926001600160a01b031691635aa6e675916004808301926020929190829003018186803b15801561067b57600080fd5b61082b61099e565b6001600160a01b0316336001600160a01b03161461085b5760405162461bcd60e51b815260040161049790612915565b60015460ff166108a25760405162461bcd60e51b815260206004820152601260248201527115d2551211149055d7d0d3d354131155115160721b6044820152606401610497565b6001805460ff1916905561063480565b6000806108bd61095d565b915091509091565b6108cd61099e565b6001600160a01b0316336001600160a01b0316146108fd5760405162461bcd60e51b815260040161049790612915565b60005460ff16156109465760405162461bcd60e51b81526020600482015260136024820152724445504f5349545f494e5f50524f475245535360681b6044820152606401610497565b6000805460ff191660011790556105a2828261105a565b60065460009081908190819081906109779060ff1661106c565b9194509250905080610989838561296b565b610993919061296b565b954395509350505050565b6002546040805163aced166160e01b815290516000926001600160a01b03169163aced1661916004808301926020929190829003018186803b15801561067b57600080fd5b6109eb6107de565b6001600160a01b0316336001600160a01b031614610a1b5760405162461bcd60e51b8152600401610497906128f3565b6008546001600160a01b0316610a3882610a33610636565b610b75565b816001600160a01b0316816001600160a01b03167f71cae61980b6821adcf07fefce6282528bb04dd92867e49a61deda83fe65c08260405160405180910390a35050565b610a8461099e565b6001600160a01b0316336001600160a01b031614610ab45760405162461bcd60e51b815260040161049790612915565b6105a2828261126c565b610ac661099e565b6001600160a01b0316336001600160a01b031614610af65760405162461bcd60e51b815260040161049790612915565b6105a2828261192c565b610b086107de565b6001600160a01b0316336001600160a01b031614610b385760405162461bcd60e51b8152600401610497906128f3565b600354610b4482600355565b604051829082907f282c65286b5ce3db38b8527661b948d366f1642008bb1f38bfe820cad1003a4290600090a35050565b60068054610100600160a81b0319166101006001600160a01b038481169190910291909117909155600880546001600160a01b03191691841691909117905560408051630176f71760e71b81529051600080516020612a908339815191529163bb7b8b80916004808301926020929190829003018186803b158015610bf957600080fd5b505afa158015610c0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3191906127e4565b60095560075460405163095ea7b360e01b81526001600160a01b039091169063095ea7b390610c7c9073f403c135812408bfbe8713b5a23a04b3d48aae3190600019906004016128a7565b602060405180830381600087803b158015610c9657600080fd5b505af1158015610caa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cce9190612702565b5060065460405163095ea7b360e01b81526101009091046001600160a01b03169063095ea7b390610d1b9073a79828df1850e8a3a3064576f380d90aecdd335990600019906004016128a7565b602060405180830381600087803b158015610d3557600080fd5b505af1158015610d49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6d9190612702565b5060075460405163095ea7b360e01b81526001600160a01b039091169063095ea7b390610db69073a79828df1850e8a3a3064576f380d90aecdd335990600019906004016128a7565b602060405180830381600087803b158015610dd057600080fd5b505af1158015610de4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e089190612702565b505050565b6000610e1b8284018461278b565b6007546040516370a0823160e01b81529192506001600160a01b0316906370a0823190610e4c90309060040161283b565b60206040518083038186803b158015610e6457600080fd5b505afa158015610e78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9c91906127e4565b81511115610ee35760405162461bcd60e51b8152602060048201526014602482015273494e53554646494349454e545f42414c414e434560601b6044820152606401610497565b73f403c135812408bfbe8713b5a23a04b3d48aae316001600160a01b03166343a0d066600080516020612a708339815191526001600160a01b031663f10684546040518163ffffffff1660e01b815260040160206040518083038186803b158015610f4d57600080fd5b505afa158015610f61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8591906127e4565b835160405160e084901b6001600160e01b03191681526004810192909252602482015260016044820152606401602060405180830381600087803b158015610fcc57600080fd5b505af1158015610fe0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110049190612702565b610e085760405162461bcd60e51b815260206004820152601560248201527410d3d395915617d4d51052d25391d7d19052531151605a1b6044820152606401610497565b6110528282611b01565b6105a2610823565b6110648282611d66565b6105a26105a6565b600080600080600080516020612a708339815191526001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016110ac919061283b565b60206040518083038186803b1580156110c457600080fd5b505afa1580156110d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fc91906127e4565b6007546040516370a0823160e01b81529192506000916001600160a01b03909116906370a082319061113290309060040161283b565b60206040518083038186803b15801561114a57600080fd5b505afa15801561115e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118291906127e4565b90506000611190828461296b565b90506000876111a7576111a282611e7f565b6111b0565b6111b082611f33565b9050876111c5576111c083611e7f565b6111ce565b6111ce83611f33565b95506111da86826129c2565b6006546040516370a0823160e01b815291985061010090046001600160a01b0316906370a082319061121090309060040161283b565b60206040518083038186803b15801561122857600080fd5b505afa15801561123c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126091906127e4565b96989597505050505050565b600080516020612a708339815191526001600160a01b0316633d18b9126040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156112b557600080fd5b505af11580156112c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ed9190612702565b61132f5760405162461bcd60e51b81526020600482015260136024820152721c995dd85c990818db185a5b4819985a5b1959606a1b6044820152606401610497565b6006546040516370a0823160e01b815260009161010090046001600160a01b0316906370a082319061136590309060040161283b565b60206040518083038186803b15801561137d57600080fd5b505afa158015611391573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b591906127e4565b90506000600860009054906101000a90046001600160a01b03166001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b15801561140757600080fd5b505afa15801561141b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114439190810190612632565b90506000805b82518110156115645782818151811061147257634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016114a5919061283b565b60206040518083038186803b1580156114bd57600080fd5b505afa1580156114d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f591906127e4565b91508115611552576008548351611552916001600160a01b031690849086908590811061153257634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b0316611fd69092919063ffffffff16565b8061155c81612a05565b915050611449565b50600860009054906101000a90046001600160a01b03166001600160a01b0316634641257d6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156115b557600080fd5b505af11580156115c9573d6000803e3d6000fd5b505050506000600080516020612a908339815191526001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b15801561161657600080fd5b505afa15801561162a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164e91906127e4565b9050600954811115611848576007546040516370a0823160e01b81526000916001600160a01b0316906370a082319061168b90309060040161283b565b60206040518083038186803b1580156116a357600080fd5b505afa1580156116b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116db91906127e4565b6040516370a0823160e01b8152909150600090600080516020612a70833981519152906370a082319061171290309060040161283b565b60206040518083038186803b15801561172a57600080fd5b505afa15801561173e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176291906127e4565b61176c908361296b565b90506000816009548561177f91906129c2565b61178991906129a3565b905060006117978583612983565b90508381111561183957600080516020612a7083398151915263c32e72026117bf86846129c2565b6040516001600160e01b031960e084901b168152600481019190915260016024820152604401602060405180830381600087803b1580156117ff57600080fd5b505af1158015611813573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118379190612702565b505b6118428161202c565b50505050505b60098190556006546040516370a0823160e01b8152859161010090046001600160a01b0316906370a082319061188290309060040161283b565b60206040518083038186803b15801561189a57600080fd5b505afa1580156118ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d291906127e4565b6118dc91906129c2565b6004819055600580546000906118f390849061296b565b90915550506004546040517f7bb2b3c10797baccb6f8c4791f1edd6ca2f0d028ee0eda64b01a9a57e3a653f790600090a2505050505050565b600061193a8284018461278b565b6040516370a0823160e01b8152909150600080516020612a70833981519152906370a082319061196e90309060040161283b565b60206040518083038186803b15801561198657600080fd5b505afa15801561199a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119be91906127e4565b81511115611a075760405162461bcd60e51b8152602060048201526016602482015275414d4f554e545f455843454544535f42414c414e434560501b6044820152606401610497565b805115611a9d578051604051636197390160e11b8152600481019190915260016024820152600080516020612a708339815191529063c32e720290604401602060405180830381600087803b158015611a5f57600080fd5b505af1158015611a73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a979190612702565b50505050565b6040516324f81cd160e11b815260016004820152600080516020612a70833981519152906349f039a290602401600060405180830381600087803b158015611ae457600080fd5b505af1158015611af8573d6000803e3d6000fd5b50505050505050565b6000611b0f8284018461278b565b90506000806000611b20600061106c565b91945092509050600081611b34848661296b565b611b3e919061296b565b90508085600001511115611b50578085525b8451600083821115611cde57611b6684836129c2565b905084811115611cde576000611b7c86836129c2565b90506000611c12611b8c83612205565b6040516370a0823160e01b8152600080516020612a70833981519152906370a0823190611bbd90309060040161283b565b60206040518083038186803b158015611bd557600080fd5b505afa158015611be9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0d91906127e4565b61227c565b604051636197390160e11b81526004810182905260016024820152909150600080516020612a708339815191529063c32e720290604401602060405180830381600087803b158015611c6357600080fd5b505af1158015611c77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c9b9190612702565b611cdb5760405162461bcd60e51b8152602060048201526011602482015270636f756c64206e6f7420756e7374616b6560781b6044820152606401610497565b50505b6000611d1c611cec83612205565b6007546040516370a0823160e01b81526001600160a01b03909116906370a0823190611bbd90309060040161283b565b90508015611d2f57611d2d8161202c565b505b87516040517f5b6b431d4476a211bb7d41c20d1aab9ae2321deee0d20be3d9fc9b1093fa6e3d90600090a250505050505050505050565b6000611d748284018461278b565b6006546040516370a0823160e01b815291925061010090046001600160a01b0316906370a0823190611daa90309060040161283b565b60206040518083038186803b158015611dc257600080fd5b505afa158015611dd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dfa91906127e4565b81511115611e435760405162461bcd60e51b81526020600482015260166024820152751a5b9d985b1a590819195c1bdcda5d08185b5bdd5b9d60521b6044820152606401610497565b8051611e4e90612294565b5080516040517f4d6ce1e535dbade1c23defba91e23b8f791ce5edc0cc320257a2b364e4e3842690600090a2505050565b600081611e8e57506000919050565b6040516341b028f360e01b8152600080516020612a908339815191526004820152602481018390526002604482015273a79828df1850e8a3a3064576f380d90aecdd3359906341b028f3906064015b60206040518083038186803b158015611ef557600080fd5b505afa158015611f09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2d91906127e4565b92915050565b600068327cb2734119d3b7a9601e1b82600080516020612a908339815191526001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b158015611f8a57600080fd5b505afa158015611f9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc291906127e4565b611fcc91906129a3565b611f2d9190612983565b610e088363a9059cbb60e01b8484604051602401611ff59291906128a7565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612414565b60008060029050600068327cb2734119d3b7a9601e1b600080516020612a908339815191526001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b15801561208957600080fd5b505afa15801561209d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c191906127e4565b6120cb90866129a3565b6120d59190612983565b905073a79828df1850e8a3a3064576f380d90aecdd33596001600160a01b03166329ed2862600080516020612a9083398151915286857f00000000000000000000000000000000000000000000000000000000000027106003547f000000000000000000000000000000000000000000000000000000000000271061215a91906129c2565b61216490886129a3565b61216e9190612983565b6040516001600160e01b031960e087901b1681526001600160a01b0390941660048501526024840192909252600f0b604483015260648201526084015b602060405180830381600087803b1580156121c557600080fd5b505af11580156121d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121fd91906127e4565b949350505050565b60008161221457506000919050565b6040805160808101825260008082526020820181905281830185905260608201529051630861cdef60e41b815273a79828df1850e8a3a3064576f380d90aecdd33599163861cdef091611edd91600080516020612a908339815191529160019060040161284f565b600081831061228b578161228d565b825b9392505050565b60008060405180608001604052806000815260200160008152602001848152602001600081525090506000600080516020612a908339815191526001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b15801561230657600080fd5b505afa15801561231a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233e91906127e4565b61235468327cb2734119d3b7a9601e1b866129a3565b61235e9190612983565b905073a79828df1850e8a3a3064576f380d90aecdd33596001600160a01b031663384e03db600080516020612a90833981519152847f00000000000000000000000000000000000000000000000000000000000027106003547f00000000000000000000000000000000000000000000000000000000000027106123e291906129c2565b6123ec90876129a3565b6123f69190612983565b6040518463ffffffff1660e01b81526004016121ab9392919061287c565b6000612469826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166124e69092919063ffffffff16565b805190915015610e0857808060200190518101906124879190612702565b610e085760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610497565b60606121fd8484600085856001600160a01b0385163b6125485760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610497565b600080866001600160a01b03168587604051612564919061281f565b60006040518083038185875af1925050503d80600081146125a1576040519150601f19603f3d011682016040523d82523d6000602084013e6125a6565b606091505b50915091506125b68282866125c1565b979650505050505050565b606083156125d057508161228d565b8251156125e05782518084602001fd5b8160405162461bcd60e51b815260040161049791906128c0565b60006020828403121561260b578081fd5b813561228d81612a4c565b600060208284031215612627578081fd5b815161228d81612a4c565b60006020808385031215612644578182fd5b825167ffffffffffffffff8082111561265b578384fd5b818501915085601f83011261266e578384fd5b81518181111561268057612680612a36565b8060051b915061269184830161293a565b8181528481019084860184860187018a10156126ab578788fd5b8795505b838610156126d957805194506126c485612a4c565b848352600195909501949186019186016126af565b5098975050505050505050565b6000602082840312156126f7578081fd5b813561228d81612a61565b600060208284031215612713578081fd5b815161228d81612a61565b60008060208385031215612730578081fd5b823567ffffffffffffffff80821115612747578283fd5b818501915085601f83011261275a578283fd5b813581811115612768578384fd5b866020828501011115612779578384fd5b60209290920196919550909350505050565b60006020828403121561279c578081fd5b6040516020810181811067ffffffffffffffff821117156127bf576127bf612a36565b6040529135825250919050565b6000602082840312156127dd578081fd5b5035919050565b6000602082840312156127f5578081fd5b5051919050565b8060005b6004811015611a97578151845260209384019390910190600101612800565b600082516128318184602087016129d9565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b038416815260c0810161286c60208301856127fc565b82151560a0830152949350505050565b6001600160a01b038416815260c0810161289960208301856127fc565b8260a0830152949350505050565b6001600160a01b03929092168252602082015260400190565b60208152600082518060208401526128df8160408501602087016129d9565b601f01601f19169190910160400192915050565b60208082526008908201526727a7262cafa3a7ab60c11b604082015260600190565b6020808252600b908201526a27a7262cafa5a2a2a822a960a91b604082015260600190565b604051601f8201601f1916810167ffffffffffffffff8111828210171561296357612963612a36565b604052919050565b6000821982111561297e5761297e612a20565b500190565b60008261299e57634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156129bd576129bd612a20565b500290565b6000828210156129d4576129d4612a20565b500390565b60005b838110156129f45781810151838201526020016129dc565b83811115611a975750506000910152565b6000600019821415612a1957612a19612a20565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146107db57600080fd5b80151581146107db57600080fdfe000000000000000000000000b900ef131301b307db5efcbed9dbb50a3e209b2e000000000000000000000000d632f22692fac7611d2aa1c0d552930d43caed3ba264697066735822122058e2975a36b82c9027fbd14dfc0139e0d82393adfb781345cd5376f82f7ec54264736f6c63430008040033

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

0000000000000000000000002022c855ceefd7759dbbb5bb7a8f14c82688646a0000000000000000000000003c4fe0db16c9b521480c43856ba3196a9fa50e08

-----Decoded View---------------
Arg [0] : _harvester (address): 0x2022C855CeefD7759dBbb5bB7A8F14C82688646A
Arg [1] : _vault (address): 0x3c4Fe0db16c9b521480c43856ba3196A9fa50E08

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000002022c855ceefd7759dbbb5bb7a8f14c82688646a
Arg [1] : 0000000000000000000000003c4fe0db16c9b521480c43856ba3196a9fa50e08


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.