Stratax Contracts

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

Denial of Service in `createLeveragedPosition` due to Strict Balance Equality

Author Revealed upon completion

Root + Impact

Description

  • The _executeOpenOperation function enforces a strict equality check to ensure all borrowed tokens are used in the 1inch swap.

  • However, DEX swaps frequently leave small amounts of "dust" (e.g., 1-2 wei) due to decimal rounding, causing this strict check to revert valid transactions.

// src/Stratax.sol:518
// @> Root cause: Strict equality reverts if even 1 wei of dust remains
require(afterSwapBorrowTokenbalance == prevBorrowTokenBalance, "Borrow token left in contract");

Risk

Likelihood:

  • High: Many 1inch aggregation routes involving Curve, Uniswap, or complex paths result in varying precision that leaves dust.

  • The check requires 100.000000% efficiency, which is practically impossible for all pairs 100% of the time.

Impact:

  • DoS: Users will be unable to open leveraged positions for many assets/routes that leave dust.

  • Protocol Unreliability: The protocol becomes unusable for specific tokens that have rounding issues in their pools.

Proof of Concept

This PoC concept shows how a tiny dust remainder causes a revert.

function test_OpenPosition_RevertsOnDust() public {
// ... setup ...
uint256 borrowAmount = 1000e6;
// Mock 1inch Router behavior:
// Takes 1000e6 USDC
// BUT only uses 999.999999 USDC (leaving 1 wei dust) due to rounding
// Returns WETH
vm.mockCall(ROUTER, swapData, abi.encode(1 ether));
// Mock token behavior simulating dust left behind:
// Mock balance of Stratax is now 1 (dust) instead of 0
// Expect Revert
vm.expectRevert("Borrow token left in contract");
stratax.createLeveragedPosition(...);
}

Recommended Mitigation

Relax the strict equality to allow a negligible amount of dust, or transfer the remaining dust to the contract owner/treasury instead of reverting.

- require(afterSwapBorrowTokenbalance == prevBorrowTokenBalance, "Borrow token left in contract");
+ // Allow for small dust (e.g. < 100 wei or based on token precision)
+ require(afterSwapBorrowTokenbalance <= prevBorrowTokenBalance + DUST_THRESHOLD, "Too much borrow token left");
+ // OR simply ignore the check if the main swap return amount is satisfied

Support

FAQs

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

Give us feedback!