Stratax Contracts

First Flight #57
Beginner FriendlyDeFi
100 EXP
Submission Details
Impact: high
Likelihood: medium

Balance Fallback in `_call1InchSwap()` Accepts Zero-Output Swaps

Author Revealed upon completion

Description

When the 1inch router returns empty bytes, the function falls back to reading the contract's entire current token balance as the returnAmount. This is semantically wrong and can mask a completely failed or zero-output swap.

Root Cause

if (result.length > 0) {
(returnAmount,) = abi.decode(result, (uint256, uint256));
} else {
// If no return data, check balance
returnAmount = IERC20(_asset).balanceOf(address(this));
}

In the OPEN flow, the user's collateralAmount is transferred into the contract BEFORE the flash loan executes. So even if the swap produces zero output, balanceOf(address(this)) may still return a non-zero amount from that pre-existing deposit, causing require(returnAmount >= _minReturnAmount) to pass falsely.

Impact

A zero-output swap passes silently. The flash loan repayment logic then attempts to pull from whatever balance exists, potentially consuming the user's original collateral to repay the flash loan — effectively stealing the user's deposit. Even when it causes a revert, it does so only after state has been partially dirtied.

Attack Scenario

  1. User deposits 10 WETH as collateral — contract holds 10 WETH

  2. Flash loan of 20 WETH arrives — all 30 WETH supplied to Aave

  3. Borrow 60,000 USDC, approve 1inch

  4. Swap executes but router returns success=true with empty bytes (valid for some router paths)

  5. Fallback: returnAmount = IERC20(WETH).balanceOf(address(this)) — if any WETH residual exists, check passes

  6. Flash loan repayment proceeds against wrong accounting

Poc


Mitigation

require(success && result.length >= 64, "1inch swap failed or no return data");
(returnAmount,) = abi.decode(result, (uint256, uint256));
require(returnAmount >= _minReturnAmount, "Insufficient return amount");

Support

FAQs

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

Give us feedback!