ETH Price: $2,327.18 (-0.73%)

Contract Diff Checker

Contract Name:
BoosterOwnerLite

Contract Source Code:

// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;


interface IOwner {
    //booster lite
    function setFactories(address _rfactory, address _sfactory, address _tfactory) external;
    function shutdownSystem() external;
    function isShutdown() external view returns(bool);
    function poolLength() external view returns(uint256);
    function poolInfo(uint256) external view returns(address,address,address,address,address,bool);
    function setFeeManager(address _feeM) external;
    function setOwner(address _owner) external;

    //rescue
    function setDistribution(address _distributor, address _rewardDeposit, address _treasury) external;
    function setExtraReward(address _token, uint256 _option) external;

    //stash
    function setExtraReward(address _token) external;
    function setRewardHook(address _hook) external;

    //stash factory
    function setImplementation(address _v1, address _v2, address _v3) external;
}

// prettier-ignore
interface IBoosterOwnerLite {
    function transferOwnership(address _owner) external;
    function acceptOwnership() external;
    function setFactories(address _rfactory, address _sfactory, address _tfactory) external;
    function setFeeManager(address _feeM) external;
    function shutdownSystem() external;
    function queueForceShutdown() external;
    function forceShutdownSystem() external;
    function execute( address _to, uint256 _value, bytes calldata _data) external returns (bool, bytes memory);
    function setRescueTokenDistribution(address _distributor, address _rewardDeposit, address _treasury) external;
    function setRescueTokenReward(address _token, uint256 _option) external;
    function setStashExtraReward(address _stash, address _token) external;
    function setStashRewardHook(address _stash, address _hook) external;
    function setStashFactoryImplementation(address _v1, address _v2, address _v3) external;
}

/**
 * @title   BoosterOwnerLite
 * @author  ConvexFinance
 * @notice  Immutable booster owner that requires all pools to be shutdown before shutting down the entire convex system
 * @dev     A timelock is required if forcing a shutdown if there is a bugged pool that can not be withdrawn from.
 *          Allow arbitrary calls to other contracts, but limit how calls are made to Booster.
 *          A lite version of the original Booster for use on sidechains
 */
contract BoosterOwnerLite is IBoosterOwnerLite{

    address public immutable poolManager;
    address public immutable booster;
    address public immutable stashFactory;
    address public immutable rescueStash;
    address public owner;
    address public pendingowner;
    bool public isSealed;

    uint256 public constant FORCE_DELAY = 30 days;

    bool public isForceTimerStarted;
    uint256 public forceTimestamp;

    event ShutdownStarted(uint256 executableTimestamp);
    event ShutdownExecuted();
    event TransferOwnership(address pendingOwner);
    event AcceptedOwnership(address newOwner);
    event OwnershipSealed();

    /**
     * @param _owner         Owner (e.g. CVX multisig)
     * @param _poolManager   PoolManager (e.g. PoolManagerSecondaryProxy or 0xD20904e5916113D11414F083229e9C8C6F91D1e1)
     * @param _booster       The booster (e.g. 0xF403C135812408BFbE8713b5A23a04b3D48AAE31)
     * @param _stashFactory  Creates stashes (e.g. 0x884da067B66677e72530df91eabb6e3CE69c2bE4)
     * @param _rescueStash   Rescues tokens for subsequent vlCVX redistribution (e.g. 0x01140351069af98416cC08b16424b9E765436531)
     */
    constructor(
        address _owner,
        address _poolManager,
        address _booster,
        address _stashFactory,
        address _rescueStash,
        bool _seal
    ) public {
        owner = _owner;
        poolManager = _poolManager;
        booster = _booster;
        stashFactory = _stashFactory;
        rescueStash = _rescueStash;
        isSealed = _seal;
    }

    modifier onlyOwner() {
        require(owner == msg.sender, "!owner");
        _;
    }

    function transferOwnership(address _owner) external override onlyOwner{
        pendingowner = _owner;
        emit TransferOwnership(_owner);
    }

    function acceptOwnership() external override {
        require(pendingowner == msg.sender, "!pendingowner");
        owner = pendingowner;
        pendingowner = address(0);
        emit AcceptedOwnership(owner);
    }

    function sealOwnership() external onlyOwner{
        isSealed = true;
        emit OwnershipSealed();
    }

    function setBoosterOwner() external onlyOwner{
        //allow reverting ownership until sealed
        require(!isSealed, "ownership sealed");

        //transfer booster ownership to this owner
        IOwner(booster).setOwner(owner);
    }

    function setFactories(address _rfactory, address _sfactory, address _tfactory) external override onlyOwner{
        IOwner(booster).setFactories(_rfactory, _sfactory, _tfactory);
    }


    function setFeeManager(address _feeM) external override onlyOwner{
        IOwner(booster).setFeeManager(_feeM);
    }


    function shutdownSystem() external override onlyOwner{
        require(IOwner(poolManager).isShutdown(),"!poolMgrShutdown");

        //check that all pools are already shutdown
        uint256 poolCount = IOwner(booster).poolLength();
        for(uint256 i = 0; i < poolCount; i++){
            (,,,,,bool isshutdown) = IOwner(booster).poolInfo(i);
            require(isshutdown, "!poolShutdown");
        }

        //complete the shutdown process
        IOwner(booster).shutdownSystem();
        emit ShutdownExecuted();
    }


    //queue a forced shutdown that does not require pools to already be shutdown
    //this should only be needed if a pool is broken and withdrawAll() does not
    //correctly return enough lp tokens
    function queueForceShutdown() external override onlyOwner{
        require(IOwner(poolManager).isShutdown(),"!poolMgrShutdown");
        require(!isForceTimerStarted, "already started");
    
        isForceTimerStarted = true;
        forceTimestamp = block.timestamp + FORCE_DELAY;

        emit ShutdownStarted(forceTimestamp);
    }

    //force shutdown the system after timer has expired
    function forceShutdownSystem() external override onlyOwner{
        require(isForceTimerStarted, "!timer start");
        require(block.timestamp > forceTimestamp, "!timer finish");

        IOwner(booster).shutdownSystem();
        emit ShutdownExecuted();
    }


    //allow arbitrary calls to any contract other than the booster, as some contracts
    //may use ownership as booster.owner() instead of local variable
    function execute(
        address _to,
        uint256 _value,
        bytes calldata _data
    ) external override onlyOwner returns (bool, bytes memory) {
        require(_to != booster, "!invalid target");

        (bool success, bytes memory result) = _to.call{value:_value}(_data);

        return (success, result);
    }


    // --- Helper functions for other systems, could also just use execute() ---

    //TokenRescue setDistribution
    function setRescueTokenDistribution(address _distributor, address _rewardDeposit, address _treasury) external override onlyOwner{
        IOwner(rescueStash).setDistribution(_distributor, _rewardDeposit, _treasury);
    }

    //TokenRescue setExtraReward
    function setRescueTokenReward(address _token, uint256 _option) external override onlyOwner{
        IOwner(rescueStash).setExtraReward(_token, _option);
    }

    //stash v3 - set extra reward
    function setStashExtraReward(address _stash, address _token) external override onlyOwner{
        IOwner(_stash).setExtraReward(_token);
    }

    //stash v3 - set reward hook
    function setStashRewardHook(address _stash, address _hook) external override onlyOwner{
        IOwner(_stash).setRewardHook(_hook);
    }

    //stash factory - set implementation
    function setStashFactoryImplementation(address _v1, address _v2, address _v3) external override onlyOwner{
        IOwner(stashFactory).setImplementation(_v1, _v2, _v3);
    }
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):