Staking Platform
This guide explores the development of a staking platform, leveraging the capabilities of Superfluid's Distribution Pools (also called the General Distributions Agreement - GDA).
Repository
The contract and associated tests can be found in the SuperfluidStaking Repository.
Contract Architecture
The SuperfluidStaking system consists of two main contracts:
- SuperfluidStaking: The core contract that manages staking, unstaking, and reward distribution.
- ClaimContract: An auxiliary contract created for each staker to manage their individual rewards.
SuperfluidStaking Contract
This contract is responsible for:
- Accepting stakes from users
- Managing the total staked amount
- Creating and upgrading Super Tokens for rewards
- Creating and managing a Superfluid pool for reward distribution
- Handling the unstaking process
- Facilitating reward claims
Key components:
underlyingStakedToken
: The ERC20 token that users stakeunderlyingRewardsToken
: The ERC20 token used for rewardssuperToken
: The Super Token wrapper for the rewards tokenpool
: The Superfluid pool used for distributing rewardsscalingFactor
: A factor used to scale down staked amounts for precision
ClaimContract
This contract is created for each staker and is responsible for:
- Claiming rewards from the Superfluid pool
- Holding claimed rewards until withdrawn by the staker
Setup and Installation
To set up the development environment and run the tests, follow these steps:
-
Install Foundry
Foundry is a blazing fast, portable and modular toolkit for Ethereum application development. To install Foundry, run the following command:
curl -L https://foundry.paradigm.xyz | bash
Then, run
foundryup
in a new terminal session to install the latest version. -
Clone the repository
git clone https://github.com/superfluid-finance/sf-example-staking
cd superfluid-staking -
Install dependencies
Use Forge to install the necessary dependencies:
forge install
This will install OpenZeppelin contracts and Superfluid contracts as specified in the
foundry.toml
file. -
Compile the contracts
forge build
-
Run the tests
forge test
This will run all the test cases defined in the
test
directory.
Contract Interaction Flow
-
Deployment: The contract is deployed with parameters for the staked token, rewards token, Superfluid token factory, and scaling factor.
-
Supplying Funds: The contract owner calls
supplyFunds
to add rewards to the pool. -
Staking: Users call
stake
to deposit tokens. This creates a ClaimContract if they don't have one and updates their units in the Superfluid pool. -
Unstaking: Users call
unstake
to withdraw their staked tokens. This updates their units in the Superfluid pool. -
Claiming Rewards: Users call
claimRewards
to receive their accumulated rewards. This interacts with their ClaimContract to fetch and distribute rewards.
Key Considerations
- The use of a scaling factor is crucial for maintaining precision in reward calculations, especially when dealing with tokens of different decimals.
- The ClaimContract pattern allows for efficient reward claiming without requiring frequent updates to the main contract.
- The contract leverages Superfluid's streaming capabilities for continuous and gas-efficient reward distribution.
Testing
The test suite (located in test/SuperfluidStaking.t.sol
) covers various scenarios including:
- Staking and unstaking
- Reward distribution and claiming
- Multiple users interacting with the contract
- Edge cases and potential vulnerabilities
To run a specific test:
forge test --match-test testFunctionName
Replace testFunctionName
with the name of the test function you want to run.
Conclusion
The SuperfluidStaking contract provides a robust and efficient system for stake-based reward distribution using Superfluid. By following this guide, you should be able to understand the contract's architecture, set up your development environment, and run the tests.