The _swapExact function in BelongCheckIn.sol calculates the minimum output amount (amountOutMinimum) on-chain during the same transaction, making it vulnerable to sandwich attacks via MEV bots. Attackers can manipulate the pool price before the victim's transaction, causing the victim to receive unfavorable swap rates while the slippage protection becomes ineffective.
Vulnerability Details
Root Cause
The vulnerability exists in the _swapExact function at BelongCheckIn.sol:652-694:
function_swapExact(addresstokenIn,addresstokenOut,addressrecipient,uint256amount)internalreturns(uint256swapped){// ...// VULNERABLE: amountOutMinimum calculated on-chain in same transactionuint256 amountOutMinimum =IV3Quoter(_paymentsInfo.swapV3Quoter).quoteExactInput(path, amount).amountOutMin(_paymentsInfo.slippageBps); IV3Router.ExactInputParamsV1 memory swapParamsV1 = IV3Router.ExactInputParamsV1({ path: path, recipient: recipient, deadline:block.timestamp,// Also vulnerable: no real deadline protection amountIn: amount, amountOutMinimum: amountOutMinimum});// ...}
1
Attack Flow — Step 1: Detection
MEV bot detects a pending venueDeposit transaction in the mempool.
2
Attack Flow — Step 2: Front-run
Bot submits a transaction with higher gas to:
Buy LONG tokens, increasing the price
This manipulates the pool reserves before the victim's transaction
3
Attack Flow — Step 3: Victim Transaction Executes
quoteExactInput() returns the manipulated (inflated) price
amountOutMin() calculates slippage from this already-manipulated price
Swap executes at the bad rate (but within the newly calculated slippage)
4
Attack Flow — Step 4: Back-run
Bot sells LONG tokens back, capturing the price difference as profit.
Why Slippage Protection Fails
The slippage protection is calculated AFTER the price manipulation:
Normal scenario (no attack):
Pool price: 1 USDC = 1 LONG
Quote: 1000 USDC -> 1000 LONG
With 5% slippage: minOut = 950 LONG
Under sandwich attack:
Bot manipulates price: 1 USDC = 0.95 LONG
Quote NOW: 1000 USDC -> 950 LONG (using manipulated price)
With 5% slippage: minOut = 902.5 LONG
Victim gets 950 LONG (seems "protected" but actually lost 5%)
Impact Details
Financial Loss
Users lose 5-20% of their deposit value to MEV bots
Affects all venueDeposit transactions involving swaps
Higher deposits face proportionally larger absolute losses
Affected Functions
venueDeposit() - when convenience fees are swapped to LONG
_handleRevenue() - when platform revenue is swapped
Any future functions using _swapExact()
Severity Justification: HIGH
Users lose funds on every swap
Attack is automatic via MEV bots
Can be exploited on every transaction
Flash loans can amplify the attack
Recommendations
Primary Fix: Off-chain Slippage Calculation
Calculate amountOutMinimum off-chain and pass it as a parameter:
Secondary Fix: Add Meaningful Deadline
Replace block.timestamp with a user-provided deadline:
Additional Mitigations
TWAP Oracle: Use time-weighted average price for reference
Private Mempool: Submit transactions through private pools (e.g., Flashbots)
Commit-Reveal: Two-phase deposits to hide transaction details
Maximum Slippage Check: Revert if price deviates too much from oracle
Proof of Concept
Running the POC
1
Save the test file to test/foundry/H2_SandwichAttack_POC.t.sol