dApp Security Guidelines: DEX
Informational
Informational
Threat 1: LP Token Value Calculation and Issuance Errors
When adding liquidity to a pool, the value of the issued LP tokens may not match the actual value of the pool assets, leading to new liquidity providers receiving excessive gains or losses.
Impact
Low
It is rated Low because if new liquidity providers receive LP tokens that do not match the actual value of the pool assets due to calculation and issuance errors, some users may experience limited losses or gains.
Guideline
Accurate Value Calculation:
Reflect the current market price of each token in real-time from reliable oracles like Chainlink and Uniswap TWAP, using only data updated within a minimum of 1 minute to a maximum of 3 minutes. If the price deviation between referenced oracles exceeds a certain percentage (e.g., within 0.5% ~ 2% for Chainlink), perform additional verification.
Apply liquidity weights when calculating the weighted average price by multiplying the liquidity ratio for each token.
Pool Value=(tokenAamount×priceA)+(tokenBamount×priceB)
Calculate the exact proportion of the new liquidity relative to the entire pool.
Ensuring Numerical Precision:
Mandatory use of fixed-point math libraries like SafeMath and FixedPointMathLib, with a precision of at least 18 decimal places.
Convert intermediate calculation values to fixed-point units and verify that the precision of the intermediate calculation results42 does not fall below 1e18.
Optimize the order of addition/multiplication by performing operations on larger numbers first and applying division at the end. Use numerical precision-guaranteeing formula calculation modules like SafeMath and FixedPointMathLib.
Real-time Verification:
Compare the calculated LP token value with the actual pool asset value by checking if the following formula holds true:
LP Total Supply×Current LP Token Value≈LP Pool TVL
Immediately after the liquidity addition transaction is executed, verify that the calculated expected issuance amount matches the actually issued LP token amount.
Best Practice
Threat 2: Liquidity Removal Timing Attack and Minimum Liquidity Bypass
An attacker can exploit moments of sharp price increases or decreases to remove liquidity, causing the remaining liquidity in the pool to fall below a standard threshold or bypassing the minimum holding period to quickly realize profits.
Impact
Low
Although an attacker can remove liquidity during sharp price fluctuations, causing the pool's remaining liquidity to fall below the threshold or bypassing the minimum holding period to realize profits, the impact on the entire pool is limited, so it is rated Low.
Guideline
Minimum Liquidity Verification:
Verify the minimum liquidity threshold per pool in the smart contract before removing liquidity, as shown below. (The α value is a coefficient used to impose a high penalty for actions that cause pool imbalance, set to 10^6 based on Curve Finance).
MinLiquidity=max(BaseAmount, AvgVolumeN Days×α)(Pool Valueafter removal≥MinLiquidity)
Since the pool becomes vulnerable to price manipulation/MEV attacks if the sum of each token's balance multiplied by its market price falls below a certain level, perform real-time verification at the time of liquidity removal based on the oracle price to ensure the total token value is above the threshold.
Pool Value=∑i=1n(TokeniBalance×TokeniPrice)(Pool Vauleafter removal≥MinLiquidity)
Timing Attack Prevention:
As in cases like Uniswap V3, fix the oracle/TWAP price at the time of the liquidity removal request and settle based on the initial request price until the actual removal is processed.
Remove Value=Liquidity Amount×Pricerequest
When removing liquidity, use the average price of the last N blocks (TWAP) as the settlement standard to prevent temporary price manipulation45.
TWAP=N1Σj=1NPriceblock j (N=Block Number)
Like Curve and Balancer, add a condition at the protocol level that requires a minimum holding period43 to pass after receiving LP tokens for providing liquidity before liquidity can be removed.
(Example: Current Time−LP Mint Time≥Min Hold Period)
Best Practice
The invariant ratio limit can vary depending on the protocol's risk model. The code below specifies the maximum/minimum invariant limits according to Balancer's weighted invariant formula.
Threat 3: Liquidity Pool Imbalance
Repeated large deposits and withdrawals of a specific token can severely disrupt the token ratio in the pool, leading to price distortion or the depletion of liquidity for some tokens. An attacker can use a flash loan to borrow a large amount of funds in a single block, drastically manipulate the pool price, take a profit, and then immediately repay, inducing regular users to trade at distorted prices.
Impact
Informational
If the asset ratio in a pool is severely disrupted due to repeated large deposits and withdrawals of a specific token, it can lead to price distortion or liquidity depletion for some tokens. However, since this does not lead to a system-wide security issue or direct loss, it is rated as Informational.
Guideline
Flash Loan Attack Prevention
Enforce a hard cap at the protocol level on the maximum price fluctuation a single trade can cause in a liquidity pool.
When a flash loan function call or a large-scale borrow-swap-repay pattern is detected within a transaction, induce a reduction in the attacker's potential profit by imposing an additional 1% fee on top of the basic swap fee, similar to Uniswap and Balancer.
Apply a
lockmodifier to prevent re-entrancy attacks through the flash loan execution function within the same transaction.Oracle Price Verification
Utilize at least two independent oracle price sources. If the price deviation between oracles exceeds 1.5%, reject the transaction or conduct further verification.
This threshold is operated by oracle networks like Chainlink and Band Protocol.
DeFi protocols like Compound and Synthetix41 specify an oracle discrepancy tolerance of within 1%. To prevent liquidity provider losses due to accumulated discrepancies, they temporarily pause trading if not updated for more than 3 minutes.ΔP≈σ×t (Example: σ=0.5%,t=3min⟹ΔP≈0.5%×3≈0.866%)
Minimize the impact of price manipulation from a single trade by using an average price like TWAP (Time-Weighted Average Price).
Automatic Rebalancing Mechanism
Like AMM services such as Uniswap and Curve, set a deviation threshold49 against the target ratio for maintaining the asset value ratio in the liquidity pool. Trigger rebalancing when the threshold is exceeded.
Example: RatioA=ValueA+ValueBValueA,Threshold≈ValueA+ValueBCgas+Cswap(∣RatioA−Target RatioA∣>Threshold⇒Rebalance Trigger)Cgas: Network gas cost required to execute the rebalancing transactionCswap: Swap fee paid to the liquidity poolValueA+ValueB: Total market value of assets A and B deposited in the pool
When a deviation occurs, provide a trigger in the smart contract for automatic rebalancing to restore price balance, similar to Uniswap's x*y=k47 curve.
Imbalance Monitoring
Similar to existing DEX services, it is necessary to provide a function to track and calculate key indicators such as the asset ratio and TVL in the pool on a real-time dashboard.
If the operated liquidity pool ratio deviates significantly from the target, build a warning system with deviation-level alerts for administrators to respond immediately.
Automatic Swap Processing
Like Curve and Balancer, when providing liquidity with a single token, automatically swap to match the pool's ratio before supplying liquidity to prevent pool imbalance, price distortion, and liquidity depletion. The formula based on Balancer v1 is as follows:
V=Πi=1nBiWiExample: V=(BAWA)×(BAWA)×(BCWC)(n=3)(BA,B,C:TokenA,B,C Balances)(WA,B,C:TokenA,B,C Weights)
Minimum Liquidity Requirements
Based on Balancer, require a minimum liquidity of the greater of 10% of the pool's recent N-day average trading volume or $10,000. This may vary depending on the protocol's governance.
MinLiquidity=max(BaseAmount, AvgVolumeNDays×α)(Example: MinLiquidity=max(10,000, 150,000×0.1)=15,000)
In AMMs like Uniswap and KyberSwap, to prevent market price distortion due to slippage, restrict a single trade from exceeding a set percentage of the pool's balance. (The trade size limit may vary depending on the AMM protocol's risk model; a 30% limit is applied in the example code).Price Impact=1−x+Δxx (x=Pool Balance,Δx=Asset Increment)(Example: 1−1+0.42861≈0.3≈30%)
Best Practice
Threat 4: Token Swap Slippage Maximization and Minimum Output Calculation Errors
Due to large trades, the actual execution price may fluctuate unfavorably, resulting in receiving far fewer tokens than expected. Alternatively, an error in the minimum output calculation may cause a loss by delivering fewer tokens than the minimum amount specified by the user.
Impact
Informational
Although a sharp increase in slippage due to large trades or an error in the minimum output calculation can lead to users receiving fewer tokens than the minimum amount they specified, this primarily results in an unfavorable execution for individual traders and does not directly impact the overall security of the system. Therefore, it is rated as Informational.
Guideline
Slippage Tolerance Setting and Verification:
Like major DEXs such as Uniswap and SushiSwap, guide users to input their own slippage tolerance, pre-defining the maximum slippage threshold before a trade. If the limit is exceeded, the trade is automatically canceled. (In Uniswap, users can directly specify the slippage percentage in the UI during a swap).
Use a formula49 to verify that the minimum amount entered by the user matches the actually calculated minimum output and confirm the actual amount to be paid (the type of formula may vary by protocol).
(Example: Minimum Output=Input Amount×(1−Slippage Tolerance))
Automatically cancel the trade if the slippage limit is exceeded, as is standard in major DEXs.
Splitting Large Trades:
Like DEXs on the 1inch50 network, split large trades across multiple DEXs/liquidity pools to minimize slippage and perform slippage verification for each trade.
To prevent flash loan/MEV attacks and ensure market stability, set a minimum block interval between split trades to restrict their execution in different blocks.
(Based on UniswapV3, the N value is dynamically specified according to time, generally set between 30 minutes to 1 hour).
(Example:Total Slippage=1−∏i=1n(1−Slippagei)) (n=BlockNum)
Real-time Price Monitoring and Verification:
Just before trade execution, re-query the oracle/pool price, and if the price fluctuation exceeds a threshold, perform a recalculation or handle the exception, similar to DEX Screeners and Aggregators.
Receive prices from multiple oracles like Chainlink and Band for multi-source price utilization and cross-verification. If the deviation is large, cancel the trade or switch to an alternative source.
Apply and monitor a real-time slippage prediction formula based on current liquidity, using a formula like the one below.
Price Impact=1−x+Δxx(x=PoolAmount,Δx=TradeSize)
Best Practice
[Source for Balancer Swap Limit]
Threat 5: Fee Management and Modification Vulnerabilities
An administrator could suddenly change the fee rate significantly or withdraw a large amount of fees instantly, causing unexpected losses for liquidity providers.
Impact
Informational
If an administrator suddenly changes the fee rate or withdraws a large amount of fees, it could cause unexpected losses for liquidity providers. However, this is considered an operational issue that does not directly impact the overall security of the system, so it is rated as Informational.
Guideline
Automated Fee Management:
At the protocol level, handle fee collection automatically with a trigger for automatic collection51 when a certain accumulated fee threshold is reached, similar to DEXs like Uniswap and Balancer.
(balance0×1000−amount0In×3)×(balance1×1000−amount1In×3)≥reserve0×reserve1×10002- balance0, balance1: The balance of token0 and token1 remaining in the pool after the swap.- amount0In, amount1In: The amount of input token0 and token1 used in the swap.- reserve0, reserve1: The balance of token0 and token1 before the swap.
Prevent unpredictable large withdrawals by setting a regular collection cycle for fee distribution/withdrawal, as seen in protocols like Curve and SushiSwap.(Example: Current Time−Last Collection Time≥Collection Interval)
Permission and Change Management:
Apply a timelock52 for large withdrawals or sensitive administrator function executions, as shown in the formula below.
Execute Time=Request Time+2 days (UniswapV2 Example)
Best Practice
Threat 6: Mismatches during Pool State Updates
During a pool rebalancing, if only some token states are changed and the transaction fails midway, it can lead to a mismatch in the pool's invariant or total supply.
Impact
Informational
If only some token states are changed during a pool rebalancing and the transaction fails, it can lead to a mismatch in the pool's invariant or total supply. However, this is primarily an operational error and does not directly impact the overall security of the system, so it is rated as Informational.
Guideline
Ensuring Atomic Transactions:
All pool state changes should be handled within a single transaction to update related variables at once. To prevent re-entrancy during state changes, apply a Re-entrancy Guard like Uniswap V2's lock mechanism.
Use keywords like
require/assertto ensure that if an error occurs during an intermediate execution step, the entire transaction is rolled back, preventing any intermediate state from being left behind.Intermediate State Verification:
Immediately after each pool update, verify the invariant using a simple AMM formula like X * Y = K from Uniswap or a weighted invariant verification formula like Balancer's to prevent price errors, arbitrage, and potential losses. (In Berachain's case, a Balancer-style weighted invariant verification formula is used).
V=Πi=1nBiWi
To reduce arbitrage arising from interactions between multiple pools or tokens, check for price consistency between pools and verify the conservation of the total token supply55 using a set formula.
(Example: ∑i=1nToken Supplyi=Total Supply (n=BlockNum))
Pool State Synchronization:
If synchronization is required across multiple pools/chains, set up alerts and automatic responses if the state mismatch exceeds a defined threshold.
Best Practice
Last updated