DeFiFoundry
50,000 USDC
View results
Submission Details
Severity: low
Invalid

No Slippage Protection in Paraswap DEX Interactions

Summary

The PerpetualVault contract performs token swaps using Paraswap DEX without implementing any slippage protection. The contract blindly executes swaps and never validates the output amounts, leaving users vulnerable to sandwich attacks, price manipulation, and significant value loss due to unfavorable trade execution.

Vulnerability Details

The _doDexSwap function fails to implement any form of minimum output validation:

function _doDexSwap(bytes memory data, bool isCollateralToIndex) internal returns (uint256 outputAmount) {
(address to, uint256 amount, bytes memory callData) = abi.decode(data, (address, uint256, bytes));
IERC20 inputToken;
IERC20 outputToken;
if (isCollateralToIndex) {
inputToken = collateralToken;
outputToken = IERC20(indexToken);
} else {
inputToken = IERC20(indexToken);
outputToken = collateralToken;
}
uint256 balBefore = outputToken.balanceOf(address(this));
ParaSwapUtils.swap(to, callData);
// No slippage checks here!
outputAmount = IERC20(outputToken).balanceOf(address(this)) - balBefore;
emit DexSwap(address(inputToken), amount, address(outputToken), outputAmount, isCollateralToIndex);
  1. No minimum output validation

  2. No comparison against expected rates

  3. Accepts any output amount, even if extremely unfavorable

  4. No reversion mechanism for bad trades

  5. No validation that output amount is greater than zero

The issue is particularly concerning because:

  • The contract handles valuable tokens (USDC, WETH, WBTC, LINK, USDT)

  • These tokens trade in highly liquid markets where MEV bots are active

  • Paraswap is an aggregator routing through multiple DEXes, increasing attack surface

  • Users have no opt-out or control over slippage parameters

Impact

The lack of slippage protection in DEX swaps creates serious risks:

  1. Direct Loss of Funds: Users receive significantly fewer tokens than would be fair market value

  2. MEV Exploitation: Sandwich attacks can extract value from every swap

  3. Liquidation Risk: Unfavorable swaps may lead to insufficient collateral for positions

  4. Trust Erosion: Users experiencing losses from bad trades will lose trust in the protocol

This vulnerability could be exploited on every DEX swap transaction, making it especially dangerous as it affects core functionality used throughout the protocol.

Proof of Concept

The attack flow:

  1. Vault prepares to swap 100,000 USDC for ETH

  2. Attacker front-runs by buying ETH, pushing price up 3%

  3. Vault executes swap at inflated price, receiving 3% less ETH

  4. Attacker back-runs by selling ETH, returning price to normal

  5. Attacker profits ~3%, vault users lose ~3%

  6. No minimum output check means transaction succeeds despite the loss

This pattern can be repeated for every DEX swap the vault performs.

Tools Used

Manual review

Recommendations

1.Add minimum output validation which is dynamically adjusted to prices passed by an oracle to all DEX swaps:

function _doDexSwap(bytes memory data, bool isCollateralToIndex) internal returns (uint256 outputAmount) {
(address to, uint256 amount, bytes memory callData, uint256 minOutputAmount) =
abi.decode(data, (address, uint256, bytes, uint256));
uint256 balBefore = outputToken.balanceOf(address(this));
ParaSwapUtils.swap(to, callData);
outputAmount = IERC20(outputToken).balanceOf(address(this)) - balBefore;
=> require(outputAmount >= minOutputAmount, "Slippage too high");

2.Add configuration options for slippage tolerance:

  • Add a default maximum slippage parameter (e.g., 100 basis points / 1%)

  • Allow the keeper to customize slippage tolerance for different market conditions

Updates

Lead Judging Commences

n0kto Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

invalid_swap_slippage_and_deadline

Slippage and deadline are handled externally. Paraswap implementation used by the current code (behind the proxy): https://etherscan.io/address/0xdffd706ee98953d3d25a3b8440e34e3a2c9beb2c GMX code: https://github.com/gmx-io/gmx-synthetics/blob/caf3dd8b51ad9ad27b0a399f668e3016fd2c14df/contracts/order/OrderUtils.sol#L150C15-L150C33

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!