Contract 0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d

 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x2c657a72cc640b29360420123c6f7e5634e3084a8773dcdf36dcc14df4778d96Vote581458102023-03-22 18:22:052 days 6 hrs agoTarot: Deployer IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.05076725
0x8bc77c70f31aab36dc94c974b797222114ba2744d6823d4041de62558daf71beProcess Ve Rewar...581450292023-03-22 18:09:012 days 6 hrs agoTarot: Deployer IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.233025
0xc166302482ebcbacde79bf9f87c6e4f82af113b38652111b12fdb5b760d5f744Wrapped Ve Depos...581436412023-03-22 17:41:322 days 7 hrs ago0x35c0c5b748270f36df0b106bc6f0d09124c92623 IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.019504906651
0xf6b669486f07ff15e5f568434b99e02fd6f4822fcb193a8da97ac3dc62347161Wrapped Ve Depos...581434422023-03-22 17:37:242 days 7 hrs ago0x35c0c5b748270f36df0b106bc6f0d09124c92623 IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.0278193073
0xbf70757b030ed03ad9c32d329eec1ad64f09c30776a5abbb5386c9a462f94b87Wrapped Ve Depos...579774652023-03-20 10:50:034 days 14 hrs ago0x060039c5ecc53d1ec684dcab1cd3b4499e9a1d8a IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.013088107806
0xd0eab856238c219523ba5f1926534add2c5f98c3b2a30c66be01611778f4bc4fWrapped Ve Depos...578809952023-03-18 23:24:326 days 1 hr ago0x557947f2d6d592f7861e916c12bd3058ace9cb81 IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.018945731412
0x7dff0109b1faf12035e800e95a1015c43c920be7d4ec5351f40a50efe04cfa57Wrapped Ve Depos...578769812023-03-18 21:54:096 days 3 hrs ago0x07494efb9fc623b74b31714192826c70eba7423f IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.025039457233
0x25acea5153937eaa3a25150beb42968b4b522759241c2fdfae35cb3f7c23e3c4Wrapped Ve Depos...577232712023-03-16 18:57:098 days 6 hrs ago0xdb530f7ce1763eeca60467f080abc858469c2ff7 IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.02310600245
0x984e6808c15fdfeb3ad6e597b65e18ea0333748ea668089af24b9e4920c28041Wrapped Ve Depos...576671302023-03-16 1:04:368 days 23 hrs ago0x07494efb9fc623b74b31714192826c70eba7423f IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.042083219737
0x328a9b8d90bda682ef36741c9fd4822f88c60477401e03b22b10cac578f9d1faWrapped Ve Depos...575815502023-03-14 17:42:4910 days 7 hrs ago0x07494efb9fc623b74b31714192826c70eba7423f IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.089964754986
0x1eefa09c7c19c7e39eb4806e9d7ffb1ef36df968fa7c119e8ac6db48009c55cfWrapped Ve Depos...575773902023-03-14 16:34:5110 days 8 hrs ago0xfc2ea617f5214fdb17caa576837cd044b93959b9 IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.106948321598
0x595ffa4d89db6dfdc230006b563fef14971257237233dd45cc2ffabf805456c3Wrapped Ve Depos...574979562023-03-13 7:44:1011 days 17 hrs ago0xa1165f895e35012e5b8bc6bf8c8078dabc735064 IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.019844365414
0x3ef78b1e111f0de6f4df002d60c6e6a27375ff919e7e08bae9493c00e2c7cc5bVote574048262023-03-11 18:54:1213 days 6 hrs agoTarot: Deployer IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.2436828
0x82ad2d1e330c564a6415a668b662adf041fa7cfe473f623a3557d863b1a7e7a6Process Ve Rewar...574046672023-03-11 18:50:1713 days 6 hrs agoTarot: Deployer IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.4631088
0x7eef9361ba26072decb86cddbc4ab2a22a9388e9cb379d4195d51c38ae40239eWrapped Ve Depos...572392292023-03-09 8:58:4815 days 16 hrs ago0x28c974c18c6553b445c4b77f35d83f3499acf58f IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.077646903203
0x3ccd35a055298d57110101fca7c0a4853858a27d617a07323bdaf23241c6568aProcess Ve Rewar...571256212023-03-07 14:45:4117 days 10 hrs agoTarot: Deployer IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.1005554
0x20625a0ce4a1cff6c42697944a8724cd8e0db8683c5654e6673d73552d7ad75fWrapped Ve Depos...570957222023-03-07 1:35:0517 days 23 hrs ago0x8d1982b9a10f5890d8a669a0f982bb402175bf60 IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.009733362047
0xa7b3473a7dc604f061b9a1f31a5f4b13cc86c0f9f8e8ee3812b02fca277e0c0fWrapped Ve Depos...570300922023-03-06 1:03:0618 days 23 hrs ago0x33072b34a26537f64c4f9a96db35d754a1e8664c IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.017085741207
0x53e7e918bd354e3aa2e62830518137a973e068024def25969b4c1336525b364eVote567582802023-03-01 23:49:2123 days 1 hr agoTarot: Deployer IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.0406138
0x26fef4dd0924a4f1d71ad28bc41b1fdfca1840e45692d1f553f2eb8ea63d01feWrapped Ve Depos...566894682023-02-28 20:36:0224 days 4 hrs ago0x9c1df238a1b1b1f5e3bc5c046201b253d8bf9e3c IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.012230975008
0x494aaa4f4fb74167f1c34c9da9a884ee6b13429cb6eb98f986f5a65528a017d4Wrapped Ve Depos...565232392023-02-26 3:07:3226 days 21 hrs ago0x72d59fa86133d75e5e7c4f32aa90516bdbd605a1 IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.008905253314
0xf5e182e088a74eeded691765e6e5d4bef5dfd286a59f9abfdca380877129a48eVote562447862023-02-21 16:50:2931 days 8 hrs agoTarot: Deployer IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.0406138
0xdffc80b9b85910bf40ae7420807a6e298461bc5e0efe2fcd9c4ae15673b3947dWrapped Ve Depos...561920272023-02-20 22:05:5332 days 2 hrs ago0x9d9d5b53c167155c11b603fbc691b63059a0d472 IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.011648448
0x7de2d9eaa4c129457556fd56738be6bf59196e8ea2e49903c8cd0144580e98c6Wrapped Ve Depos...556857162023-02-13 8:16:2039 days 16 hrs ago0xa1165f895e35012e5b8bc6bf8c8078dabc735064 IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.007184191739
0x6343529dbbac326efeb7d0db80b58de44881ccce889c912a5196f1a3f5fa98b1Wrapped Ve Depos...556808342023-02-13 6:23:1139 days 18 hrs ago0xe13e5cb1fea0d1197ec5b9d50f3ad26c68763f5c IN  0x44f7688aba71e462ac44fb2424b6e0cd83e0d47d0 FTM0.007007514885
[ Download CSV Export 
Latest 1 internal transaction
Parent Txn Hash Block From To Value
0x7822d788c1500aa08b9fa8372879b886ae2c3af42f126b1d2494b1e44a8750e3453223742022-08-20 18:48:35216 days 6 hrs ago Tarot: Deployer  Contract Creation0 FTM
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
GaugeVaultProxyAdmin

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 21 : GaugeVaultProxyAdmin.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

import "./interfaces/IGaugeProxy.sol";
import "./interfaces/IOptiSwap.sol";
import "./interfaces/IGaugeVaultProxy.sol";
import "./interfaces/IVeToken.sol";
import "./interfaces/IWrappedVotingEscrowToken.sol";
import "./interfaces/ITokenDistributor.sol";
import "./interfaces/IDelegateRegistry.sol";
import "./interfaces/IGauge.sol";
import "./interfaces/IBaseV1Pair.sol";

import "./interfaces/ISpiritV2VaultTokenFactory.sol";
import "./interfaces/IVaultToken.sol";

interface OptiSwapPair {
    function swap(
        uint amount0Out,
        uint amount1Out,
        address to,
        bytes calldata data
    ) external;
}

contract GaugeVaultProxyAdmin is Ownable, ReentrancyGuard {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    uint256 public constant GRACE_PERIOD = 14 days;
    uint256 public constant MIN_DELAY = 3 days;
    uint256 public constant MAX_DELAY = 30 days;

    uint256 constant MAX_BPS = 10_000;
    uint256 constant MIN_VELOCK_BPS = 0;
    uint256 constant MAX_VELOCK_BPS = MAX_BPS / 2;

    uint256 public veLockBps = (MAX_BPS * 15) / 100; // 15%

    ISpiritV2VaultTokenFactory public vaultTokenFactory;
    IGaugeVaultProxy public gaugeVaultProxy;
    IVeToken public veToken;
    IERC20 public rewardToken;
    address public wrappedVeToken;
    address public tokenDistributor;
    address public optiSwap;
    address public manager;
    address public gaugeProxyAdmin;
    address public pendingGaugeProxyAdmin;
    uint256 public pendingGaugeProxyAdminNotBefore;

    IGaugeProxy[] m_gaugeProxyList;
    mapping(IGaugeProxy => bool) m_gaugeProxyEnabled;

    mapping(address => address) public getGauge;

    event UpdatePendingGaugeProxyAdmin(address indexed gaugeProxyAdmin, uint256 notBefore);
    event UpdateGaugeProxyAdmin(address indexed gaugeProxyAdmin);
    event UpdateVeLockBps(uint256 _newVeLockBps);
    event DepositInGauge(address vaultToken, address gauge, uint256 amount);
    event WithdrawFromGauge(address vaultToken, address gauge, uint256 amount);
    event ClaimGaugeReward(address vaultToken, address gauge, uint256 rewardTokenAmount);

    constructor(
        address _gaugeVaultProxy,
        address _veToken,
        address _wrappedVeToken,
        address _tokenDistributor,
        address _optiSwap
    ) public {
        gaugeVaultProxy = IGaugeVaultProxy(_gaugeVaultProxy);
        veToken = IVeToken(_veToken);
        rewardToken = IERC20(veToken.token());
        wrappedVeToken = _wrappedVeToken;
        tokenDistributor = _tokenDistributor;
        optiSwap = _optiSwap;
        gaugeProxyAdmin = msg.sender;
    }

    function setVaultTokenFactory(address _vaultTokenFactory) external onlyOwner {
        require(address(vaultTokenFactory) == address(0), "GaugeVaultProxyAdmin: FACTORY_ALREADY_SET");
        vaultTokenFactory = ISpiritV2VaultTokenFactory(_vaultTokenFactory);
    }

    function removeGaugeProxyAdmin() external onlyOwner {
        gaugeProxyAdmin = address(0);
        delete pendingGaugeProxyAdmin;
        delete pendingGaugeProxyAdminNotBefore;

        emit UpdateGaugeProxyAdmin(gaugeProxyAdmin);
    }

    function updatePendingGaugeProxyAdmin(address _newPendingGaugeProxyAdmin, uint256 _notBefore)
        external
        onlyOwner
        nonReentrant
    {
        if (_newPendingGaugeProxyAdmin == address(0)) {
            require(_notBefore == 0, "GaugeVaultProxyAdmin: NOT_BEFORE");
        } else {
            require(_newPendingGaugeProxyAdmin != gaugeProxyAdmin, "GaugeVaultProxyAdmin: SAME_ADMIN");
            require(_notBefore >= block.timestamp + MIN_DELAY, "GaugeVaultProxyAdmin: TOO_SOON");
            require(_notBefore < block.timestamp + MAX_DELAY, "GaugeVaultProxyAdmin: TOO_LATE");
        }

        pendingGaugeProxyAdmin = _newPendingGaugeProxyAdmin;
        pendingGaugeProxyAdminNotBefore = _notBefore;

        emit UpdatePendingGaugeProxyAdmin(_newPendingGaugeProxyAdmin, _notBefore);
    }

    function updateGaugeProxyAdmin() external onlyOwner nonReentrant {
        require(pendingGaugeProxyAdmin != address(0), "GaugeVaultProxyAdmin: INVLD_ADMIN");
        require(block.timestamp >= pendingGaugeProxyAdminNotBefore, "GaugeVaultProxyAdmin: TOO_SOON");
        require(block.timestamp < pendingGaugeProxyAdminNotBefore + GRACE_PERIOD, "GaugeVaultProxyAdmin: TOO_LATE");
        require(pendingGaugeProxyAdmin != gaugeProxyAdmin, "GaugeVaultProxyAdmin: SAME_ADMIN");

        gaugeProxyAdmin = pendingGaugeProxyAdmin;
        delete pendingGaugeProxyAdmin;
        delete pendingGaugeProxyAdminNotBefore;

        emit UpdateGaugeProxyAdmin(gaugeProxyAdmin);
    }

    function updateOptiSwap(address _optiSwap) external onlyOwner {
        optiSwap = _optiSwap;
    }

    function updateManager(address _manager) external onlyOwner {
        manager = _manager;
    }

    function updateVeLockBps(uint256 _newVeLockBps) external onlyOwnerOrManager {
        require(
            _newVeLockBps >= MIN_VELOCK_BPS && _newVeLockBps <= MAX_VELOCK_BPS,
            "GaugeVaultProxyAdmin: INVLD_VELOCK"
        );
        veLockBps = _newVeLockBps;

        emit UpdateVeLockBps(_newVeLockBps);
    }

    function gaugeBalanceOf(address _vaultToken) public view returns (uint256) {
        IVaultToken vaultToken = IVaultToken(_vaultToken);
        address underlying = vaultToken.underlying();
        return IGauge(getGauge[underlying]).balanceOf(address(gaugeVaultProxy));
    }

    function gaugeProxyListLength() external view returns (uint256) {
        return m_gaugeProxyList.length;
    }

    function gaugeProxyListItem(uint256 index) external view returns (IGaugeProxy) {
        return m_gaugeProxyList[index];
    }

    function gaugeProxyEnabled(IGaugeProxy gaugeProxy) external view returns (bool) {
        return m_gaugeProxyEnabled[gaugeProxy];
    }

    function _addGaugeProxy(IGaugeProxy gaugeProxy) internal {
        require(!m_gaugeProxyEnabled[gaugeProxy], "GaugeVaultProxyAdmin: GAUGE_PROXY_ENABLED");

        m_gaugeProxyEnabled[gaugeProxy] = true;
        m_gaugeProxyList.push(gaugeProxy);
    }

    function addGaugeProxy(IGaugeProxy gaugeProxy) external onlyGaugeProxyAdmin {
        _addGaugeProxy(gaugeProxy);
    }

    function addGaugeProxies(IGaugeProxy[] calldata gaugeProxyList) external onlyGaugeProxyAdmin {
        for (uint256 i = 0; i < gaugeProxyList.length; i++) {
            IGaugeProxy gaugeProxy = gaugeProxyList[i];
            _addGaugeProxy(gaugeProxy);
        }
    }

    function _indexOfGaugeProxy(IGaugeProxy gaugeProxy) internal view returns (uint256 index) {
        uint256 count = m_gaugeProxyList.length;
        for (uint256 i = 0; i < count; i++) {
            if (m_gaugeProxyList[i] == gaugeProxy) {
                return i;
            }
        }
        require(false, "GaugeVaultProxyAdmin: GAUGE_PROXY_NOT_FOUND");
    }

    function removeGaugeProxy(IGaugeProxy gaugeProxy) external onlyGaugeProxyAdmin {
        require(m_gaugeProxyEnabled[gaugeProxy], "GaugeVaultProxyAdmin: GAUGE_PROXY_ENABLED");

        uint256 index = _indexOfGaugeProxy(gaugeProxy);
        IGaugeProxy last = m_gaugeProxyList[m_gaugeProxyList.length - 1];
        m_gaugeProxyList[index] = last;
        m_gaugeProxyList.pop();
        delete m_gaugeProxyEnabled[gaugeProxy];
    }

    function setGauge(address _underlying, address _gaugeProxy) external onlyOwnerOrManager {
        require(!IBaseV1Pair(_underlying).stable(), "GaugeVaultProxyAdmin: STABLE");
        require(m_gaugeProxyEnabled[IGaugeProxy(_gaugeProxy)], "GaugeVaultProxyAdmin: GAUGE_PROXY_ENABLED");
        address gaugeTo = IGaugeProxy(_gaugeProxy).getGauge(_underlying);
        require(gaugeTo != address(0), "GaugeVaultProxyAdmin: NO_GAUGE");
        address gaugeFrom = getGauge[_underlying];
        if (gaugeFrom != address(0)) {
            require(IGauge(gaugeFrom).gaugeProxy() != _gaugeProxy);
            migrateGauge(_underlying, gaugeFrom, gaugeTo);
        }
        getGauge[_underlying] = gaugeTo;
    }

    function migrateGauge(
        address _underlying,
        address _gaugeFrom,
        address _gaugeTo
    ) internal {
        IGauge gaugeFrom = IGauge(_gaugeFrom);
        uint256 amount = gaugeFrom.balanceOf(address(gaugeVaultProxy));
        if (amount > 0) {
            gvpGaugeWithdraw(gaugeFrom, amount);
            IERC20 underlying = IERC20(_underlying);
            uint256 underlyingBalanceAfter = underlying.balanceOf(address(gaugeVaultProxy));
            require(underlyingBalanceAfter >= amount, "GaugeVaultProxyAdmin: INSUFFICIENT_BALANCE");
            gvpSafeApprove(underlying, address(_gaugeTo), amount);
            gvpGaugeDeposit(IGauge(_gaugeTo), amount);
        }
    }

    function depositInGauge(uint256 _amount) external onlyVaultToken nonReentrant {
        IVaultToken vaultToken = IVaultToken(msg.sender);
        IERC20 underlying = IERC20(vaultToken.underlying());
        IGauge gauge = IGauge(getGauge[address(underlying)]);
        underlying.safeTransferFrom(address(vaultToken), address(gaugeVaultProxy), _amount);
        gvpSafeApprove(underlying, address(gauge), _amount);
        gvpGaugeDeposit(gauge, _amount);
        emit DepositInGauge(msg.sender, address(gauge), _amount);
    }

    function withdrawFromGauge(uint256 _amount) external onlyVaultToken nonReentrant {
        require(_amount > 0, "GaugeVaultProxyAdmin: AMOUNT_ZERO");
        IVaultToken vaultToken = IVaultToken(msg.sender);
        IERC20 underlying = IERC20(vaultToken.underlying());
        IGauge gauge = IGauge(getGauge[address(underlying)]);
        gvpGaugeWithdraw(gauge, _amount);
        uint256 underlyingBalanceAfter = underlying.balanceOf(address(gaugeVaultProxy));
        require(underlyingBalanceAfter >= _amount, "GaugeVaultProxyAdmin: INSUFFICIENT_BALANCE");
        gvpSafeTransfer(underlying, msg.sender, _amount);
        emit WithdrawFromGauge(msg.sender, address(gauge), _amount);
    }

    function claimGaugeReward() external onlyVaultToken nonReentrant {
        IVaultToken vaultToken = IVaultToken(msg.sender);
        IGauge gauge = IGauge(getGauge[vaultToken.underlying()]);
        uint256 rewardTokenBalanceBefore = rewardToken.balanceOf(address(gaugeVaultProxy));
        gvpGaugeGetReward(gauge);
        uint256 rewardTokenBalanceAfter = rewardToken.balanceOf(address(gaugeVaultProxy));
        uint256 rewardTokenAmount = rewardTokenBalanceAfter.sub(rewardTokenBalanceBefore);
        if (rewardTokenAmount > 0) {
            uint256 lockAmount = rewardTokenAmount.mul(veLockBps).div(MAX_BPS);
            uint256 xferAmount = rewardTokenAmount.sub(lockAmount);
            gvpSafeTransfer(rewardToken, msg.sender, xferAmount);
        }
        emit ClaimGaugeReward(msg.sender, address(gauge), rewardTokenAmount);
    }

    function wrappedVeDeposit(uint256 _amount) external {
        require(_amount > 0, "GaugeVaultProxyAdmin: AMOUNT_ZERO");
        (address pair, uint256 amountOut) = IOptiSwap(optiSwap).getBestAmountOut(
            _amount,
            address(rewardToken),
            wrappedVeToken
        );
        if (pair != address(0) && amountOut > _amount) {
            // Swap
            rewardToken.safeTransferFrom(msg.sender, pair, _amount);
            if (address(rewardToken) < wrappedVeToken) {
                OptiSwapPair(pair).swap(0, amountOut, msg.sender, new bytes(0));
            } else {
                OptiSwapPair(pair).swap(amountOut, 0, msg.sender, new bytes(0));
            }
        } else {
            // Mint
            rewardToken.safeTransferFrom(msg.sender, address(gaugeVaultProxy), _amount);
            gaugeVaultProxy.increaseAmount(_amount);
            IWrappedVotingEscrowToken(wrappedVeToken).mint(msg.sender, _amount);
        }
    }

    function processVeRewards(address _feeDistributor) external onlyOwnerOrManager {
        ITokenDistributor(tokenDistributor).claim();
        if (_feeDistributor != address(0)) {
            gaugeVaultProxy.claimVeTokenReward(_feeDistributor);
        }
        uint256 amount = rewardToken.balanceOf(address(gaugeVaultProxy));
        require(amount > 0, "GaugeVaultProxyAdmin: AMOUNT_ZERO");
        (address pair, uint256 amountOut) = IOptiSwap(optiSwap).getBestAmountOut(
            amount,
            address(rewardToken),
            wrappedVeToken
        );
        if (pair != address(0) && amountOut > amount) {
            // Swap
            gaugeVaultProxy.withdrawRewardToken(amount);
            rewardToken.safeTransfer(pair, amount);
            if (address(rewardToken) < wrappedVeToken) {
                OptiSwapPair(pair).swap(0, amountOut, tokenDistributor, new bytes(0));
            } else {
                OptiSwapPair(pair).swap(amountOut, 0, tokenDistributor, new bytes(0));
            }
        } else {
            // Mint
            gaugeVaultProxy.increaseAmount(amount);
            IWrappedVotingEscrowToken(wrappedVeToken).mint(tokenDistributor, amount);
        }
    }

    function vote(
        address gaugeProxy,
        address[] calldata _tokenVote,
        uint256[] calldata _weights
    ) external onlyOwnerOrManager {
        gvpGaugeProxyVote(IGaugeProxy(gaugeProxy), _tokenVote, _weights);
    }

    function inCaseTokensGetStuck(address _token, uint256 _amount) external onlyOwnerOrManager nonReentrant {
        IERC20(_token).safeTransfer(msg.sender, _amount);
    }

    function gvpExecute(address to, bytes memory data) internal returns (bytes memory) {
        (bool success, bytes memory result) = gaugeVaultProxy.execute(to, 0, data);
        require(success == true, "GaugeVaultProxyAdmin: EXECUTE_FAILED");
        return result;
    }

    function gvpSafeTransfer(
        IERC20 token,
        address to,
        uint256 amount
    ) internal {
        bytes memory returndata = gvpExecute(
            address(token),
            abi.encodeWithSelector(token.transfer.selector, to, amount)
        );
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "GaugeVaultProxyAdmin: SAFE_XFER_FAILED");
        }
    }

    function gvpApprove(
        IERC20 token,
        address to,
        uint256 amount
    ) internal {
        bytes memory returndata = gvpExecute(
            address(token),
            abi.encodeWithSelector(token.approve.selector, to, amount)
        );
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "GaugeVaultProxyAdmin: APPROVE_FAILED");
        }
    }

    function gvpSafeApprove(
        IERC20 token,
        address to,
        uint256 amount
    ) internal {
        gvpApprove(token, to, 0);
        gvpApprove(token, to, amount);
    }

    function gvpGaugeGetReward(IGauge gauge) internal {
        gvpExecute(address(gauge), abi.encodeWithSelector(gauge.getReward.selector));
    }

    function gvpGaugeDeposit(IGauge gauge, uint256 amount) internal {
        gvpExecute(address(gauge), abi.encodeWithSelector(gauge.deposit.selector, amount));
    }

    function gvpGaugeWithdraw(IGauge gauge, uint256 amount) internal {
        gvpExecute(address(gauge), abi.encodeWithSelector(gauge.withdraw.selector, amount));
    }

    function gvpGaugeProxyVote(
        IGaugeProxy gaugeProxy,
        address[] calldata _tokenVote,
        uint256[] calldata _weights
    ) internal {
        gvpExecute(address(gaugeProxy), abi.encodeWithSelector(gaugeProxy.vote.selector, _tokenVote, _weights));
    }

    function gvpClearDelegate(address _delegateRegistry, bytes32 _id) external onlyOwnerOrManager {
        _gvpClearDelegate(IDelegateRegistry(_delegateRegistry), _id);
    }

    function gvpSetDelegate(
        address _delegateRegistry,
        bytes32 _id,
        address _delegate
    ) external onlyOwnerOrManager {
        _gvpSetDelegate(IDelegateRegistry(_delegateRegistry), _id, _delegate);
    }

    function _gvpClearDelegate(IDelegateRegistry _delegateRegistry, bytes32 _id) internal {
        gvpExecute(address(_delegateRegistry), abi.encodeWithSelector(_delegateRegistry.clearDelegate.selector, _id));
    }

    function _gvpSetDelegate(
        IDelegateRegistry _delegateRegistry,
        bytes32 _id,
        address _delegate
    ) internal {
        gvpExecute(
            address(_delegateRegistry),
            abi.encodeWithSelector(_delegateRegistry.setDelegate.selector, _id, _delegate)
        );
    }

    modifier onlyOwnerOrManager() {
        require(msg.sender == owner() || msg.sender == manager, "GaugeVaultProxyAdmin: RESTRICTED");
        _;
    }

    modifier onlyVaultToken() {
        require(
            msg.sender == vaultTokenFactory.getVaultToken(IVaultToken(msg.sender).underlying()),
            "GaugeVaultProxyAdmin: ONLY_VAULT_TOKEN"
        );
        _;
    }

    modifier onlyGaugeProxyAdmin() {
        require(msg.sender == gaugeProxyAdmin, "GaugeVaultProxyAdmin: ONLY_GAUGE_PROXY_ADMIN");
        _;
    }
}

