Skip to content

core staking contracts

StakingPool Contract: Liquid Staking and Rebasing LSTs

StakingPool is one of the most important pieces of the protocol as it handles the liquid staking of tokens. When a user stakes some amount of tokens (such as LINK), they receive liquid staking tokens (such as stLINK) at a 1:1 ratio. These liquid staking tokens represent a user’s staked balance and must be burned to withdraw the underlying tokens they represent.

Once tokens have been staked into the pool, they are deposited into one or more strategy contracts controlled by the pool. These strategies then take the deposited tokens and use them to earn rewards which are distributed to stakers.

In the case of LINK staking, the tokens are deposited into the Chainlink staking contracts.

The liquid staking token issued by StakingPool is a rebasing token so rewards will be automatically distributed to stakers without any action on their part. This is possible by using a “shares” accounting model where a share represents a certain percentage ownership of the pool. When a user stakes, they receive a number of shares determined by the ratio of total shares to total tokens in the pool. The amount of shares a user owns remains constant unless they stake or withdraw but the ratio of total shares to total tokens changes with each rebase so their shares will be worth more tokens after each rebase. The new token value of their shares will be automatically reflected in their token balance.

While unlikely, it is also possible for a rebase to be negative if strategies earned net negative rewards since the last rebase due to slashing penalties. In this case, each share will be worth less tokens so a user’s token balance will decrease.

All standard ERC20 functions are implemented for StakingPool

Returns the staking token for the pool

function token() external view returns (address)
Name Type Description
token address Address of staking token

Returns the address of the priority pool for this pool

function priorityPool() external view returns (address)
Name Type Description
priorityPool address address of priority pool

Returns the total amount of shares in the pool

function totalShares() external view returns (uint256)
Name Type Description
sharesAmount uint256 Total shares in the pool

Returns the amount of shares owned by an account

function sharesOf(address _account) public view returns (uint256)
Name Type Description
_account address Address of account
Name Type Description
sharesBalance uint256 Total shares owned by account

Returns the amount of shares that corresponds to an amount of stake

function getSharesByStake(uint256 _amount) public view returns (uint256)
Name Type Description
_amount uint256 Amount of stake
Name Type Description
sharesAmount uint256 Corresponding amount of shares

Returns the amount of stake that corresponds to an amount of shares

function getStakeByShares(uint256 _amount) public view returns (uint256)
Name Type Description
_amount uint256 Amount of shares
Name Type Description
stakeAmount uint256 Corresponding amount of stake

Returns the total amount of tokens in the pool

function totalStaked() external view returns (uint256)
Name Type Description
stakedAmount uint256 Total tokens in the pool

Returns a list of all active strategies

function getStrategies() external view returns (address[])
Name Type Description
strategies address[] List of strategy contract addresses

Returns a list of all fees

function getFees() external view returns (struct StakingPool.Fee[])
Name Type Description
fees struct Fee[] list of fees

Returns the maximum amount of tokens that the pool can hold

function getMaxDeposits() public view returns (uint256)
Name Type Description
maxDeposits uint256 maximum deposit limit

Returns the minimum amount of tokens that must remain in the pool

function getMinDeposits() public view returns (uint256)
Name Type Description
minDeposits uint256 minimum deposit limit

Returns the amount of unused asset tokens sitting in this pool outside a strategy

These tokens earn no yield and will be deposited ASAP on the next call to _depositLiquidity

function getUnusedDeposits() external view returns (uint256)
Name Type Description
unusedDeposits uint256 amount of unused tokens

Returns the sum of available deposit room across all strategies

Does not account for unused deposits sitting in pool

function getStrategyDepositRoom() external view returns (uint256)
Name Type Description
strategyDepositRoom uint256 available deposit room in strategies

Returns the total available deposit room for this pool

Accounts for unused deposits sitting in pool

function canDeposit() external view returns (uint256)
Name Type Description
canDeposit uint256 available deposit room

Returns the total available withdrawal room for this pool

function canWithdraw() external view returns (uint256)
Name Type Description
canWithdraw uint256 available withdrawal room

Returns the amount of rewards earned since the last call to updateStrategyRewards and the
amount of fees that will be paid on the rewards

