Stratax Contracts

First Flight #57
Beginner FriendlyDeFi
100 EXP
View results
Submission Details
Severity: medium
Valid

_executeOpenOperation passes incorrect asset to swap fallback, causing DoS on valid swaps

Root + Impact

Description

  • When opening a position, the protocol swaps the borrowed token (e.g., USDC) for the collateral token (e.g., WETH). If the 1inch router returns no data, the contract should verify the balance of the received collateral token.

  • The _executeOpenOperation function incorrectly passes the borrowToken address (the token being sold) as the _asset parameter to _call1InchSwap. If the fallback logic triggers, it checks the balance of the sold token instead of the bought token.

// src/Stratax.sol
function _executeOpenOperation(...) internal {
// ...
// Swapping Borrow Token -> Collateral Token
uint256 amountReceived = _call1InchSwap(
flashParams.oneInchSwapData,
@> flashParams.borrowToken, // <--- INCORRECT: This is the input token
flashParams.minReturnAmount
);
// ...
}
// src/Stratax.sol
function _call1InchSwap(bytes memory _swapParams, address _asset, uint256 _minReturnAmount) ... {
(bool success, bytes memory result) = address(oneInchRouter).call(_swapParams);
if (result.length > 0) {
(returnAmount,) = abi.decode(result, (uint256, uint256));
} else {
// If result is empty, it checks balance of _asset (which is wrongly set to borrowToken)
@> returnAmount = IERC20(_asset).balanceOf(address(this));
}
// ...
}

Risk

Likelihood:

  • A user selects a swap route where the specific 1inch aggregator adapter returns empty bytes (common in some legacy adapters or specific execution paths).

Impact:

  • Valid open operations revert with "Slippage too high" because the balance of the sold token is 0 (or less than minReturn).

  • Users are effectively blocked from using specific swap routes, creating a functional Denial of Service.

Proof of Concept

Add this test to test/StrataxPoC.t.sol:

function test_1inchFallbackUsesWrongToken() public {
// 1. Simulate a swap where we Sell TokenA (Borrow) to Buy TokenB (Collateral)
// 2. Simulate 1inch router returning empty bytes (result.length == 0)
// 3. The contract has received TokenB, but has 0 TokenA left.
uint256 minReturn = 10 ether;
// Emulate the bug logic in _executeOpenOperation
// passing borrowToken (TokenA) instead of collateralToken (TokenB)
uint256 balanceCheck = MockERC20(tokenA).balanceOf(address(this));
// This reverts even though the swap was successful (we have TokenB)
if (balanceCheck < minReturn) {
revert("Slippage too high");
}
}

Recommended Mitigation

In src/Stratax.sol, function _executeOpenOperation:

uint256 amountReceived = _call1InchSwap(
flashParams.oneInchSwapData,
- flashParams.borrowToken,
+ flashParams.collateralToken,
flashParams.minReturnAmount
);
Updates

Lead Judging Commences

izuman Lead Judge 16 days ago
Submission Judgement Published
Validated
Assigned finding tags:

_executeOpenOperation passes wrong token address to _call1inchSwap to verify slippage

Wrong address is passed to _call1inchSwap and will cause incorrect reverts even after a successful swap.

Support

FAQs

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

Give us feedback!