File 2 of 21 : ERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

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

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20 {
    using SafeMath for uint256;

    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
     * a default value of 18.
     *
     * To select a different value for {decimals}, use {_setupDecimals}.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name_, string memory symbol_) public {
        _name = name_;
        _symbol = symbol_;
        _decimals = 18;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
     * called.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual returns (uint8) {
        return _decimals;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Sets {decimals} to a value other than the default one of 18.
     *
     * WARNING: This function should only be called from the constructor. Most
     * applications that interact with token contracts will not expect
     * {decimals} to ever change, and may work incorrectly if it does.
     */
    function _setupDecimals(uint8 decimals_) internal virtual {
        _decimals = decimals_;
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}

File 3 of 21 : SafeERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

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

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

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

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

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

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

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

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

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

File 4 of 21 : SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

File 5 of 21 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "../utils/Context.sol";
/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

File 6 of 21 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor () internal {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 7 of 21 : IGaugeProxy.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.12;

interface IGaugeProxy {
    function getGauge(address _token) external view returns (address);

    function tokens() external view returns (address[] memory);

    function vote(address[] calldata _tokenVote, uint256[] calldata _weights) external;
}

File 8 of 21 : IOptiSwap.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;

interface IOptiSwap {
    function weth() external view returns (address);

    function bridgeFromTokens(uint256 index) external view returns (address token);

    function bridgeFromTokensLength() external view returns (uint256);

    function getBridgeToken(address _token) external view returns (address bridgeToken);

    function addBridgeToken(address _token, address _bridgeToken) external;

    function getDexInfo(uint256 index) external view returns (address dex, address handler);

    function dexListLength() external view returns (uint256);

    function indexOfDex(address _dex) external view returns (uint256);

    function getDexEnabled(address _dex) external view returns (bool);

    function addDex(address _dex, address _handler) external;

    function removeDex(address _dex) external;

    function getBestAmountOut(
        uint256 _amountIn,
        address _tokenIn,
        address _tokenOut
    ) external view returns (address pair, uint256 amountOut);
}

File 9 of 21 : IGaugeVaultProxy.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.12;

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

import "./IMasterChefProxy.sol";
import "./IGauge.sol";
import "./IVaultToken.sol";

interface IGaugeVaultProxy is IMasterChefProxy {
    function manager() external view returns (address);

    function admin() external view returns (address);

    function pendingAdmin() external view returns (address);

    function pendingAdminNotBefore() external view returns (uint256);

    function veLockBps() external view returns (uint256);

    function removeAdmin() external;

    function updatePendingAdmin(address _newPendingAdmin, uint256 _notBefore) external;

    function updateAdmin() external;

    function updateManager(address _manager) external;

    function setVaultTokenFactory(address _vaultTokenFactory) external;

    function updateVeLockBps(uint256 _newVeLockBps) external;

    function getUnderlying(uint256 _pid) external view returns (IERC20 underlying);

    function getGauge(uint _pid) external view returns (IGauge gauge);

    function getVaultToken(uint _pid) external view returns (IVaultToken vaultToken);

    function createLock(uint256 _amount, uint256 _unlockTime) external;

    function release() external;

    function increaseAmount(uint256 _amount) external;

    function increaseTime(uint256 _unlockTime) external;

    function claimVeTokenReward(address _feeDistributor) external;

    function vote(address[] calldata _tokenVote, uint256[] calldata _weights) external;

    function withdrawRewardToken(uint256 _amount) external;

    function inCaseTokensGetStuck(address _token, uint256 _amount) external;

    function execute(
        address to,
        uint256 value,
        bytes calldata data
    ) external returns (bool, bytes memory);

    event UpdatePendingAdmin(address indexed admin, uint256 notBefore);
    event UpdateAdmin(address indexed admin);

    event UpdateVeLockBps(uint256 _newVeLockFeeBps);
    event Deposit(address indexed user, uint256 indexed pid, uint256 amount);
    event Withdraw(address indexed user, uint256 indexed pid, uint256 amount);

    event CreateLock(address indexed user, uint256 amount, uint256 unlockTime);
    event Release(address indexed user, uint256 amount, uint256 balanceAfter);
    event IncreaseAmount(address indexed user, uint256 amount);
    event IncreaseTime(address indexed user, uint256 unlockTime);
    event ClaimVeTokenReward(address indexed user, address indexed feeDistributor, uint256 amount);
}

File 10 of 21 : IVeToken.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.12;

interface IVeToken {
    function create_lock(uint256 _amount, uint256 _unlockTime) external;

    function increase_amount(uint256 _amount) external;

    function increase_unlock_time(uint256 _unlockTime) external;

    function withdraw() external;

    function locked__end(address _user) external view returns (uint256);

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

    function token() external view returns (address);
}

File 11 of 21 : IWrappedVotingEscrowToken.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;

interface IWrappedVotingEscrowToken {
    function manager() external view returns (address);

    function setManager(address _manager) external;

    function mint(address _to, uint256 _amount) external;

    function burn(address _from, uint256 _amount) external;
}

File 12 of 21 : ITokenDistributor.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.12;

interface ITokenDistributor {
    function token() external view returns (address);

    function xToken() external view returns (address);

    function periodLength() external view returns (uint);

    function lastClaim() external view returns (uint);

    function claim() external returns (uint amount);

    function setPeriodLength(uint newPeriodLength) external;

    event Claim(uint previousBalance, uint timeElapsed, uint amount);
    event NewPeriodLength(uint oldPeriodLength, uint newPeriodLength);
}

File 13 of 21 : IDelegateRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;

interface IDelegateRegistry {
    function clearDelegate(bytes32 _id) external;

    function setDelegate(bytes32 _id, address _delegate) external;

    function delegation(address _address, bytes32 _id) external view returns (address);
}

File 14 of 21 : IGauge.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.12;

interface IGauge {
    function deposit(uint256 _amount) external;

    function depositFor(uint256 _amount, address _account) external;

    function withdraw(uint256 _amount) external;

    function withdrawAll() external;

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

    function derivedBalance(address account) external view returns (uint);

    function earned(address _account) external view returns (uint256);

    function getReward() external;

    function vote(address[] calldata _tokenVote, uint256[] calldata _weights) external;

    function gaugeProxy() external view returns (address);
}

File 15 of 21 : IBaseV1Pair.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;

interface IBaseV1Pair {
    function claimFees() external returns (uint, uint);

    function tokens() external returns (address, address);

    function stable() external returns (bool);
}

File 16 of 21 : ISpiritV2VaultTokenFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;

interface ISpiritV2VaultTokenFactory {
    function getVaultToken(address) external view returns (address);
}

File 17 of 21 : IVaultToken.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.6.12;

interface IVaultToken {
    /*** Tarot ERC20 ***/

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    function name() external pure returns (string memory);

    function symbol() external pure returns (string memory);

    function decimals() external pure returns (uint8);

    function totalSupply() external view returns (uint256);

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

    function allowance(address owner, address spender) external view returns (uint256);

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

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function PERMIT_TYPEHASH() external pure returns (bytes32);

    function nonces(address owner) external view returns (uint256);

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /*** Pool Token ***/

    event Mint(address indexed sender, address indexed minter, uint256 mintAmount, uint256 mintTokens);
    event Redeem(address indexed sender, address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens);
    event Sync(uint256 totalBalance);

    function underlying() external view returns (address);

    function factory() external view returns (address);

    function totalBalance() external view returns (uint256);

    function MINIMUM_LIQUIDITY() external pure returns (uint256);

    function exchangeRate() external view returns (uint256);

    function mint(address minter) external returns (uint256 mintTokens);

    function redeem(address redeemer) external returns (uint256 redeemAmount);

    function skim(address to) external;

    function sync() external;

    function _setFactory() external;

    /*** VaultToken ***/

    event Reinvest(address indexed caller, uint256 reward, uint256 bounty);

    function isVaultToken() external pure returns (bool);

    function router() external view returns (address);

    function masterChef() external view returns (address);

    function rewardsToken() external view returns (address);

    function WETH() external view returns (address);

    function token0() external view returns (address);

    function token1() external view returns (address);

    function swapFeeFactor() external view returns (uint256);

    function pid() external view returns (uint256);

    function REINVEST_BOUNTY() external pure returns (uint256);

    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );

    function price0CumulativeLast() external view returns (uint256);

    function price1CumulativeLast() external view returns (uint256);

    function _initialize(
        address _router,
        address _masterChef,
        address _rewardsToken,
        uint256 _swapFeeFactor,
        uint256 _pid
    ) external;

    function reinvest() external;
}

File 18 of 21 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 19 of 21 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

File 20 of 21 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 21 of 21 : IMasterChefProxy.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;

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

interface IMasterChefProxy {
    // Info of each user.
    struct UserInfo {
        uint256 amount; // How many LP tokens the user has provided.
        uint256 rewardDebt; // Reward debt. See explanation below.
    }

    // Info of each pool.
    struct PoolInfo {
        IERC20 lpToken; // Address of LP token contract.
        uint256 allocPoint; // How many allocation points assigned to this pool. Reward tokens to distribute per block.
        uint256 lastRewardBlock; // Last block number that reward token distribution occurs.
        uint256 accRewardTokenPerShare; // Accumulated reward tokens per share, times 1e12. See below.
    }

    // Info of each user that stakes LP tokens.
    function poolInfo(uint256 _pid) external view returns (PoolInfo memory);

    function userInfo(uint256 _pid, address _address) external view returns (UserInfo memory);

    // Deposit LP tokens to MasterChef.
    function deposit(uint256 _pid, uint256 _amount) external;

    // Withdraw LP tokens from MasterChef.
    function withdraw(uint256 _pid, uint256 _amount) external;
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_gaugeVaultProxy","type":"address"},{"internalType":"address","name":"_veToken","type":"address"},{"internalType":"address","name":"_wrappedVeToken","type":"address"},{"internalType":"address","name":"_tokenDistributor","type":"address"},{"internalType":"address","name":"_optiSwap","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"vaultToken","type":"address"},{"indexed":false,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"rewardTokenAmount","type":"uint256"}],"name":"ClaimGaugeReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"vaultToken","type":"address"},{"indexed":false,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DepositInGauge","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"gaugeProxyAdmin","type":"address"}],"name":"UpdateGaugeProxyAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"gaugeProxyAdmin","type":"address"},{"indexed":false,"internalType":"uint256","name":"notBefore","type":"uint256"}],"name":"UpdatePendingGaugeProxyAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_newVeLockBps","type":"uint256"}],"name":"UpdateVeLockBps","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"vaultToken","type":"address"},{"indexed":false,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawFromGauge","type":"event"},{"inputs":[],"name":"GRACE_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IGaugeProxy[]","name":"gaugeProxyList","type":"address[]"}],"name":"addGaugeProxies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IGaugeProxy","name":"gaugeProxy","type":"address"}],"name":"addGaugeProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimGaugeReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositInGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vaultToken","type":"address"}],"name":"gaugeBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gaugeProxyAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IGaugeProxy","name":"gaugeProxy","type":"address"}],"name":"gaugeProxyEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"gaugeProxyListItem","outputs":[{"internalType":"contract IGaugeProxy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gaugeProxyListLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gaugeVaultProxy","outputs":[{"internalType":"contract IGaugeVaultProxy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"getGauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_delegateRegistry","type":"address"},{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"gvpClearDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegateRegistry","type":"address"},{"internalType":"bytes32","name":"_id","type":"bytes32"},{"internalType":"address","name":"_delegate","type":"address"}],"name":"gvpSetDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"inCaseTokensGetStuck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"optiSwap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGaugeProxyAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGaugeProxyAdminNotBefore","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_feeDistributor","type":"address"}],"name":"processVeRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IGaugeProxy","name":"gaugeProxy","type":"address"}],"name":"removeGaugeProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"removeGaugeProxyAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_underlying","type":"address"},{"internalType":"address","name":"_gaugeProxy","type":"address"}],"name":"setGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vaultTokenFactory","type":"address"}],"name":"setVaultTokenFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenDistributor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateGaugeProxyAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_manager","type":"address"}],"name":"updateManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_optiSwap","type":"address"}],"name":"updateOptiSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newPendingGaugeProxyAdmin","type":"address"},{"internalType":"uint256","name":"_notBefore","type":"uint256"}],"name":"updatePendingGaugeProxyAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newVeLockBps","type":"uint256"}],"name":"updateVeLockBps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vaultTokenFactory","outputs":[{"internalType":"contract ISpiritV2VaultTokenFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"veLockBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"veToken","outputs":[{"internalType":"contract IVeToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"gaugeProxy","type":"address"},{"internalType":"address[]","name":"_tokenVote","type":"address[]"},{"internalType":"uint256[]","name":"_weights","type":"uint256[]"}],"name":"vote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawFromGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"wrappedVeDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wrappedVeToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60806040526105dc6002553480156200001757600080fd5b5060405162003b0338038062003b038339810160408190526200003a91620001cc565b60006200004662000198565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35060018055600480546001600160a01b038088166001600160a01b0319928316178355600580548883169316929092179182905560408051637e062a3560e11b81529051929091169263fc0c546a928282019260209290829003018186803b158015620000fb57600080fd5b505afa15801562000110573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200013691906200019c565b600680546001600160a01b03199081166001600160a01b0393841617909155600780548216958316959095179094556008805485169382169390931790925560098054841691909216179055600b805433921691909117905550620002649050565b3390565b600060208284031215620001ae578081fd5b81516001600160a01b0381168114620001c5578182fd5b9392505050565b600080600080600060a08688031215620001e4578081fd5b8551620001f1816200024b565b602087015190955062000204816200024b565b604087015190945062000217816200024b565b60608701519093506200022a816200024b565b60808701519092506200023d816200024b565b809150509295509295909350565b6001600160a01b03811681146200026157600080fd5b50565b61388f80620002746000396000f3fe608060405234801561001057600080fd5b50600436106102695760003560e01c80638576960911610151578063b9ca55ed116100c3578063e5bd363b11610087578063e5bd363b1461048e578063e81aec88146104a1578063e8f00eed146104b4578063f2fde38b146104c7578063f42859d5146104da578063f7c618c1146104e257610269565b8063b9ca55ed14610445578063bc90addb1461044d578063c1a287e214610460578063c6d758cb14610468578063e4ff5c2f1461047b57610269565b8063a2b0f37b11610115578063a2b0f37b146103de578063a6ad66c6146103f1578063af9312ab146103f9578063b1c6f0e91461040c578063b3bd66591461041f578063b75ffadf1461043257610269565b806385769609146103a05780638da5cb5b146103a85780639d328e39146103b05780639e019bd0146103c35780639f81aed7146103d657610269565b80632b63b07b116101ea57806358aba00f116101ae57806358aba00f1461034d57806360c2affa1461036057806362d0468d14610368578063715018a6146103885780637f81e2ad1461039057806380d5adde1461039857610269565b80632b63b07b1461030f5780633b92eb23146103225780634125ff901461032a578063481c6a7514610332578063506ffb6f1461033a57610269565b806316c12ac21161023157806316c12ac2146102b957806318a6bc32146102cc5780631e70a069146102d457806321e3895a146102e9578063237e6d64146102fc57610269565b8063074ab5af1461026e578063097eb0521461028c5780630af8de34146102965780630c7b04261461029e57806315bc9a41146102b1575b600080fd5b6102766104ea565b6040516102839190612fce565b60405180910390f35b6102946104f9565b005b6102766108b8565b6102946102ac366004612cc0565b6108c7565b6102766109f7565b6102946102c7366004612cc0565b610a06565b610276610a67565b6102dc610a76565b60405161028391906130d9565b6102dc6102f7366004612cc0565b610a7c565b61029461030a366004612cf8565b610b94565b61029461031d366004612f56565b610e3c565b610276610eeb565b6102dc610efa565b610276610f01565b610294610348366004612e49565b610f10565b61029461035b366004612cc0565b610f81565b610276610fe2565b61037b610376366004612cc0565b610ff1565b60405161028391906130ce565b61029461100f565b610276611098565b6102946110a7565b610276611211565b610276611220565b6102946103be366004612cc0565b61122f565b6102946103d1366004612f56565b611265565b6102dc611560565b6102946103ec366004612cc0565b611567565b6102946115f1565b610294610407366004612f56565b61167d565b61027661041a366004612cc0565b6118db565b61029461042d366004612cc0565b6118f6565b610294610440366004612ddb565b611df2565b6102dc611e4a565b61027661045b366004612f56565b611e50565b6102dc611e7a565b610294610476366004612db0565b611e81565b610294610489366004612d30565b611f12565b61029461049c366004612db0565b611f73565b6102946104af366004612f56565b6120e5565b6102946104c2366004612db0565b6123bb565b6102946104d5366004612cc0565b612416565b6102dc6124d6565b6102766124dc565b600c546001600160a01b031681565b600360009054906101000a90046001600160a01b03166001600160a01b0316639dc6108f336001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561055657600080fd5b505afa15801561056a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058e9190612cdc565b6040518263ffffffff1660e01b81526004016105aa9190612fce565b60206040518083038186803b1580156105c257600080fd5b505afa1580156105d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105fa9190612cdc565b6001600160a01b0316336001600160a01b0316146106335760405162461bcd60e51b815260040161062a90613383565b60405180910390fd5b600260015414156106565760405162461bcd60e51b815260040161062a906137b4565b60026001819055506000339050600060106000836001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b1580156106a257600080fd5b505afa1580156106b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106da9190612cdc565b6001600160a01b039081168252602082019290925260409081016000908120546006546004805494516370a0823160e01b815292861696509294908116936370a082319361072d93919092169101612fce565b60206040518083038186803b15801561074557600080fd5b505afa158015610759573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061077d9190612f6e565b9050610788826124eb565b600654600480546040516370a0823160e01b81526000936001600160a01b03908116936370a08231936107be9392169101612fce565b60206040518083038186803b1580156107d657600080fd5b505afa1580156107ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080e9190612f6e565b9050600061081c828461251f565b905080156108725760006108476127106108416002548561254c90919063ffffffff16565b9061258d565b90506000610855838361251f565b60065490915061086f906001600160a01b031633836125bf565b50505b7f8056b132b128c79cae0255577c28459aa2810e5b192b0e1dd97f1784b86517d73385836040516108a593929190612fe2565b60405180910390a1505060018055505050565b6007546001600160a01b031681565b600b546001600160a01b031633146108f15760405162461bcd60e51b815260040161062a90613280565b6001600160a01b0381166000908152600f602052604090205460ff166109295760405162461bcd60e51b815260040161062a906135e4565b600061093482612651565b600e8054919250600091600019810190811061094c57fe5b600091825260209091200154600e80546001600160a01b03909216925082918490811061097557fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600e8054806109ae57fe5b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b03949094168152600f909352505060409020805460ff19169055565b600b546001600160a01b031681565b610a0e6126bd565b6001600160a01b0316610a1f611220565b6001600160a01b031614610a455760405162461bcd60e51b815260040161062a906134b7565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b031681565b600d5481565b6000808290506000816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b158015610abd57600080fd5b505afa158015610ad1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af59190612cdc565b6001600160a01b0380821660009081526010602052604090819020546004805492516370a0823160e01b8152949550908316936370a0823193610b3a93169101612fce565b60206040518083038186803b158015610b5257600080fd5b505afa158015610b66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8a9190612f6e565b925050505b919050565b610b9c611220565b6001600160a01b0316336001600160a01b03161480610bc55750600a546001600160a01b031633145b610be15760405162461bcd60e51b815260040161062a90613205565b816001600160a01b03166322be3de16040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610c1c57600080fd5b505af1158015610c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c549190612e89565b15610c715760405162461bcd60e51b815260040161062a9061318d565b6001600160a01b0381166000908152600f602052604090205460ff16610ca95760405162461bcd60e51b815260040161062a906135e4565b60405163b1c6f0e960e01b81526000906001600160a01b0383169063b1c6f0e990610cd8908690600401612fce565b60206040518083038186803b158015610cf057600080fd5b505afa158015610d04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d289190612cdc565b90506001600160a01b038116610d505760405162461bcd60e51b815260040161062a906135ad565b6001600160a01b03808416600090815260106020526040902054168015610e0b57826001600160a01b0316816001600160a01b031663ca1c9b756040518163ffffffff1660e01b815260040160206040518083038186803b158015610db457600080fd5b505afa158015610dc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dec9190612cdc565b6001600160a01b03161415610e0057600080fd5b610e0b8482846126c1565b506001600160a01b03928316600090815260106020526040902080546001600160a01b031916919093161790915550565b610e44611220565b6001600160a01b0316336001600160a01b03161480610e6d5750600a546001600160a01b031633145b610e895760405162461bcd60e51b815260040161062a90613205565b611388811115610eab5760405162461bcd60e51b815260040161062a9061362d565b60028190556040517f399b76bf122b580e18ba032e411399136d075c4ca9fb2353756a0fd76a9df98190610ee09083906130d9565b60405180910390a150565b6005546001600160a01b031681565b62278d0081565b600a546001600160a01b031681565b600b546001600160a01b03163314610f3a5760405162461bcd60e51b815260040161062a90613280565b60005b81811015610f7c576000838383818110610f5357fe5b9050602002016020810190610f689190612cc0565b9050610f7381612816565b50600101610f3d565b505050565b610f896126bd565b6001600160a01b0316610f9a611220565b6001600160a01b031614610fc05760405162461bcd60e51b815260040161062a906134b7565b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6009546001600160a01b031681565b6001600160a01b03166000908152600f602052604090205460ff1690565b6110176126bd565b6001600160a01b0316611028611220565b6001600160a01b03161461104e5760405162461bcd60e51b815260040161062a906134b7565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6003546001600160a01b031681565b6110af6126bd565b6001600160a01b03166110c0611220565b6001600160a01b0316146110e65760405162461bcd60e51b815260040161062a906134b7565b600260015414156111095760405162461bcd60e51b815260040161062a906137b4565b6002600155600c546001600160a01b03166111365760405162461bcd60e51b815260040161062a90613400565b600d544210156111585760405162461bcd60e51b815260040161062a906134ec565b62127500600d5401421061117e5760405162461bcd60e51b815260040161062a906136a6565b600b54600c546001600160a01b03908116911614156111af5760405162461bcd60e51b815260040161062a90613441565b600c8054600b80546001600160a01b038084166001600160a01b0319928316179283905592169092556000600d81905560405192909116917fa98d8344975cdfa5e7756a9bd78b2e9621ee254670ea9a2418d0abe8708d666e9190a260018055565b6004546001600160a01b031681565b6000546001600160a01b031690565b600b546001600160a01b031633146112595760405162461bcd60e51b815260040161062a90613280565b61126281612816565b50565b600360009054906101000a90046001600160a01b03166001600160a01b0316639dc6108f336001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b1580156112c257600080fd5b505afa1580156112d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fa9190612cdc565b6040518263ffffffff1660e01b81526004016113169190612fce565b60206040518083038186803b15801561132e57600080fd5b505afa158015611342573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113669190612cdc565b6001600160a01b0316336001600160a01b0316146113965760405162461bcd60e51b815260040161062a90613383565b600260015414156113b95760405162461bcd60e51b815260040161062a906137b4565b6002600155806113db5760405162461bcd60e51b815260040161062a906131c4565b60003390506000816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561141b57600080fd5b505afa15801561142f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114539190612cdc565b6001600160a01b038082166000908152601060205260409020549192501661147b81856128b5565b600480546040516370a0823160e01b81526000926001600160a01b03808716936370a08231936114b093919092169101612fce565b60206040518083038186803b1580156114c857600080fd5b505afa1580156114dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115009190612f6e565b9050848110156115225760405162461bcd60e51b815260040161062a90613143565b61152d8333876125bf565b7f2099a829592212d2a574e2ad7e6c84caa37c18c538886219b6b76a143064b4133383876040516108a593929190612fe2565b6203f48081565b61156f6126bd565b6001600160a01b0316611580611220565b6001600160a01b0316146115a65760405162461bcd60e51b815260040161062a906134b7565b6003546001600160a01b0316156115cf5760405162461bcd60e51b815260040161062a906136dd565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6115f96126bd565b6001600160a01b031661160a611220565b6001600160a01b0316146116305760405162461bcd60e51b815260040161062a906134b7565b600b80546001600160a01b0319908116909155600c805490911690556000600d8190556040517fa98d8344975cdfa5e7756a9bd78b2e9621ee254670ea9a2418d0abe8708d666e908290a2565b600360009054906101000a90046001600160a01b03166001600160a01b0316639dc6108f336001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b1580156116da57600080fd5b505afa1580156116ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117129190612cdc565b6040518263ffffffff1660e01b815260040161172e9190612fce565b60206040518083038186803b15801561174657600080fd5b505afa15801561175a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177e9190612cdc565b6001600160a01b0316336001600160a01b0316146117ae5760405162461bcd60e51b815260040161062a90613383565b600260015414156117d15760405162461bcd60e51b815260040161062a906137b4565b600260018190555060003390506000816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561181957600080fd5b505afa15801561182d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118519190612cdc565b6001600160a01b0380821660008181526010602052604090205460045493945082169261188192869116876128d2565b61188c82828661292a565b6118968185612941565b7f17347907b13f53d0562455046a967c5008944a22ecea3ddee6fc4301cd9fe7273382866040516118c993929190612fe2565b60405180910390a15050600180555050565b6010602052600090815260409020546001600160a01b031681565b6118fe611220565b6001600160a01b0316336001600160a01b031614806119275750600a546001600160a01b031633145b6119435760405162461bcd60e51b815260040161062a90613205565b600860009054906101000a90046001600160a01b03166001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561199357600080fd5b505af11580156119a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119cb9190612f6e565b506001600160a01b03811615611a3d576004805460405163095222d760e31b81526001600160a01b0390911691634a9116b891611a0a91859101612fce565b600060405180830381600087803b158015611a2457600080fd5b505af1158015611a38573d6000803e3d6000fd5b505050505b600654600480546040516370a0823160e01b81526000936001600160a01b03908116936370a0823193611a739392169101612fce565b60206040518083038186803b158015611a8b57600080fd5b505afa158015611a9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac39190612f6e565b905060008111611ae55760405162461bcd60e51b815260040161062a906131c4565b600954600654600754604051630820681160e11b815260009384936001600160a01b0391821693631040d02293611b2593899381169216906004016137eb565b604080518083038186803b158015611b3c57600080fd5b505afa158015611b50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b749190612e1c565b90925090506001600160a01b03821615801590611b9057508281115b15611d215760048054604051630935450960e21b81526001600160a01b03909116916324d5142491611bc4918791016130d9565b600060405180830381600087803b158015611bde57600080fd5b505af1158015611bf2573d6000803e3d6000fd5b5050600654611c0e92506001600160a01b03169050838561295e565b6007546006546001600160a01b0391821691161015611ca257600854604080516000808252602082019283905263022c0d9f60e01b9092526001600160a01b038581169363022c0d9f93611c6b93909287921690602481016130f9565b600060405180830381600087803b158015611c8557600080fd5b505af1158015611c99573d6000803e3d6000fd5b50505050611d1c565b600854604080516000808252602082019283905263022c0d9f60e01b9092526001600160a01b038581169363022c0d9f93611ce993879391929190911690602481016130f9565b600060405180830381600087803b158015611d0357600080fd5b505af1158015611d17573d6000803e3d6000fd5b505050505b611dec565b60048054604051630aa2b75d60e11b81526001600160a01b03909116916315456eba91611d50918791016130d9565b600060405180830381600087803b158015611d6a57600080fd5b505af1158015611d7e573d6000803e3d6000fd5b50506007546008546040516340c10f1960e01b81526001600160a01b0392831694506340c10f199350611db992909116908790600401613006565b600060405180830381600087803b158015611dd357600080fd5b505af1158015611de7573d6000803e3d6000fd5b505050505b50505050565b611dfa611220565b6001600160a01b0316336001600160a01b03161480611e235750600a546001600160a01b031633145b611e3f5760405162461bcd60e51b815260040161062a90613205565b610f7c83838361297d565b600e5490565b6000600e8281548110611e5f57fe5b6000918252602090912001546001600160a01b031692915050565b6212750081565b611e89611220565b6001600160a01b0316336001600160a01b03161480611eb25750600a546001600160a01b031633145b611ece5760405162461bcd60e51b815260040161062a90613205565b60026001541415611ef15760405162461bcd60e51b815260040161062a906137b4565b6002600155611f0a6001600160a01b038316338361295e565b505060018055565b611f1a611220565b6001600160a01b0316336001600160a01b03161480611f435750600a546001600160a01b031633145b611f5f5760405162461bcd60e51b815260040161062a90613205565b611f6c858585858561299c565b5050505050565b611f7b6126bd565b6001600160a01b0316611f8c611220565b6001600160a01b031614611fb25760405162461bcd60e51b815260040161062a906134b7565b60026001541415611fd55760405162461bcd60e51b815260040161062a906137b4565b60026001556001600160a01b03821661200b5780156120065760405162461bcd60e51b815260040161062a906132cc565b612082565b600b546001600160a01b03838116911614156120395760405162461bcd60e51b815260040161062a90613441565b6203f480420181101561205e5760405162461bcd60e51b815260040161062a906134ec565b62278d00420181106120825760405162461bcd60e51b815260040161062a906136a6565b600c80546001600160a01b0319166001600160a01b038416908117909155600d8290556040517f5f3816ba3fcccea768b514be2a8ff8f60c071c804d1ef1e26da38bb7a3e2a1f8906120d59084906130d9565b60405180910390a2505060018055565b600081116121055760405162461bcd60e51b815260040161062a906131c4565b600954600654600754604051630820681160e11b815260009384936001600160a01b0391821693631040d0229361214593899381169216906004016137eb565b604080518083038186803b15801561215c57600080fd5b505afa158015612170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121949190612e1c565b90925090506001600160a01b038216158015906121b057508281115b156122d2576006546121cd906001600160a01b03163384866128d2565b6007546006546001600160a01b039182169116101561225c57604080516000808252602082019283905263022c0d9f60e01b9092526001600160a01b0384169163022c0d9f91612225919085903390602481016130f9565b600060405180830381600087803b15801561223f57600080fd5b505af1158015612253573d6000803e3d6000fd5b505050506122cd565b604080516000808252602082019283905263022c0d9f60e01b9092526001600160a01b0384169163022c0d9f9161229a9185913390602481016130f9565b600060405180830381600087803b1580156122b457600080fd5b505af11580156122c8573d6000803e3d6000fd5b505050505b610f7c565b6004546006546122f1916001600160a01b0391821691339116866128d2565b60048054604051630aa2b75d60e11b81526001600160a01b03909116916315456eba91612320918791016130d9565b600060405180830381600087803b15801561233a57600080fd5b505af115801561234e573d6000803e3d6000fd5b50506007546040516340c10f1960e01b81526001600160a01b0390911692506340c10f1991506123849033908790600401613006565b600060405180830381600087803b15801561239e57600080fd5b505af11580156123b2573d6000803e3d6000fd5b50505050505050565b6123c3611220565b6001600160a01b0316336001600160a01b031614806123ec5750600a546001600160a01b031633145b6124085760405162461bcd60e51b815260040161062a90613205565b61241282826129c7565b5050565b61241e6126bd565b6001600160a01b031661242f611220565b6001600160a01b0316146124555760405162461bcd60e51b815260040161062a906134b7565b6001600160a01b03811661247b5760405162461bcd60e51b815260040161062a9061323a565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60025481565b6006546001600160a01b031681565b6040805160048152602481019091526020810180516001600160e01b0316631e8c5c8960e11b1790526124129082906129e4565b6000828211156125415760405162461bcd60e51b815260040161062a9061334c565b508082035b92915050565b60008261255b57506000612546565b8282028284828161256857fe5b04146125865760405162461bcd60e51b815260040161062a90613476565b9392505050565b60008082116125ae5760405162461bcd60e51b815260040161062a906133c9565b8183816125b757fe5b049392505050565b60606126178463a9059cbb60e01b85856040516024016125e0929190613006565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526129e4565b805190915015611dec57808060200190518101906126359190612e89565b611dec5760405162461bcd60e51b815260040161062a90613567565b600e54600090815b818110156126a457836001600160a01b0316600e828154811061267857fe5b6000918252602090912001546001600160a01b0316141561269c579150610b8f9050565b600101612659565b5060405162461bcd60e51b815260040161062a90613301565b3390565b600480546040516370a0823160e01b815284926000926001600160a01b03808616936370a08231936126f7939092169101612fce565b60206040518083038186803b15801561270f57600080fd5b505afa158015612723573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127479190612f6e565b90508015611f6c5761275982826128b5565b600480546040516370a0823160e01b815287926000926001600160a01b03808616936370a082319361278f939092169101612fce565b60206040518083038186803b1580156127a757600080fd5b505afa1580156127bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127df9190612f6e565b9050828110156128015760405162461bcd60e51b815260040161062a90613143565b61280c82868561292a565b6123b28584612941565b6001600160a01b0381166000908152600f602052604090205460ff161561284f5760405162461bcd60e51b815260040161062a906135e4565b6001600160a01b03166000818152600f60205260408120805460ff19166001908117909155600e805491820181559091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0180546001600160a01b0319169091179055565b610f7c82632e1a7d4d60e01b836040516024016125e091906130d9565b611dec846323b872dd60e01b8585856040516024016128f393929190612fe2565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612aa4565b61293683836000612b33565b610f7c838383612b33565b610f7c8263b6b55f2560e01b836040516024016125e091906130d9565b610f7c8363a9059cbb60e01b84846040516024016128f3929190613006565b611dec8363bd86e50860e01b84846040516024016125e09291906130e2565b6129bf85636f816a2060e01b868686866040516024016125e0949392919061304f565b505050505050565b610f7c8263f0bedbe260e01b836040516024016125e091906130d9565b60048054604051635b0e93fb60e11b815260609260009284926001600160a01b039091169163b61d27f691612a1f91899187918a910161301f565b600060405180830381600087803b158015612a3957600080fd5b505af1158015612a4d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a759190810190612ea5565b9092509050600182151514612a9c5760405162461bcd60e51b815260040161062a90613523565b949350505050565b6060612af9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612b8e9092919063ffffffff16565b805190915015610f7c5780806020019051810190612b179190612e89565b610f7c5760405162461bcd60e51b815260040161062a9061376a565b6060612b548463095ea7b360e01b85856040516024016125e0929190613006565b805190915015611dec5780806020019051810190612b729190612e89565b611dec5760405162461bcd60e51b815260040161062a90613726565b6060612a9c848460008585612ba285612c38565b612bbe5760405162461bcd60e51b815260040161062a9061366f565b60006060866001600160a01b03168587604051612bdb9190612fb2565b60006040518083038185875af1925050503d8060008114612c18576040519150601f19603f3d011682016040523d82523d6000602084013e612c1d565b606091505b5091509150612c2d828286612c3e565b979650505050505050565b3b151590565b60608315612c4d575081612586565b825115612c5d5782518084602001fd5b8160405162461bcd60e51b815260040161062a9190613130565b60008083601f840112612c88578182fd5b50813567ffffffffffffffff811115612c9f578182fd5b6020830191508360208083028501011115612cb957600080fd5b9250929050565b600060208284031215612cd1578081fd5b813561258681613836565b600060208284031215612ced578081fd5b815161258681613836565b60008060408385031215612d0a578081fd5b8235612d1581613836565b91506020830135612d2581613836565b809150509250929050565b600080600080600060608688031215612d47578081fd5b8535612d5281613836565b9450602086013567ffffffffffffffff80821115612d6e578283fd5b612d7a89838a01612c77565b90965094506040880135915080821115612d92578283fd5b50612d9f88828901612c77565b969995985093965092949392505050565b60008060408385031215612dc2578182fd5b8235612dcd81613836565b946020939093013593505050565b600080600060608486031215612def578283fd5b8335612dfa81613836565b9250602084013591506040840135612e1181613836565b809150509250925092565b60008060408385031215612e2e578182fd5b8251612e3981613836565b6020939093015192949293505050565b60008060208385031215612e5b578182fd5b823567ffffffffffffffff811115612e71578283fd5b612e7d85828601612c77565b90969095509350505050565b600060208284031215612e9a578081fd5b81516125868161384b565b60008060408385031215612eb7578182fd5b8251612ec28161384b565b602084015190925067ffffffffffffffff80821115612edf578283fd5b818501915085601f830112612ef2578283fd5b815181811115612f00578384fd5b604051601f8201601f191681016020018381118282101715612f20578586fd5b604052818152838201602001881015612f37578485fd5b612f4882602083016020870161380a565b809450505050509250929050565b600060208284031215612f67578081fd5b5035919050565b600060208284031215612f7f578081fd5b5051919050565b60008151808452612f9e81602086016020860161380a565b601f01601f19169290920160200192915050565b60008251612fc481846020870161380a565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b600060018060a01b0385168252836020830152606060408301526130466060830184612f86565b95945050505050565b6040808252810184905260008560608301825b87811015613092576020833561307781613836565b6001600160a01b031683529283019290910190600101613062565b5083810360208501528481526001600160fb1b038511156130b1578283fd5b602085029150818660208301370160200190815295945050505050565b901515815260200190565b90815260200190565b9182526001600160a01b0316602082015260400190565b600085825284602083015260018060a01b0384166040830152608060608301526131266080830184612f86565b9695505050505050565b6000602082526125866020830184612f86565b6020808252602a908201527f47617567655661756c7450726f787941646d696e3a20494e53554646494349456040820152694e545f42414c414e434560b01b606082015260800190565b6020808252601c908201527f47617567655661756c7450726f787941646d696e3a20535441424c4500000000604082015260600190565b60208082526021908201527f47617567655661756c7450726f787941646d696e3a20414d4f554e545f5a45526040820152604f60f81b606082015260800190565b6020808252818101527f47617567655661756c7450726f787941646d696e3a2052455354524943544544604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252602c908201527f47617567655661756c7450726f787941646d696e3a204f4e4c595f474155474560408201526b2fa82927ac2cafa0a226a4a760a11b606082015260800190565b6020808252818101527f47617567655661756c7450726f787941646d696e3a204e4f545f4245464f5245604082015260600190565b6020808252602b908201527f47617567655661756c7450726f787941646d696e3a2047415547455f50524f5860408201526a1657d393d517d193d5539160aa1b606082015260800190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526026908201527f47617567655661756c7450726f787941646d696e3a204f4e4c595f5641554c546040820152652faa27a5a2a760d11b606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b60208082526021908201527f47617567655661756c7450726f787941646d696e3a20494e564c445f41444d496040820152602760f91b606082015260800190565b6020808252818101527f47617567655661756c7450726f787941646d696e3a2053414d455f41444d494e604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601e908201527f47617567655661756c7450726f787941646d696e3a20544f4f5f534f4f4e0000604082015260600190565b60208082526024908201527f47617567655661756c7450726f787941646d696e3a20455845435554455f46416040820152631253115160e21b606082015260800190565b60208082526026908201527f47617567655661756c7450726f787941646d696e3a20534146455f584645525f60408201526511905253115160d21b606082015260800190565b6020808252601e908201527f47617567655661756c7450726f787941646d696e3a204e4f5f47415547450000604082015260600190565b60208082526029908201527f47617567655661756c7450726f787941646d696e3a2047415547455f50524f586040820152681657d153905093115160ba1b606082015260800190565b60208082526022908201527f47617567655661756c7450726f787941646d696e3a20494e564c445f56454c4f604082015261434b60f01b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252601e908201527f47617567655661756c7450726f787941646d696e3a20544f4f5f4c4154450000604082015260600190565b60208082526029908201527f47617567655661756c7450726f787941646d696e3a20464143544f52595f414c604082015268149150511657d4d15560ba1b606082015260800190565b60208082526024908201527f47617567655661756c7450726f787941646d696e3a20415050524f56455f46416040820152631253115160e21b606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b9283526001600160a01b03918216602084015216604082015260600190565b60005b8381101561382557818101518382015260200161380d565b83811115611dec5750506000910152565b6001600160a01b038116811461126257600080fd5b801515811461126257600080fdfea264697066735822122027eb2cfd0ed7d9035eb32355a52b8df5c40c2e7dc43a91bdaea34aa6a348b03d64736f6c634300060c0033000000000000000000000000cf8660e267d44cc804ddbee6b1ce44f9ed5648890000000000000000000000002fbff41a9efaeae77538bd63f1ea489494acdc080000000000000000000000006caa3e5feba1f83ec1d80ea2eaca37c3421c33a80000000000000000000000006d137d99084f710fad6adf45fd6ef65e617bd4dd000000000000000000000000d04f1a8182d5670e42ba9ee0ce9ffc71e6d1fc18

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

