Skip to content

Latest commit

 

History

History
610 lines (493 loc) · 18.5 KB

VestingLogic.md

File metadata and controls

610 lines (493 loc) · 18.5 KB

Vesting Logic contract. (VestingLogic.sol)

View Source: contracts/governance/Vesting/VestingLogic.sol

↗ Extends: IVesting, VestingStorage, ApprovalReceiver

VestingLogic contract

Staking, delegating and withdrawal functionality.

Events

event TokensStaked(address indexed caller, uint256  amount);
event VotesDelegated(address indexed caller, address  delegatee);
event TokensWithdrawn(address indexed caller, address  receiver);
event DividendsCollected(address indexed caller, address  loanPoolToken, address  receiver, uint32  maxCheckpoints);
event MigratedToNewStakingContract(address indexed caller, address  newStakingContract);

Modifiers

onlyOwners

Throws if called by any account other than the token owner or the contract owner.

modifier onlyOwners() internal

onlyTokenOwner

Throws if called by any account other than the token owner.

modifier onlyTokenOwner() internal

Functions


stakeTokens

⤾ overrides IVesting.stakeTokens

Stakes tokens according to the vesting schedule.

function stakeTokens(uint256 _amount) public nonpayable

Arguments

Name Type Description
_amount uint256 The amount of tokens to stake.
Source Code
function stakeTokens(uint256 _amount) public {
        _stakeTokens(msg.sender, _amount);
    }

stakeTokensWithApproval

Stakes tokens according to the vesting schedule.

function stakeTokensWithApproval(address _sender, uint256 _amount) public nonpayable onlyThisContract 

Arguments

Name Type Description
_sender address The sender of SOV.approveAndCall
_amount uint256 The amount of tokens to stake.
Source Code
function stakeTokensWithApproval(address _sender, uint256 _amount) public onlyThisContract {
        _stakeTokens(_sender, _amount);
    }

_stakeTokens

Stakes tokens according to the vesting schedule. Low level function.

function _stakeTokens(address _sender, uint256 _amount) internal nonpayable

Arguments

Name Type Description
_sender address The sender of tokens to stake.
_amount uint256 The amount of tokens to stake.
Source Code
function _stakeTokens(address _sender, uint256 _amount) internal {
        /// @dev Maybe better to allow staking unil the cliff was reached.
        if (startDate == 0) {
            startDate = staking.timestampToLockDate(block.timestamp);
        }
        endDate = staking.timestampToLockDate(block.timestamp + duration);

        /// @dev Transfer the tokens to this contract.
        bool success = SOV.transferFrom(_sender, address(this), _amount);
        require(success);

        /// @dev Allow the staking contract to access them.
        SOV.approve(address(staking), _amount);

        staking.stakeBySchedule(_amount, cliff, duration, FOUR_WEEKS, address(this), tokenOwner);

        emit TokensStaked(_sender, _amount);
    }

delegate

Delegate votes from msg.sender which are locked until lockDate to delegatee.

function delegate(address _delegatee) public nonpayable onlyTokenOwner 

Arguments

Name Type Description
_delegatee address The address to delegate votes to.
Source Code
function delegate(address _delegatee) public onlyTokenOwner {
        require(_delegatee != address(0), "delegatee address invalid");

        /// @dev Withdraw for each unlocked position.
        /// @dev Don't change FOUR_WEEKS to TWO_WEEKS, a lot of vestings already deployed with FOUR_WEEKS
        ///		workaround found, but it doesn't work with TWO_WEEKS
        for (uint256 i = startDate + cliff; i <= endDate; i += FOUR_WEEKS) {
            staking.delegate(_delegatee, i);
        }
        emit VotesDelegated(msg.sender, _delegatee);
    }

governanceWithdrawTokens

Withdraws all tokens from the staking contract and forwards them to an address specified by the token owner.

function governanceWithdrawTokens(address receiver) public nonpayable

Arguments

Name Type Description
receiver address The receiving address.
Source Code
function governanceWithdrawTokens(address receiver) public {
        require(msg.sender == address(staking), "unauthorized");

        _withdrawTokens(receiver, true);
    }

