Skip to content

Latest commit

 

History

History
83 lines (45 loc) · 2.29 KB

040.md

File metadata and controls

83 lines (45 loc) · 2.29 KB

Tall Burgundy Nightingale

High

Missing Time-Based Validations in _verifyStablecoinSwap Function

Summary

The absence of expiration time validation in _verifyStablecoinSwap() will cause potential sandwich attacks and stale trades for users as malicious actors can delay transaction execution and execute trades under unfavorable conditions.

Root Cause

The choice to omit deadline checks in the StablecoinHandler._verifyStablecoinSwap() function is a mistake as it allows transactions to be executed at any time after submission, enabling MEV attacks and stale trades:

https://github.com/sherlock-audit/2024-11-telcoin/blob/main/telcoin-audit/contracts/stablecoin/StablecoinHandler.sol#L194-L224

Internal pre-conditions

User needs to submit a stablecoin swap transaction

Transaction must be pending in mempool

No deadline for transaction execution is enforced

Swap amounts must be within valid limits

External pre-conditions

Price difference between submission time and execution time must be significant enough to profit

Network congestion or high gas prices to enable delayed execution

Sufficient liquidity in pools to execute sandwich attacks

Attack Path

User submits swap transaction with parameters based on current market conditions

Attacker monitors mempool and sees profitable swap transaction

Attacker sandwiches the transaction:

Front-runs with a large buy order

Allows victim transaction to execute at worse price

Back-runs with a sell order to profit

Impact

The users suffer losses due to:

Price slippage with no upper bound

Sandwich attacks extracting value

Stale trades executing at outdated prices

Estimated losses can range from 1-10% of trade value depending on market volatility and attack sophistication. Attackers gain the price differential minus gas costs.

PoC

No response

Mitigation

Add deadline parameter to StablecoinSwap struct and validate in _verifyStablecoinSwap:

struct StablecoinSwap {
    // existing fields
    uint256 deadline;  // timestamp after which trade reverts
}

function _verifyStablecoinSwap(address wallet, StablecoinSwap memory ss) internal view nonZero(ss) {
    if (wallet == address(0)) revert ZeroValueInput("WALLET");
    if (block.timestamp > ss.deadline) revert ExpiredSwap();
    
    // Rest of validation
}