Skip to content

Latest commit

 

History

History
1008 lines (778 loc) · 28.3 KB

LockedSOV.md

File metadata and controls

1008 lines (778 loc) · 28.3 KB

The Locked SOV Contract. (LockedSOV.sol)

View Source: contracts/locked/LockedSOV.sol

↗ Extends: ILockedSOV

LockedSOV contract

This contract is used to receive reward from other contracts, Create Vesting and Stake Tokens.

Contract Members

Constants & Variables

//public members
uint256 public constant MAX_BASIS_POINT;
uint256 public constant MAX_DURATION;
bool public migration;
uint256 public cliff;
uint256 public duration;
contract IERC20 public SOV;
contract VestingRegistry public vestingRegistry;
contract ILockedSOV public newLockedSOV;

//private members
mapping(address => uint256) private lockedBalances;
mapping(address => uint256) private unlockedBalances;
mapping(address => bool) private isAdmin;

Events

event AdminAdded(address indexed _initiator, address indexed _newAdmin);
event AdminRemoved(address indexed _initiator, address indexed _removedAdmin);
event RegistryCliffAndDurationUpdated(address indexed _initiator, address indexed _vestingRegistry, uint256  _cliff, uint256  _duration);
event Deposited(address indexed _initiator, address indexed _userAddress, uint256  _sovAmount, uint256  _basisPoint);
event Withdrawn(address indexed _initiator, address indexed _userAddress, uint256  _sovAmount);
event VestingCreated(address indexed _initiator, address indexed _userAddress, address indexed _vesting);
event TokenStaked(address indexed _initiator, address indexed _vesting, uint256  _amount);
event MigrationStarted(address indexed _initiator, address indexed _newLockedSOV);
event UserTransfered(address indexed _initiator, uint256  _amount);

Modifiers

onlyAdmin

modifier onlyAdmin() internal

migrationAllowed

modifier migrationAllowed() internal

Functions


constructor

Setup the required parameters.

function (address _SOV, address _vestingRegistry, uint256 _cliff, uint256 _duration, address[] _admins) public nonpayable

Arguments

Name Type Description
_SOV address The SOV Token Address.
_vestingRegistry address The Vesting Registry Address.
_cliff uint256 The time period after which the tokens begin to unlock.
_duration uint256 The time period after all tokens will have been unlocked.
_admins address[] The list of Admins to be added.
Source Code
constructor(
        address _SOV,
        address _vestingRegistry,
        uint256 _cliff,
        uint256 _duration,
        address[] memory _admins
    ) public {
        require(_SOV != address(0), "Invalid SOV Address.");
        require(_vestingRegistry != address(0), "Vesting registry address is invalid.");
        require(_duration < MAX_DURATION, "Duration is too long.");

        SOV = IERC20(_SOV);
        vestingRegistry = VestingRegistry(_vestingRegistry);
        cliff = _cliff * 4 weeks;
        duration = _duration * 4 weeks;

        for (uint256 index = 0; index < _admins.length; index++) {
            isAdmin[_admins[index]] = true;
        }
    }

addAdmin

The function to add a new admin.

function addAdmin(address _newAdmin) public nonpayable onlyAdmin 

Arguments

Name Type Description
_newAdmin address The address of the new admin.
Source Code
function addAdmin(address _newAdmin) public onlyAdmin {
        require(_newAdmin != address(0), "Invalid Address.");
        require(!isAdmin[_newAdmin], "Address is already admin.");
        isAdmin[_newAdmin] = true;

        emit AdminAdded(msg.sender, _newAdmin);
    }

removeAdmin

The function to remove an admin.

function removeAdmin(address _adminToRemove) public nonpayable onlyAdmin 

Arguments

Name Type Description
_adminToRemove address The address of the admin which should be removed.
Source Code
function removeAdmin(address _adminToRemove) public onlyAdmin {
        require(isAdmin[_adminToRemove], "Address is not an admin.");
        isAdmin[_adminToRemove] = false;

        emit AdminRemoved(msg.sender, _adminToRemove);
    }

changeRegistryCliffAndDuration

The function to update the Vesting Registry, Duration and Cliff.

function changeRegistryCliffAndDuration(address _vestingRegistry, uint256 _cliff, uint256 _duration) external nonpayable onlyAdmin 

Arguments

Name Type Description
_vestingRegistry address The Vesting Registry Address.
_cliff uint256 The time period after which the tokens begin to unlock.
_duration uint256 The time period after all tokens will have been unlocked.
Source Code
function changeRegistryCliffAndDuration(
        address _vestingRegistry,
        uint256 _cliff,
        uint256 _duration
    ) external onlyAdmin {
        require(
            address(vestingRegistry) != _vestingRegistry,
            "Vesting Registry has to be different for changing duration and cliff."
        );
        /// If duration is also zero, then it is similar to Unlocked SOV.
        require(_duration != 0, "Duration cannot be zero.");
        require(_duration < MAX_DURATION, "Duration is too long.");

        vestingRegistry = VestingRegistry(_vestingRegistry);

        cliff = _cliff * 4 weeks;
        duration = _duration * 4 weeks;

        emit RegistryCliffAndDurationUpdated(msg.sender, _vestingRegistry, _cliff, _duration);
    }