withdrawTokens

Withdraws unlocked tokens from the staking contract and forwards them to an address specified by the token owner.

function withdrawTokens(address receiver) public nonpayable onlyOwners 

Arguments

Name Type Description
receiver address The receiving address.
Source Code
function withdrawTokens(address receiver) public onlyOwners {
        _withdrawTokens(receiver, false);
    }

_withdrawTokens

Withdraws tokens from the staking contract and forwards them to an address specified by the token owner. Low level function.

function _withdrawTokens(address receiver, bool isGovernance) internal nonpayable

Arguments

Name Type Description
receiver address The receiving address.
isGovernance bool Whether all tokens (true) or just unlocked tokens (false).
Source Code
function _withdrawTokens(address receiver, bool isGovernance) internal {
        require(receiver != address(0), "receiver address invalid");

        uint96 stake;

        /// @dev Usually we just need to iterate over the possible dates until now.
        uint256 end;

        /// @dev In the unlikely case that all tokens have been unlocked early,
        ///   allow to withdraw all of them.
        if (staking.allUnlocked() || isGovernance) {
            end = endDate;
        } else {
            end = block.timestamp;
        }

        /// @dev Withdraw for each unlocked position.
        /// @dev Don't change FOUR_WEEKS to TWO_WEEKS, a lot of vestings already deployed with FOUR_WEEKS
        ///		workaround found, but it doesn't work with TWO_WEEKS
        for (uint256 i = startDate + cliff; i <= end; i += FOUR_WEEKS) {
            /// @dev Read amount to withdraw.
            stake = staking.getPriorUserStakeByDate(address(this), i, block.number - 1);

            /// @dev Withdraw if > 0
            if (stake > 0) {
                if (isGovernance) {
                    staking.governanceWithdraw(stake, i, receiver);
                } else {
                    staking.withdraw(stake, i, receiver);
                }
            }
        }

        emit TokensWithdrawn(msg.sender, receiver);
    }

collectDividends

Collect dividends from fee sharing proxy.

function collectDividends(address _loanPoolToken, uint32 _maxCheckpoints, address _receiver) public nonpayable onlyOwners 

Arguments

Name Type Description
_loanPoolToken address The loan pool token address.
_maxCheckpoints uint32 Maximum number of checkpoints to be processed.
_receiver address The receiver of tokens or msg.sender
Source Code
function collectDividends(
        address _loanPoolToken,
        uint32 _maxCheckpoints,
        address _receiver
    ) public onlyOwners {
        require(_receiver != address(0), "receiver address invalid");

        /// @dev Invokes the fee sharing proxy.
        feeSharingCollector.withdraw(_loanPoolToken, _maxCheckpoints, _receiver);

        emit DividendsCollected(msg.sender, _loanPoolToken, _receiver, _maxCheckpoints);
    }

migrateToNewStakingContract

Allows the owners to migrate the positions to a new staking contract.

function migrateToNewStakingContract() public nonpayable onlyOwners 
Source Code
function migrateToNewStakingContract() public onlyOwners {
        staking.migrateToNewStakingContract();
        staking = IStaking(staking.newStakingContract());
        emit MigratedToNewStakingContract(msg.sender, address(staking));
    }

_getToken

⤾ overrides ApprovalReceiver._getToken

Overrides default ApprovalReceiver._getToken function to register SOV token on this contract.

function _getToken() internal view
returns(address)
Source Code
function _getToken() internal view returns (address) {
        return address(SOV);
    }

_getSelectors

⤾ overrides ApprovalReceiver._getSelectors

Overrides default ApprovalReceiver._getSelectors function to register stakeTokensWithApproval selector on this contract.

function _getSelectors() internal pure
returns(bytes4[])
Source Code
function _getSelectors() internal pure returns (bytes4[] memory) {
        bytes4[] memory selectors = new bytes4[](1);
        selectors[0] = this.stakeTokensWithApproval.selector;
        return selectors;
    }

Contracts