000000000000000000000000cf8660e267d44cc804ddbee6b1ce44f9ed5648890000000000000000000000002fbff41a9efaeae77538bd63f1ea489494acdc080000000000000000000000006caa3e5feba1f83ec1d80ea2eaca37c3421c33a80000000000000000000000006d137d99084f710fad6adf45fd6ef65e617bd4dd000000000000000000000000d04f1a8182d5670e42ba9ee0ce9ffc71e6d1fc18

-----Decoded View---------------
Arg [0] : _gaugeVaultProxy (address): 0xcf8660e267d44cc804ddbee6b1ce44f9ed564889
Arg [1] : _veToken (address): 0x2fbff41a9efaeae77538bd63f1ea489494acdc08
Arg [2] : _wrappedVeToken (address): 0x6caa3e5feba1f83ec1d80ea2eaca37c3421c33a8
Arg [3] : _tokenDistributor (address): 0x6d137d99084f710fad6adf45fd6ef65e617bd4dd
Arg [4] : _optiSwap (address): 0xd04f1a8182d5670e42ba9ee0ce9ffc71e6d1fc18

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000cf8660e267d44cc804ddbee6b1ce44f9ed564889
Arg [1] : 0000000000000000000000002fbff41a9efaeae77538bd63f1ea489494acdc08
Arg [2] : 0000000000000000000000006caa3e5feba1f83ec1d80ea2eaca37c3421c33a8
Arg [3] : 0000000000000000000000006d137d99084f710fad6adf45fd6ef65e617bd4dd
Arg [4] : 000000000000000000000000d04f1a8182d5670e42ba9ee0ce9ffc71e6d1fc18


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Validator ID :
0 FTM

Amount Staked
0

Amount Delegated
0

Staking Total
0

Staking Start Epoch
0

Staking Start Time
0

Proof of Importance
0

Origination Score
0

Validation Score
0

Active
0

Online
0

Downtime
0 s
Address Amount claimed Rewards Created On Epoch Created On
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.