deposit

⤾ overrides ILockedSOV.deposit

Adds SOV to the user balance (Locked and Unlocked Balance based on _basisPoint).

function deposit(address _userAddress, uint256 _sovAmount, uint256 _basisPoint) external nonpayable

Arguments

Name Type Description
_userAddress address The user whose locked balance has to be updated with _sovAmount.
_sovAmount uint256 The amount of SOV to be added to the locked and/or unlocked balance.
_basisPoint uint256 The % (in Basis Point)which determines how much will be unlocked immediately.
Source Code
function deposit(
        address _userAddress,
        uint256 _sovAmount,
        uint256 _basisPoint
    ) external {
        _deposit(_userAddress, _sovAmount, _basisPoint);
    }

depositSOV

⤾ overrides ILockedSOV.depositSOV

Adds SOV to the locked balance of a user.

function depositSOV(address _userAddress, uint256 _sovAmount) external nonpayable

Arguments

Name Type Description
_userAddress address The user whose locked balance has to be updated with _sovAmount.
_sovAmount uint256 The amount of SOV to be added to the locked balance.
Source Code
function depositSOV(address _userAddress, uint256 _sovAmount) external {
        _deposit(_userAddress, _sovAmount, 0);
    }

_deposit

function _deposit(address _userAddress, uint256 _sovAmount, uint256 _basisPoint) private nonpayable

Arguments

Name Type Description
_userAddress address
_sovAmount uint256
_basisPoint uint256
Source Code
function _deposit(
        address _userAddress,
        uint256 _sovAmount,
        uint256 _basisPoint
    ) private {
        // MAX_BASIS_POINT is not included because if 100% is unlocked, then LockedSOV is not required to be used.
        require(_basisPoint < MAX_BASIS_POINT, "Basis Point has to be less than 10000.");
        bool txStatus = SOV.transferFrom(msg.sender, address(this), _sovAmount);
        require(txStatus, "Token transfer was not successful. Check receiver address.");

        uint256 unlockedBal = _sovAmount.mul(_basisPoint).div(MAX_BASIS_POINT);

        unlockedBalances[_userAddress] = unlockedBalances[_userAddress].add(unlockedBal);
        lockedBalances[_userAddress] = lockedBalances[_userAddress].add(_sovAmount).sub(
            unlockedBal
        );

        emit Deposited(msg.sender, _userAddress, _sovAmount, _basisPoint);
    }

withdraw

A function to withdraw the unlocked balance.

function withdraw(address _receiverAddress) public nonpayable

Arguments

Name Type Description
_receiverAddress address If specified, the unlocked balance will go to this address, else to msg.sender.
Source Code
function withdraw(address _receiverAddress) public {
        _withdraw(msg.sender, _receiverAddress);
    }

_withdraw

function _withdraw(address _sender, address _receiverAddress) private nonpayable

Arguments

Name Type Description
_sender address
_receiverAddress address
Source Code
function _withdraw(address _sender, address _receiverAddress) private {
        address userAddr = _receiverAddress;
        if (_receiverAddress == address(0)) {
            userAddr = _sender;
        }

        uint256 amount = unlockedBalances[_sender];
        unlockedBalances[_sender] = 0;

        bool txStatus = SOV.transfer(userAddr, amount);
        require(txStatus, "Token transfer was not successful. Check receiver address.");

        emit Withdrawn(_sender, userAddr, amount);
    }

createVestingAndStake

Creates vesting if not already created and Stakes tokens for a user.

function createVestingAndStake() public nonpayable
Source Code
function createVestingAndStake() public {
        _createVestingAndStake(msg.sender);
    }

_createVestingAndStake

function _createVestingAndStake(address _sender) private nonpayable

Arguments

Name Type Description
_sender address
Source Code
function _createVestingAndStake(address _sender) private {
        address vestingAddr = _getVesting(_sender);

        if (vestingAddr == address(0)) {
            vestingAddr = _createVesting(_sender);
        }

        _stakeTokens(_sender, vestingAddr);
    }

createVesting

