Uniswap V3 introduced its new staking program and moved on from ERC20 LP tokens to ERC721 positions. The old logic of rewarding LP tokens does not work in the third version of this exchange. However, Uniswap has a new contract that distributes rewards to liquidity providers with NFT positions.
To enable a reward mechanism — we need to create an incentive and invite users to stake there. The general idea of staking is covered in the first part.
How to Stake in Uniswap V3. Part I
However, it is still quite complex from the end user’s perspective, especially if the user performs all actions separately.
This article covers examples that include web3 integration for a simplified UI/UX experience. All functions can be merged and performed with just several methods (stake/unstake and withdraw).
- Incentive Data;
- Web3 Integration.
The general workflow would look like this:
- The user comes to the platform with an NFT (proof of liquidity provision);
- The user clicks the “stake” button and agrees to pass NFT to the predefined incentive;
- The client calls multiple functions to the NFT position contract;
- NFT position contract performs the transfer;
- Stacker contract receives the token and stakes it based on the received incentive key.
Before proceeding, let’s define the data required for staking integration to the front end.
- Incentive(s) — can be stored in config or any other preferred way. Data and field logic is covered in the first part.
The config file with two incentives may look like this:
- incentiveTuple (line 23) — passed to the staking contract to manually stake/unstake. It is useful when the position is already in the staker contract.
- incentiveKeyEncoded (line 28) — passed to NFTPositions manager contract to stake via safeTransfer function. It is useful when the position is not staked nor transferred to the staker contract.
- incentiveKeyHashed (line 36) — passed to the staking contract/subgraph to view data.
Node example (with the imported config):
The user that just received its position after providing liquidity has to complete the steps:
- Approve NFT token (position);
- Send NFT token to the Staker contract;
However, all of the functions can be merged thanks to implemented Multicall and onERC721Received hook in Uniswap V3.
Example of how to form and send multicall (lines 24 —35):
A multicall example with the “ethers” package can be found in Mark Curchin’s article.
The user that wants to unstake tokens and staked them (so far) only in one position — has to perform these steps to retrieve everything:
- Unstake NFT token (position);
- Withdraw NFT token (position);
Unstaking multicall would be similar to the staking one (lines 22–30):
Points to keep in mind:
- We do not always require the multicall function for staking. For example, if the token is already staked in one incentive — there is no need to approve or transfer — it is enough to use only one stakeTokenfunction in the staker contract.
- We also do not always require multicall for unstaking . The user might want to unstake from one incentive but leave the token in another. In this case, we only use the unstakeToken function.
- Tokens can be unsticked only by the depositors until the incentive end date.
End of Part II
Thank you for reading. I hope this article will be helpful for the integration of the Uniswap V3 staking program into your project.
If you have any questions, feel free to ask. Make sure to check out mentioned articles (linked below).
Thanks to Justinas for helping figure out the Uniswap V3 model 🙂
- Uniswap V3 documentation: https://docs.uniswap.org/protocol/reference/periphery/base/Multicall
- Mark Curchin Uniswap V3 staking article:https://holdex.io/c/learn/how-to-stake-tokens-with-uniswap-v3-staking-program
New to trading? Try crypto trading bots or copy trading
How to Stake in Uniswap V3. Part II was originally published in Coinmonks on Medium, where people are continuing the conversation by highlighting and responding to this story.