๐Real World Examples
Understanding Examples: In this section, we delve deep into concrete examples based on genuine exploits discovered in the wild and findings from CodeArena bug bounties. These incidents, rooted in the context of slippage, provide a hands-on perspective of the challenges faced in DeFi smart contract development and the essential lessons they bring forth.
By examining real-world cases, we aim to bridge the gap between theoretical knowledge and practical application. These examples offer insights into how attackers exploit slippage-related vulnerabilities, how certain design decisions can inadvertently introduce risks, and how vigilant developers can preemptively recognize and address these concerns.
Example 1: Missing Slippage Checks
High Code4rena bug bounty payout
Vulnerability details:
The Router
(and Pool
) does not implement any slippage checks with comparing the swap / liquidity results with a minimum swap / liquidity value.
Impact: Users can be frontrun and receive a worse price than expected when they initially submitted the transaction. There's no protection at all, no minimum return amount or deadline for the trade transaction to be valid which means the trade can be delayed by miners or users congesting the network, as well as being sandwich attacked - ultimately leading to loss of user funds.
Mitigation:
Add some sort of protection for the user such that they receive their desired amounts. Add a minimum return amount for all swap and liquidity provisions/removals to all Router
functions.
Example 2: Hard-coded slippage values
Medium code4rena bug bounty payout
Issue: In the process of adding liquidity through UniswapHandler.addLiquidity
, the smart contract uses its entire balances for both tokens and sets a hardcoded minimum acceptable amount (95% of these balances) for the operation. If the contract's balances do not match the current liquidity pool's reserve ratios, the function will fail.
Here's the problematic code:
Consequences: This design flaw opens the door for potential attacks:
If for some reason the contract's token balances are "unbalanced" with respect to the current reserve ratios in the liquidity pool, users will be unable to add liquidity.
Attackers can exploit this by sending additional tokens to the contract, intentionally disrupting the balance. This causes the liquidity addition function to revert, effectively blocking users from participating - a type of "griefing" attack.
Mitigation:
Ensure that tokens within the contract always maintain a balance in line with the liquidity pool's reserve ratios.
A more robust solution is to decouple the liquidity adding process from the contract's own balance. Instead, allow users to specify the amount of tokens they wish to provide for liquidity, thereby removing the potential for external manipulation of the contract's balance.
Example 3: 0 Slippage tolerance
Medium Code4rena bug bounty payout
In the createPair()
function from the LaunchEvent
contract, there's a call to router.addLiquidity()
where the desired amounts for tokens A and B are set to be equal to their minimum acceptable amounts. This means there's no tolerance for slippage: any variation from the specified amounts will cause the function to fail.
example of a problematic snippet:
Consequences:
Due to this zero slippage tolerance, if market conditions or token ratios don't precisely match the desired amounts when the transaction is mined, it will revert.
Users can be hindered from using the
createPair()
function if they are front-run or if there's an existing liquidity pool that doesn't support zero-slippage transactions with the specified assets.
Mitigation:
It's crucial to consider potential deviations from expected behaviors, especially if the assumptions are based on an external entity or an untrusted contract.
To address the zero slippage issue, it would be wise to introduce a slippage allowance parameter to the
createPair()
function, granting a bit of flexibility to the operation. This would make the function more adaptable to real-world conditions and reduce the chance of unintended reverts.
Last updated