Creates vesting contract (if it hasn't been created yet) for the calling user.

function createVesting() public nonpayable
returns(_vestingAddress address)
Source Code
function createVesting() public returns (address _vestingAddress) {
        _vestingAddress = _createVesting(msg.sender);
    }

stakeTokens

Stakes tokens for a user who already have a vesting created.

function stakeTokens() public nonpayable
Source Code
function stakeTokens() public {
        VestingLogic vesting = VestingLogic(_getVesting(msg.sender));

        require(
            cliff == vesting.cliff() && duration == vesting.duration(),
            "Wrong Vesting Schedule."
        );

        _stakeTokens(msg.sender, address(vesting));
    }

withdrawAndStakeTokens

Withdraws unlocked tokens and Stakes Locked tokens for a user who already have a vesting created.

function withdrawAndStakeTokens(address _receiverAddress) external nonpayable

Arguments

Name Type Description
_receiverAddress address If specified, the unlocked balance will go to this address, else to msg.sender.
Source Code
function withdrawAndStakeTokens(address _receiverAddress) external {
        _withdraw(msg.sender, _receiverAddress);
        _createVestingAndStake(msg.sender);
    }

withdrawAndStakeTokensFrom

⤾ overrides ILockedSOV.withdrawAndStakeTokensFrom

Withdraws unlocked tokens and Stakes Locked tokens for a user who already have a vesting created.

function withdrawAndStakeTokensFrom(address _userAddress) external nonpayable

Arguments

Name Type Description
_userAddress address The address of user tokens will be withdrawn.
Source Code
function withdrawAndStakeTokensFrom(address _userAddress) external {
        _withdraw(_userAddress, _userAddress);
        _createVestingAndStake(_userAddress);
    }

startMigration

Function to start the process of migration to new contract.

function startMigration(address _newLockedSOV) external nonpayable onlyAdmin 

Arguments

Name Type Description
_newLockedSOV address The new locked sov contract address.
Source Code
function startMigration(address _newLockedSOV) external onlyAdmin {
        require(_newLockedSOV != address(0), "New Locked SOV Address is Invalid.");
        newLockedSOV = ILockedSOV(_newLockedSOV);
        SOV.approve(_newLockedSOV, SOV.balanceOf(address(this)));
        migration = true;

        emit MigrationStarted(msg.sender, _newLockedSOV);
    }

transfer

Function to transfer the locked balance from this contract to new LockedSOV Contract.

function transfer() external nonpayable migrationAllowed 
Source Code
function transfer() external migrationAllowed {
        uint256 amount = lockedBalances[msg.sender];
        lockedBalances[msg.sender] = 0;

        newLockedSOV.depositSOV(msg.sender, amount);

        emit UserTransfered(msg.sender, amount);
    }

_createVesting

Creates a Vesting Contract for a user.

function _createVesting(address _tokenOwner) internal nonpayable
returns(_vestingAddress address)

Arguments

Name Type Description
_tokenOwner address The owner of the vesting contract.

Returns

_vestingAddress The Vesting Contract Address.

Source Code
function _createVesting(address _tokenOwner) internal returns (address _vestingAddress) {
        /// Here zero is given in place of amount, as amount is not really used in `vestingRegistry.createVesting()`.
        vestingRegistry.createVesting(_tokenOwner, 0, cliff, duration);
        _vestingAddress = _getVesting(_tokenOwner);
        emit VestingCreated(msg.sender, _tokenOwner, _vestingAddress);
    }

_getVesting

Returns the Vesting Contract Address.

function _getVesting(address _tokenOwner) internal view
returns(_vestingAddress address)

Arguments

Name Type Description
_tokenOwner address The owner of the vesting contract.

Returns

_vestingAddress The Vesting Contract Address.

Source Code
function _getVesting(address _tokenOwner) internal view returns (address _vestingAddress) {
        return vestingRegistry.getVesting(_tokenOwner);
    }

_stakeTokens

Stakes the tokens in a particular vesting contract.

function _stakeTokens(address _sender, address _vesting) internal nonpayable

Arguments

Name Type Description
_sender address
_vesting address The Vesting Contract Address.
Source Code
function _stakeTokens(address _sender, address _vesting) internal {
        uint256 amount = lockedBalances[_sender];
        lockedBalances[_sender] = 0;

        require(SOV.approve(_vesting, amount), "Approve failed.");
        VestingLogic(_vesting).stakeTokens(amount);

        emit TokenStaked(_sender, _vesting, amount);
    }

getLockedBalance

⤾ overrides ILockedSOV.getLockedBalance

The function to get the locked balance of a user.

function getLockedBalance(address _addr) external view
returns(_balance uint256)

Arguments

Name Type Description
_addr address The address of the user to check the locked balance.

Returns

_balance The locked balance of the address _addr.

Source Code
function getLockedBalance(address _addr) external view returns (uint256 _balance) {
        return lockedBalances[_addr];
    }

getUnlockedBalance

⤾ overrides ILockedSOV.getUnlockedBalance

The function to get the unlocked balance of a user.

function getUnlockedBalance(address _addr) external view
returns(_balance uint256)

Arguments

Name Type Description
_addr address The address of the user to check the unlocked balance.

Returns

_balance The unlocked balance of the address _addr.

Source Code
function getUnlockedBalance(address _addr) external view returns (uint256 _balance) {
        return unlockedBalances[_addr];
    }

adminStatus

The function to check is an address is admin or not.

function adminStatus(address _addr) external view
returns(_status bool)

Arguments

Name Type Description
_addr address The address of the user to check the admin status.

Returns

_status True if admin, False otherwise.

Source Code
function adminStatus(address _addr) external view returns (bool _status) {
        return isAdmin[_addr];
    }

Contracts