Skip to content

Latest commit

 

History

History
663 lines (550 loc) · 19.9 KB

StakingPoolLibV1.md

File metadata and controls

663 lines (550 loc) · 19.9 KB

StakingPoolLibV1.sol

View Source: contracts/libraries/StakingPoolLibV1.sol

StakingPoolLibV1

Functions

getInfoInternal

Gets the info of a given staking pool by key

function getInfoInternal(IStore s, bytes32 key, address you) external view
returns(info struct IStakingPools.StakingPoolInfoType)

Arguments

Name Type Description
s IStore Specify the store instance
key bytes32 Provide the staking pool key to fetch info for
you address Specify the address to customize the info for
Source Code
function getInfoInternal(
    IStore s,
    bytes32 key,
    address you
  ) external view returns (IStakingPools.StakingPoolInfoType memory info) {
    bool valid = s.checkIfStakingPoolExistsInternal(key);

    if (valid) {
      info.name = s.getStringByKeys(StakingPoolCoreLibV1.NS_POOL, key);

      info.stakingToken = s.getStakingTokenAddressInternal(key);
      info.stakingTokenStablecoinPair = s.getStakingTokenStablecoinPairAddressInternal(key);
      info.rewardToken = s.getRewardTokenAddressInternal(key);
      info.rewardTokenStablecoinPair = s.getRewardTokenStablecoinPairAddressInternal(key);

      info.totalStaked = s.getTotalStakedInternal(key);
      info.target = s.getTargetInternal(key);
      info.maximumStake = s.getMaximumStakeInternal(key);
      info.stakeBalance = getPoolStakeBalanceInternal(s, key);
      info.cumulativeDeposits = getPoolCumulativeDepositsInternal(s, key);
      info.rewardPerBlock = s.getRewardPerBlockInternal(key);
      info.platformFee = s.getRewardPlatformFeeInternal(key);
      info.lockupPeriod = s.getLockupPeriodInBlocksInternal(key);
      info.rewardTokenBalance = s.getRewardTokenBalanceInternal(key);
      info.accountStakeBalance = getAccountStakingBalanceInternal(s, key, you);
      info.totalBlockSinceLastReward = getTotalBlocksSinceLastRewardInternal(s, key, you);
      info.rewards = calculateRewardsInternal(s, key, you);
      info.canWithdrawFromBlockHeight = canWithdrawFromBlockHeightInternal(s, key, you);
      info.lastDepositHeight = getLastDepositHeightInternal(s, key, you);
      info.lastRewardHeight = getLastRewardHeightInternal(s, key, you);
    }
  }

getPoolStakeBalanceInternal

function getPoolStakeBalanceInternal(IStore s, bytes32 key) public view
returns(uint256)

Arguments

Name Type Description
s IStore
key bytes32
Source Code
function getPoolStakeBalanceInternal(IStore s, bytes32 key) public view returns (uint256) {
    uint256 totalStake = s.getUintByKeys(StakingPoolCoreLibV1.NS_POOL_STAKING_TOKEN_BALANCE, key);
    return totalStake;
  }

getPoolCumulativeDepositsInternal

function getPoolCumulativeDepositsInternal(IStore s, bytes32 key) public view
returns(uint256)

Arguments

Name Type Description
s IStore
key bytes32
Source Code
function getPoolCumulativeDepositsInternal(IStore s, bytes32 key) public view returns (uint256) {
    uint256 totalStake = s.getUintByKeys(StakingPoolCoreLibV1.NS_POOL_CUMULATIVE_STAKING_AMOUNT, key);
    return totalStake;
  }

getAccountStakingBalanceInternal

function getAccountStakingBalanceInternal(IStore s, bytes32 key, address account) public view
returns(uint256)

Arguments

Name Type Description
s IStore
key bytes32
account address
Source Code
function getAccountStakingBalanceInternal(
    IStore s,
    bytes32 key,
    address account
  ) public view returns (uint256) {
    return s.getUintByKeys(StakingPoolCoreLibV1.NS_POOL_STAKING_TOKEN_BALANCE, key, account);
  }

getTotalBlocksSinceLastRewardInternal

function getTotalBlocksSinceLastRewardInternal(IStore s, bytes32 key, address account) public view
returns(uint256)

Arguments

Name Type Description
s IStore
key bytes32
account address
Source Code
function getTotalBlocksSinceLastRewardInternal(
    IStore s,
    bytes32 key,
    address account
  ) public view returns (uint256) {
    uint256 from = getLastRewardHeightInternal(s, key, account);

    if (from == 0) {
      return 0;
    }

    return block.number - from;
  }

canWithdrawFromBlockHeightInternal

function canWithdrawFromBlockHeightInternal(IStore s, bytes32 key, address account) public view
returns(uint256)

Arguments

Name Type Description
s IStore
key bytes32
account address
Source Code
function canWithdrawFromBlockHeightInternal(
    IStore s,
    bytes32 key,
    address account
  ) public view returns (uint256) {
    uint256 lastDepositHeight = getLastDepositHeightInternal(s, key, account);

    if (lastDepositHeight == 0) {
      return 0;
    }

    uint256 lockupPeriod = s.getLockupPeriodInBlocksInternal(key);

    return lastDepositHeight + lockupPeriod;
  }

getLastDepositHeightInternal

function getLastDepositHeightInternal(IStore s, bytes32 key, address account) public view
returns(uint256)

Arguments

Name Type Description
s IStore
key bytes32
account address
Source Code
function getLastDepositHeightInternal(
    IStore s,
    bytes32 key,
    address account
  ) public view returns (uint256) {
    return s.getUintByKeys(StakingPoolCoreLibV1.NS_POOL_DEPOSIT_HEIGHTS, key, account);
  }

getLastRewardHeightInternal

function getLastRewardHeightInternal(IStore s, bytes32 key, address account) public view
returns(uint256)

Arguments

Name Type Description
s IStore
key bytes32
account address
Source Code
function getLastRewardHeightInternal(
    IStore s,
    bytes32 key,
    address account
  ) public view returns (uint256) {
    return s.getUintByKeys(StakingPoolCoreLibV1.NS_POOL_REWARD_HEIGHTS, key, account);
  }

calculateRewardsInternal

function calculateRewardsInternal(IStore s, bytes32 key, address account) public view
returns(uint256)

Arguments

Name Type Description
s IStore
key bytes32
account address
Source Code
function calculateRewardsInternal(
    IStore s,
    bytes32 key,
    address account
  ) public view returns (uint256) {
    uint256 totalBlocks = getTotalBlocksSinceLastRewardInternal(s, key, account);

    if (totalBlocks == 0) {
      return 0;
    }

    uint256 rewardPerBlock = s.getRewardPerBlockInternal(key);
    uint256 myStake = getAccountStakingBalanceInternal(s, key, account);
    uint256 rewards = (myStake * rewardPerBlock * totalBlocks) / 1 ether;

    uint256 poolBalance = s.getRewardTokenBalanceInternal(key);

    return rewards > poolBalance ? poolBalance : rewards;
  }

withdrawRewardsInternal

Withdraws the rewards of the caller (if any or if available).

function withdrawRewardsInternal(IStore s, bytes32 key, address account) public nonpayable
returns(rewardToken address, rewards uint256, platformFee uint256)

Arguments

Name Type Description
s IStore
key bytes32
account address
Source Code
function withdrawRewardsInternal(
    IStore s,
    bytes32 key,
    address account
  )
    public
    returns (
      address rewardToken,
      uint256 rewards,
      uint256 platformFee
    )
  {
    require(s.getRewardPlatformFeeInternal(key) <= ProtoUtilV1.MULTIPLIER, "Invalid reward platform fee");
    rewards = calculateRewardsInternal(s, key, account);

    s.setUintByKeys(StakingPoolCoreLibV1.NS_POOL_REWARD_HEIGHTS, key, account, block.number);

    if (rewards == 0) {
      return (address(0), 0, 0);
    }

    rewardToken = s.getAddressByKeys(StakingPoolCoreLibV1.NS_POOL_REWARD_TOKEN, key);

    // Update (decrease) the balance of reward token
    s.subtractUintByKeys(StakingPoolCoreLibV1.NS_POOL_REWARD_TOKEN_BALANCE, key, rewards);

    // Update total rewards given
    s.addUintByKeys(StakingPoolCoreLibV1.NS_POOL_TOTAL_REWARD_GIVEN, key, account, rewards); // To this account
    s.addUintByKeys(StakingPoolCoreLibV1.NS_POOL_TOTAL_REWARD_GIVEN, key, rewards); // To everyone

    // @suppress-division Checked side effects. If the reward platform fee is zero
    // or a very small number, platform fee becomes zero because of data loss
    platformFee = (rewards * s.getRewardPlatformFeeInternal(key)) / ProtoUtilV1.MULTIPLIER;

    // @suppress-subtraction If `getRewardPlatformFeeInternal` is 100%, the following can result in zero value.
    if (rewards - platformFee > 0) {
      IERC20(rewardToken).ensureTransfer(msg.sender, rewards - platformFee);
    }

    if (platformFee > 0) {
      IERC20(rewardToken).ensureTransfer(s.getTreasuryAddressInternal(), platformFee);
    }
  }

