eip | 4000 (*unofficial) |
---|---|
title | ERC-4000 Staking-Reward Pool Standard |
authors | Dotta, vfat, DkNinja |
type | Standards Track |
category | ERC |
status | Idea |
created | 2021-04-15 |
Context
Below is a draft EIP for a staking-reward pool standard. The goal is to define an easy-to-use convention for staking-reward pools.
Staking-reward pools are a common way for projects to incentivize desired behaviors like providing liquidity, bonding, token distribution, or loan origination.
The popularity of the staking-reward pool mechanism can be seen on websites like vfat.tools and apy.vision which track hundreds of reward pools across the ecosystem.
Nearly every new project launches reward pool contracts and nearly every project implements the interface differently.
The standard below is based on the author's interactions with hundreds of "Masterchef-" and "Synthetix-"style staking-rewards pools.
Adoption of a standard for staking-reward pools will benefit the ecosystem by composibility, similar to that seen with ERC20 tokens.
Request for Comments
The authors request your comments and feedback on this document before submitting for official EIP consideration in late-April 2021.
Blockquotes indicate thoughts and open questions and will be removed from the final EIP draft
Dotta
April 15, 2021
A standard interface for staking pools with rewards.
The following standard allows for the implementation of a standard API for staking-rewards pools within smart contracts.
This standard provides basic functionality to stake tokens in smart contracts with multiple pools and inspect the rewards for doing so.
Staking-reward pools are a common way for projects to incentivize desired behaviors such as providing liquidity, bonding, token distribution, or loan origination.
This document specifies a standard interface that allows any staking-reward pools on Ethereum to be re-used by other applications such as wallets, user interfaces, yield aggregators, and other smart contracts.
NOTES:
0.8.3
(or above)Returns the total number of pools
Returns the information about a pool.
Where:
stakingToken
is the address of the token to be staked in poolIdx
rewardToken
is the address of the token which is rewarded for staking in poolIdx
stakedAmount
is the total number of tokens currently staked in poolIdx
rewardAmount
is the total number of tokens currently allocated as rewards to the pool at poolIdx
rewardPerBlock
is the sum total of reward tokens accrued to all stakers in poolIdx
for the current blockstartBlock
is the first block number at which rewards will accrue for the pool at poolIdx
Returns the information about userAddress
at poolIdx
Where:
stakedAmount
is the number of tokens userAddress
has staked in poolIdx
rewardAmount
is the number of tokens credited to userAddress
in poolIdx
that have not yet been withdrawnReturns the sum total of reward tokens accrued to all stakers in poolIdx
at blockNum
.
OPTIONAL - This method can be used to improve usability, but interfaces and other contracts MUST NOT expect these values to be present.
Note - The purpose of this optional method is to allow for calculation of non-linear reward accrual curves.
amount
of staking tokens from the calling user to the pool at poolIdx
andDeposit
event andpoolIdx
to the calling user andClaim
event.Note - amount
of 0 MUST be allowed, which has the effect of withdrawing all claimable rewards.
amount
of staking tokens from the pool at poolIdx
to the calling user andWithdraw
event andpoolIdx
to the calling user andClaim
event.Note - amount
of 0 MUST be allowed, which has the effect of withdrawing all claimable rewards.
poolIdx
to the calling user andClaim
event.MUST trigger when staking tokens are deposited, including zero value deposits.
Where:
user
is the address of the depositing userpoolIdx
is the index of the poolstakeAmount
is the amount of the stake token depositedMUST trigger when staking tokens are withdrawn, including zero value withdrawals.
Where:
user
is the address of the depositing userpoolIdx
is the index of the poolstakeAmount
is the amount of the stake token withdrawnMUST trigger when reward tokens are withdrawn, including zero value withdrawals.
Where:
user
is the address of the depositing userpoolIdx
is the index of the poolrewardAmount
is the amount of the reward token withdrawnQ: Should we specify ERC20 as part of this standard?
A: Probably not because this ERC might be useful for other sorts of tokens e.g. ERC-721 NFTsQ: What about
allocPoint
,getMultiplier
,lastRewardBlock
,rewardDebt
etc?
A: While commonly exposed in "Masterchef" contracts, these values are internals that don't need to be exposed in the standard. A contract can expose them if they desire.Q: What about a global
rewardPerBlock
that shows the total emission per block for the entire contract?
A: This standard allows for differnt reward tokens to be emitted for each pool, so a globalrewardPerBlock
would not be usefulQ: What about vesting and locking both stake and rewards?
A: This standard doesn't address those issues.Q: What about legacy staking-reward pool contracts that don't conform to this standard?
A: It should be straightforward to write a Masterchef-to-ERC-4000 proxy-adapter contract (cf. multicall) that adapts the values for any standard Masterchef- or Synthetix-style pool.
Historical links related to this standard:
Copyright and related rights waived via CC0.