Stratax Contracts

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

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

Author Revealed upon completion

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
);

Support

FAQs

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

Give us feedback!