In this blog, we have outlined the concept of liquidity staking protocols and audit guidelines for staking protocols. This guideline covers various weak points such as withdrawal mechanisms, rounding errors, external calls, fee logic, loops, structures, staking periods, etc. This blog post serves as a reference for auditing staking protocols and helps identify potential bugs. .
What is liquidity staking?
Liquidity staking allows users to stake their cryptocurrency holdings and earn rewards without sacrificing liquidity. Instead of locking coins for a period of time, users can receive liquid tokens representing staked assets. This token can be traded or used like any other cryptocurrency, allowing users to spend their assets however they want while earning staking rewards.
For example, you want to bet 100 ETH on the Ethereum network. Instead of locking ETH for a period of time, using a liquidity staking service like Lido he can stake ETH and in return receive a liquid token called stETH. stETH allows you to trade or spend staked ETH while earning staking rewards.
Start auditing your staking contract:
Check all available audit specifications before starting contract code. It could be a white paper, a README file, or some other format. This will give you an idea of what the contract code contains.
When looking at a staking contract audit specification, look for the following:
- Types of fees and their calculation.
- Reward mechanism for staked tokens
- owner rights
- Will the contract hold ETH?
- What kind of tokens does the contract hold?
- Original contract to branch from
Make sure your specs match your code. Validate ownership rights, starting with fees and tokenomics. Make sure all reward and commission values are in accordance with the documentation.
How to find vulnerable places?
1. Rewards withdrawal mechanism:
Make sure that the staked token reward mechanism is implemented correctly and that rewards are distributed fairly and proportionally to all stakers. Projects can distribute rewards in two ways. Automatic, periodic, or at the user’s own request. The retraction functionality can be implemented and customized according to the protocol’s business logic.
Here are some checkpoints:
- Check if there are any users who can withdraw more than reward + wager.
- Check for overflow/underflow in amount calculation
- See if certain parameters can negatively affect rewards during calculation.
- If block.timestamp or block.number are used in this function. See if it can be exploited in some way.
2. Pricing logic:
If there are fees for deposits and withdrawals, make sure that none of the users can avoid the fees. Additionally, be aware of potential overflow or underflow issues. Only administrators or owners should be allowed to change pricing. Also, ensure that maximum charge thresholds are established to prevent administrators from setting excessively high amounts.
3. LP token issuance/burning mechanism:
Check if the create and write mechanisms are implemented correctly. The write function should undo any state changes made by the mint function. Additionally, it is important to ensure that users receive the right amount of tokens during their first stake when the pool is empty.
The logic of mint and burn functions can be mathematically verified to reveal hidden vulnerabilities. Also, the total supply of LP tokens issued must not exceed the staked assets.
4. Rounding error:
Certain small rounding mistakes are usually unavoidable and not a problem, but they can increase significantly when multiplication becomes possible. Look for edge cases where you can profit from rounding errors by repeatedly staking and unstaking.
To determine whether rounding error can reach a significant amount over time, mathematically calculate the bounds of rounding error.
5. Staking period:
Ensure that the contract’s staking period calculation is consistent with the specified business logic. Bypass period checks to ensure users cannot redeem rewards before the end of the staking period. Also, see if attackers can exploit the staking period to get more rewards.
6. External calls and token handling:
Most of the external calls are to token contracts. Therefore, you need to decide what kind of tokens your staking contract will handle. It is essential to check external calls for errors and reentrancy attacks. Deflationary tokens such as Safemoon or tokens with transfer fees can cause problems if the logic is not implemented correctly.
7. Price manipulation check:
Flash loan price manipulation is one of the most frequent hacks in DeFi projects. Situations can arise where malicious actors can use flash loans to manipulate prices while staking or unstaking large numbers of tokens. Carefully review staking and unstaking capabilities to avoid flash loan-based price-fixing attacks and edge case scenarios that can lead to loss of other users’ funds.
8. Some additional checks:
- loop: If your contract logic involves looping over arrays, it is important not to exceed the block gas limit. This can happen when the size of the array is very large, so I’d like to know what functions can increase the size of the array and how the user can abuse it to cause his DoS attack. It is necessary to investigate whether there ischeck this out report.
- Structure: Staking contracts use struct types to store user or pool data. When declaring or accessing a struct within a function, it is important to specify whether you are using “memory” or “storage”. It may help you save gas. For more information, see to this article.
- previous run: Look for scenarios where malicious actors could front-run transactions to their advantage.
- Feature visibility/access control checks: Functions declared as external or public are accessible to everyone. Therefore, it’s important to prevent public functions from performing sensitive actions. It is important to ensure that staking protocols implement appropriate controls to prevent unauthorized access to both staked coins and the infrastructure of the system.
- Centralization risk: It is important not to give the owner too much power. If the administrator address is compromised, it can seriously damage the protocol. Make sure that the owner or admin privileges are adequate, and that the protocol has a plan in place to deal with the compromise of the admin’s private key.
- Handling of ETH/WETH: Contracts often contain specific logic for handling ETH. For example, if msg.value > 0, the contract can receive WETH directly while converting her ETH to WETH. If a user specifies her WETH as a currency and sends her ETH in a call, it breaks certain invariants and can lead to erroneous behavior.
So far, we have discussed liquidity staking protocols and audit guidelines for such protocols. In a nutshell, liquidity staking allows users to earn staking rewards without sacrificing liquidity. We have outlined weaknesses in staking contracts that auditors must pay attention to. This includes withdrawal mechanisms, fee logic, LP token creation/burning mechanisms, rounding errors, staking periods, external calls, price manipulation checks, and more.
Auditors are encouraged to consult audit specifications, match specifications and codes, and verify fees and tokenomics verification. It also recommends additional checks such as looping over arrays, specifying memory or storage for struct type data, and front-running scenarios. These guidelines will help you audit your staking protocol and help identify potential bugs.