depositInternal

Deposit the specified amount of staking token to the specified pool.

function depositInternal(IStore s, bytes32 key, uint256 amount) external nonpayable
returns(stakingToken address, rewardToken address, rewards uint256, rewardsPlatformFee uint256)

Arguments

Name Type Description
s IStore
key bytes32
amount uint256
Source Code
function depositInternal(
    IStore s,
    bytes32 key,
    uint256 amount
  )
    external
    returns (
      address stakingToken,
      address rewardToken,
      uint256 rewards,
      uint256 rewardsPlatformFee
    )
  {
    require(amount > 0, "Enter an amount");
    require(amount <= s.getMaximumStakeInternal(key), "Stake too high");
    require(amount <= s.getAvailableToStakeInternal(key), "Target achieved or cap exceeded");

    stakingToken = s.getStakingTokenAddressInternal(key);

    // First withdraw your rewards
    (rewardToken, rewards, rewardsPlatformFee) = withdrawRewardsInternal(s, key, msg.sender);

    // Individual state
    s.addUintByKeys(StakingPoolCoreLibV1.NS_POOL_STAKING_TOKEN_BALANCE, key, msg.sender, amount);
    s.setUintByKeys(StakingPoolCoreLibV1.NS_POOL_DEPOSIT_HEIGHTS, key, msg.sender, block.number);

    // Global state
    s.addUintByKeys(StakingPoolCoreLibV1.NS_POOL_STAKING_TOKEN_BALANCE, key, amount);
    s.addUintByKeys(StakingPoolCoreLibV1.NS_POOL_CUMULATIVE_STAKING_AMOUNT, key, amount);

    IERC20(stakingToken).ensureTransferFrom(msg.sender, address(this), amount);
  }

withdrawInternal

Withdraw the specified amount of staking token from the specified pool.

function withdrawInternal(IStore s, bytes32 key, uint256 amount) external nonpayable
returns(stakingToken address, rewardToken address, rewards uint256, rewardsPlatformFee uint256)

Arguments

Name Type Description
s IStore
key bytes32
amount uint256
Source Code
function withdrawInternal(
    IStore s,
    bytes32 key,
    uint256 amount
  )
    external
    returns (
      address stakingToken,
      address rewardToken,
      uint256 rewards,
      uint256 rewardsPlatformFee
    )
  {
    require(amount > 0, "Please specify amount");

    require(getAccountStakingBalanceInternal(s, key, msg.sender) >= amount, "Insufficient balance");
    require(block.number >= canWithdrawFromBlockHeightInternal(s, key, msg.sender), "Withdrawal too early");

    stakingToken = s.getStakingTokenAddressInternal(key);

    // First withdraw your rewards
    (rewardToken, rewards, rewardsPlatformFee) = withdrawRewardsInternal(s, key, msg.sender);

    // @suppress-subtraction The maximum amount that can be withdrawn is the staked balance
    // and therefore underflow is not possible.
    // Individual state
    s.subtractUintByKeys(StakingPoolCoreLibV1.NS_POOL_STAKING_TOKEN_BALANCE, key, msg.sender, amount);

    // Global state
    s.subtractUintByKeys(StakingPoolCoreLibV1.NS_POOL_STAKING_TOKEN_BALANCE, key, amount);

    IERC20(stakingToken).ensureTransfer(msg.sender, amount);
  }

Contracts