We continue our series of instructive posts with some special recommendations for developers using Convex Finance DeFi integration!
In this article, we present tips that we have acquired over the years of auditing such integrations, you will also find a list of tools and research for self-study, we strongly recommend that you read it separately for better understanding!
This, in our opinion, is not the case; yet, the topic is rather tricky because you can, in certain ways, reduce the risks to yourself and your project!
We believe there is no one who doubts that the basis of any secure integration is a special approach to writing code. Consequently, this article will be focused only on those aspects that can be really useful for making your code safe and secure!
This is what we’ll cover in this post about using Convex into your project!
More about Convex: open.substack.com/pub/curve/p/april-23–2021-a-lens-on-convex
Making sense of Defi concepts — Curve’s tokenomics on Convex Finance: rainbowonfi.com/2022/01/making-sense-of-defi-concepts-curves.html
More about Convex (2): coinkickoff.com/convex-finance-cvx
A guide to Convex: medium.com/stakingbits/guide-to-convex-finance-91253329e51b
You may have heard this term somewhere before, but without a detailed study of the subject it will be difficult to understand how Convex works!
So, let’s get to the bottom of it!
The Curve Wars can be described as the competition between several DeFi protocols to get a share of the liquidity in the Curve Finance ecosystem; the hustle to accumulate veCRV, Curve‘s governance token, and decide which pool gets Curve’s reward boost.
Although Convex Finance, Yearn protocol, and StakeDAO are protagonists in the Curve wars incentivizing users to deposit their CRV tokens into their platform, the Curve Wars play out essentially on Convex protocol, which offers one of the highest ROI on CRV.
The Great Curve War (aka. Convex War): medium.com/despread-global/the-great-curve-war-aka-convex-war-bf702d159fb3
Advanced CRV warfare: analysis of protocols built on top of Curve and Convex: tokenbrice.xyz/crv-wars-l2
Let’s get started! We hope you find today’s article informative and helpful!
Following the tips below can significantly improve the security of your project’s integration:
If you get poolId, you can also get the corresponding BaseRewardPool through Booster.poolInfo(poolId).crvRewards
Booster.deposit, assuming that _stake = false, does not stake LP tokens, but just minting deposit tokens for the caller. Therefore, it should be possible to transmit stake=true in the integrating contract, or make BaseRewardPool.stakeFor() separately.
BaseRewardPool.stake stakes deposit tokens only, not real LP tokens. That’s why it’s better to stake through the Booster contract!
LP tokens — through the Booster contract: Booster.deposit(pool_id, amount, true)
CVX and cvxCRV — same as with LP tokens!
CVX will be staked in the cvxRewardPool, but cvxCRV will be staked in the regular BaseRewardPool!
If you stake through a booster contract, CVX and cvxCRV will go into the cvxRewardPool and BaseRewardPool, respectively.
For LP tokens, CVX, or cvxCRV staking: BaseRewardPool.getReward(user, claimExtras=true); claimExtras determines whether extraRewards take tokens.
claimExtras determines whether the user wants to withdraw his extraRewards tokens.
Separate pools or the Booster contract itself can be in shutdown status — in it, you wouldn’t be able to make a deposit. Before initiating a deposit, you should check their status: !Booster.poolInfo(i).shutdown && !Booster.isShutdown
Booster contract can migrate, so don’t hardcode its address — it’s better to add an option to update it.
If you want to stake LP tokens: Call BaseRewardPool.earned().
For additional rewards from LP staking: get the VirtualBalanceRewardPool address via BaseRewardPool.extraRewards(i). Call VirtualBalanceRewardPool.earned().
In the case of the cvxCRV staking, it is exactly the same as you should do with the LP tokens: Call BaseRewardPool.earned().
In case of CVX staking — get cvxRewardPool via Booster.stakerRewards(). Get cvxRewardPool.earned()
claim determines whether to collect awards via getReward()
If you call .withdraw() instead of .withdrawAndUnwrap(), the local Convex deposit tokens are returned, not the LP tokens.
If you want to support my work, you can send me a donation to the address: