Skip to content

Commit

Permalink
added more docs
Browse files Browse the repository at this point in the history
  • Loading branch information
BkChoy committed Sep 14, 2024
1 parent 082dc46 commit 03b62ae
Show file tree
Hide file tree
Showing 13 changed files with 193 additions and 27 deletions.
17 changes: 15 additions & 2 deletions contracts/core/StakingPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,25 @@ contract StakingPool is StakingRewardsPool {
using SafeERC20Upgradeable for IERC20Upgradeable;

struct Fee {
// address to receive fee
address receiver;
// value of fee in basis points
uint256 basisPoints;
}

// list of all strategies controlled by pool
address[] private strategies;
// total number of tokens staked in the pool
uint256 public totalStaked;
// max number of tokens that can sit in the pool outside of a strategy
uint256 public unusedDepositLimit;

// list of fees that are paid on rewards
Fee[] private fees;

// address of priority pool
address public priorityPool;
// address of rebase controller
address public rebaseController;
uint16 private poolIndex; // deprecated

Expand All @@ -51,8 +59,8 @@ contract StakingPool is StakingRewardsPool {
* @param _token address of asset token
* @param _liquidTokenName name of liquid staking token
* @param _liquidTokenSymbol symbol of liquid staking token
* @param _fees list of fees
* @param _unusedDepositLimit maximum amount of unused deposits that can sit in the pool
* @param _fees list of fees that are paid on rewards
* @param _unusedDepositLimit max number of tokens that can sit in the pool outside of a strategy
*/
function initialize(
address _token,
Expand Down Expand Up @@ -518,6 +526,7 @@ contract StakingPool is StakingRewardsPool {
address[][] memory receivers = new address[][](strategies.length + 1);
uint256[][] memory feeAmounts = new uint256[][](strategies.length + 1);

// sum up rewards and fees across strategies
for (uint256 i = 0; i < _strategyIdxs.length; ++i) {
IStrategy strategy = IStrategy(strategies[_strategyIdxs[i]]);

Expand All @@ -538,10 +547,12 @@ contract StakingPool is StakingRewardsPool {
}
}

// update totalStaked if there was a net change in deposits
if (totalRewards != 0) {
totalStaked = uint256(int256(totalStaked) + totalRewards);
}

// calulate fees if net positive rewards were earned
if (totalRewards > 0) {
receivers[receivers.length - 1] = new address[](fees.length);
feeAmounts[feeAmounts.length - 1] = new uint256[](fees.length);
Expand All @@ -556,10 +567,12 @@ contract StakingPool is StakingRewardsPool {
}
}

// safety check
if (totalFeeAmounts >= totalStaked) {
totalFeeAmounts = 0;
}

// distribute fees to receivers if there are any
if (totalFeeAmounts > 0) {
uint256 sharesToMint = (totalFeeAmounts * totalShares) /
(totalStaked - totalFeeAmounts);
Expand Down
6 changes: 5 additions & 1 deletion contracts/core/base/StakingRewardsPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,20 @@ import "../tokens/base/ERC677Upgradeable.sol";
* @dev Rewards can be positive or negative (user balances can increase and decrease)
*/
abstract contract StakingRewardsPool is ERC677Upgradeable, UUPSUpgradeable, OwnableUpgradeable {
// used to prevent vault inflation attack
uint256 private constant DEAD_SHARES = 10 ** 3;

// address of staking asset token
IERC20Upgradeable public token;

// mapping of staker address to their shares balance
mapping(address => uint256) private shares;
// total number of shares minted
uint256 public totalShares;

/**
* @notice Initializes the contract
* @param _token address of asset token
* @param _token address of staking asset token
* @param _liquidTokenName name of liquid staking token
* @param _liquidTokenSymbol symbol of liquid staking token
*/
Expand Down
6 changes: 6 additions & 0 deletions contracts/core/lstRewardsSplitter/LSTRewardsSplitter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,21 @@ contract LSTRewardsSplitter is Ownable {
using SafeERC20 for IERC677;

struct Fee {
// address to receive fee
address receiver;
// value of fee in basis points
uint256 basisPoints;
}

// address of contract that conrols this splitter
ILSTRewardsSplitterController public controller;
// address of liquid staking token
IERC677 public lst;

// list of fees that are paid on rewards
Fee[] private fees;

// total number of tokens deposited without rewards
uint256 public principalDeposits;

event Deposit(uint256 amount);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ import "./LSTRewardsSplitter.sol";
contract LSTRewardsSplitterController is Ownable {
using SafeERC20 for IERC677;

// mapping of account address to corresponding splitter
mapping(address => ILSTRewardsSplitter) public splitters;
// list of accounts that have splitters
address[] internal accounts;

// address of liquid staking token
address public lst;
// min amount of new rewards required to split
uint256 public rewardThreshold;

error InvalidToken();
Expand Down
31 changes: 28 additions & 3 deletions contracts/core/priorityPool/PriorityPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,31 +27,51 @@ contract PriorityPool is UUPSUpgradeable, OwnableUpgradeable, PausableUpgradeabl
CLOSED
}

// address of staking asset token
IERC20Upgradeable public token;
// address of staking pool and liquid staking token
IStakingPool public stakingPool;
// address of SDL pool
ISDLPool public sdlPool;
// address of oracle contract that handles LST distribution
address public distributionOracle;

// min amount of tokens that can be deposited into the staking pool in a single tx
uint128 public queueDepositMin;
// max amount of tokens that can be deposited into the staking pool in a single tx
uint128 public queueDepositMax;
// current status of the pool
PoolStatus public poolStatus;

// merkle root for the latest distribution tree
bytes32 public merkleRoot;
// ipfs hash where the latest distribution tree is stored
bytes32 public ipfsHash;
// number of entries in the latest distribution tree
uint256 public merkleTreeSize;

// total number of tokens queued for deposit into the staking pool
uint256 public totalQueued;
// total number of tokens deposited into the staking pool since the last distribution
uint256 public depositsSinceLastUpdate;
// total number of shares received for tokens deposited into the staking pool since the last distribution
uint256 private sharesSinceLastUpdate;

// list of all accounts that have ever queued tokens
address[] private accounts;
// stores each account's index in the distribution tree
mapping(address => uint256) private accountIndexes;
// stores the lifetime amount of queued tokens for each account less any tokens that were unqueued
mapping(address => uint256) private accountQueuedTokens;
// stores the total amount of LSTs that each account has claimed
mapping(address => uint256) private accountClaimed;
// stored the total amount of LST shares that each account has claimed
mapping(address => uint256) private accountSharesClaimed;

// address with authorization to pause the pool
address public rebaseController;

// address of withdrawal pool
IWithdrawalPool public withdrawalPool;

event UnqueueTokens(address indexed account, uint256 amount);
Expand Down Expand Up @@ -90,11 +110,11 @@ contract PriorityPool is UUPSUpgradeable, OwnableUpgradeable, PausableUpgradeabl

/**
* @notice Initializes contract
* @param _token address of asset token
* @param _token address of staking asset token
* @param _stakingPool address of staking pool
* @param _sdlPool address of SDL pool
* @param _queueDepositMin min amount of tokens required for deposit into staking pool strategies
* @param _queueDepositMax max amount of tokens that can be deposited into staking pool strategies at once
* @param _queueDepositMin min amount of tokens that can be deposited into the staking pool in a single tx
* @param _queueDepositMax mmaxin amount of tokens that can be deposited into the staking pool in a single tx
**/
function initialize(
address _token,
Expand Down Expand Up @@ -261,6 +281,7 @@ contract PriorityPool is UUPSUpgradeable, OwnableUpgradeable, PausableUpgradeabl
uint256 toWithdraw = _amountToWithdraw;
address account = msg.sender;

// attempt to unqueue tokens before withdrawing if flag is set
if (_shouldUnqueue == true) {
_requireNotPaused();

Expand All @@ -286,6 +307,7 @@ contract PriorityPool is UUPSUpgradeable, OwnableUpgradeable, PausableUpgradeabl
}
}

// attempt to withdraw if tokens remain after unqueueing
if (toWithdraw != 0) {
IERC20Upgradeable(address(stakingPool)).safeTransferFrom(
account,
Expand Down Expand Up @@ -315,6 +337,8 @@ contract PriorityPool is UUPSUpgradeable, OwnableUpgradeable, PausableUpgradeabl
if (_amountToUnqueue > totalQueued) revert InsufficientQueuedTokens();

address account = msg.sender;

// verify merkle proof only if sender is included in tree
if (accountIndexes[account] < merkleTreeSize) {
bytes32 node = keccak256(
bytes.concat(keccak256(abi.encode(account, _amount, _sharesAmount)))
Expand Down Expand Up @@ -489,6 +513,7 @@ contract PriorityPool is UUPSUpgradeable, OwnableUpgradeable, PausableUpgradeabl

/**
* @notice Executes a batch of withdrawals that have been queued in the withdrawal pool
* @dev withdraws tokens from the staking pool and sends them to the withdrawal pool
* @param _amount total amount to withdraw
* @param _data list of withdrawal data passed to staking pool strategies
*/
Expand Down
24 changes: 22 additions & 2 deletions contracts/core/priorityPool/WithdrawalPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,54 @@ import "../interfaces/IPriorityPool.sol";
contract WithdrawalPool is UUPSUpgradeable, OwnableUpgradeable {
using SafeERC20Upgradeable for IERC20Upgradeable;

// a withdrawal request made by an account
struct Withdrawal {
// number of LST shares remaining (may be withdrawable or not)
uint128 sharesRemaining;
// number of tokens that can be withdrawn
uint128 partiallyWithdrawableAmount;
}

// a withdrawal batch created when some withdrawals were finalized
struct WithdrawalBatch {
// index of last withdrawal that was finalized in this batch
uint128 indexOfLastWithdrawal;
// the exchange rate of LSTs per underlying shares at the time of this batch
uint128 stakePerShares;
}

// address of staking token
IERC20Upgradeable public token;
// address of liquid staking token
IERC20Upgradeable public lst;
// address of priority pool
IPriorityPool public priorityPool;

// list of withdrawal requests in order of creation
Withdrawal[] internal queuedWithdrawals;
// stores a list of withdrawal requests for each account
mapping(address => uint256[]) internal queuedWithdrawalsByAccount;
// mapping of withdrawal request index to the request owner
mapping(uint256 => address) internal withdrawalOwners;

// total number of LST shares queued for withdrawal
uint256 internal totalQueuedShareWithdrawals;
// index of the withdrawal that's at the front of the queue
uint256 public indexOfNextWithdrawal;

// list of withdrawal batches in order of creation
WithdrawalBatch[] internal withdrawalBatches;
// all batches before this index have had all withdrawal requests fully withdrawn
uint128 public withdrawalBatchIdCutoff;
// all withdrawal requests before this index have been fully withdrawn
uint128 public withdrawalIdCutoff;

// min amount of LSTs that can be queued for withdrawal
uint256 public minWithdrawalAmount;

// min amount of time between execution of withdrawals
uint64 public minTimeBetweenWithdrawals;
// time of last execution of withdrawals
uint64 public timeOfLastWithdrawal;

event QueueWithdrawal(address indexed account, uint256 amount);
Expand All @@ -68,8 +88,8 @@ contract WithdrawalPool is UUPSUpgradeable, OwnableUpgradeable {
* @param _token address of asset token
* @param _lst address of liquid staking token
* @param _priorityPool address of priority pool
* @param _minWithdrawalAmount minimum amount that can be queued for withdrawal
* @param _minTimeBetweenWithdrawals minimum time between withdrawals
* @param _minWithdrawalAmount minimum amount of LSTs that can be queued for withdrawal
* @param _minTimeBetweenWithdrawals min amount of time between execution of withdrawals
*/
function initialize(
address _token,
Expand Down
10 changes: 6 additions & 4 deletions contracts/linkStaking/CommunityVCS.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import "./interfaces/ICommunityVault.sol";
* @notice Implemented strategy for managing multiple Chainlink community staking vaults
*/
contract CommunityVCS is VaultControllerStrategy {
// min number of non-full vaults before a new batch is deployed
uint128 public vaultDeploymentThreshold;
// number of vaults to deploy when threshold is met
uint128 public vaultDeploymentAmount;

event SetVaultDeploymentParams(uint128 vaultDeploymentThreshold, uint128 vaultDeploymentAmount);
Expand All @@ -28,11 +30,11 @@ contract CommunityVCS is VaultControllerStrategy {
* @param _stakeController address of Chainlink staking contract
* @param _vaultImplementation address of the implementation contract to use when deploying new vaults
* @param _fees list of fees to be paid on rewards
* @param _maxDepositSizeBP basis point amount of the remaing deposit room in the Chainlink staking contract
* @param _maxDepositSizeBP max basis point amount of the deposit room in the Chainlink staking contract
* that can be deposited at once
* @param _vaultMaxDeposits maximum deposit limit for a single vault
* @param _vaultDeploymentThreshold the min number of non-full vaults before a new batch is deployed
* @param _vaultDeploymentAmount amount of vaults to deploy when threshold is met
* @param _vaultMaxDeposits max number of tokens that a vault can hold
* @param _vaultDeploymentThreshold min number of non-full vaults before a new batch is deployed
* @param _vaultDeploymentAmount number of vaults to deploy when threshold is met
* @param _vaultDepositController address of vault deposit controller
*
*/
Expand Down
Loading

0 comments on commit 03b62ae

Please sign in to comment.