function getStrategyRewards(uint256[] _strategyIdxs) external view returns (int256, uint256)
Name Type Description
_strategyIdxs uint256[] Indexes of strategies to sum rewards/fees for
Name Type Description
rewards int256 Total rewards
fees uint256 Total fees

Deposits staking tokens and mints liquid staking tokens

function deposit(address _account, uint256 _amount, bytes _data) external
Name Type Description
_account address address of account to stake for
_amount uint256 amount to stake
_data bytes list of deposit data passed to strategies

Withdraws staking tokens and burns liquid staking tokens

function withdraw(address _account, address _receiver, uint256 _amount, bytes _data) external
Name Type Description
_account address Address of account to withdraw for
_receiver address Address to receive withdrawal
_amount uint256 Amount to withdraw
_data bytes list of withdrawal data passed to strategies

Transfers tokens to an address and calls onTokenTransfer with additional data if the recipient is a contract

function transferAndCall(address _to, uint256 _value, bytes _data) external returns (bool)
Name Type Description
_to address Address to send the tokens to
_value uint256 Value of token transfer
_data bytes Calldata included in the transfer

Manually deposits asset tokens into a specific strategy

function strategyDeposit(uint256 _index, uint256 _amount) external
Name Type Description
_index uint256 Index of strategy
_amount uint256 Amount to deposit

Manually withdraws asset tokens from a strategy

function strategyWithdraw(uint256 _index, uint256 _amount) external
Name Type Description
_index uint256 Index of strategy
_amount uint256 Amount to withdraw

Adds a new strategy

function addStrategy(address _strategy) external
Name Type Description
_strategy address Address of strategy contract

Removes a strategy

function removeStrategy(uint256 _index, bytes _strategyUpdateData, bytes _strategyWithdrawalData) external
Name Type Description
_index uint256 Index of strategy
_strategyUpdateData bytes update data passed to strategy
_strategyWithdrawalData bytes withdrawal data passed to strategy

Reorders strategies

function reorderStrategies(uint256[] _newOrder) external
Name Type Description
_newOrder uint256[] List containing strategy indexes in a new order

Adds a new fee

function addFee(address _receiver, uint256 _feeBasisPoints) external
Name Type Description
_receiver address Address of fee receiver
_feeBasisPoints uint256 Fee in basis points

Updates an existing fee

function updateFee(uint256 _index, address _receiver, uint256 _feeBasisPoints) external
Name Type Description
_index uint256 Index of fee
_receiver address Address of fee receiver
_feeBasisPoints uint256 Fee in basis points

Distributes rewards/fees based on balance changes in strategies since the last update

function updateStrategyRewards(uint256[] _strategyIdxs, bytes _data) public
Name Type Description
_strategyIdxs uint256[] Indexes of strategies to update rewards for
_data bytes update data passed to each strategy

Transfers shares from the sender to another account

function transferShares(address _recipient, uint256 _sharesAmount) external
Name Type Description
_recipient address account to transfer shares to
_sharesAmount uint256 amount of shares to transfer

Transfers shares between accounts

function transferSharesFrom(address _sender, address _recipient, uint256 _sharesAmount) external
Name Type Description
_sender address account to transfer shares from
_recipient address account to transfer shares to
_sharesAmount uint256 amount of shares to transfer

Sets the address of the priority pool

function setPriorityPool(address _priorityPool) external
Name Type Description
_priorityPool address address of priority pool

Sets the maximum amount of unused deposits that can sit in the pool

function setUnusedDepositLimit(uint256 _unusedDepositLimit) external
Name Type Description
_unusedDepositLimit uint256 maximum amount of unused deposits

Sets the address of the rebase controller

function setRebaseController(address _rebaseController) external
Name Type Description
_rebaseController address address of rebase controller

Burns the sender’s liquid staking tokens, effectively donating their underlying stake to the pool

function burn(uint256 _amount) external
Name Type Description
_amount uint256 amount to burn

Deposits asset tokens into the pool without minting liquid staking tokens, effectively donating them to the pool

function donateTokens(uint256 _amount) external
Name Type Description
_amount uint256 amount to deposit