Stratax Contracts

First Flight #57
Beginner FriendlyDeFi
100 EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

ERC20 return values not checked on `transfer` and `transferFrom`

Root Cause + Impact

Two ERC20 operations use raw transfer/transferFrom without checking return values. Tokens that return false on failure instead of reverting (notably USDT) silently fail, so recoverTokens() loses funds and createLeveragedPosition() proceeds with zero collateral.

Description

The ERC20 standard specifies that transfer and transferFrom return bool. Some widely-used tokens (USDT, BNB, OMG) return false on failure instead of reverting. Two call sites in Stratax do not check the return value:

1. recoverTokens() at L283:

// Stratax.sol:283
// @> IERC20(_token).transfer(owner, _amount);

If the token returns false, the transfer silently fails. The admin thinks tokens were recovered but nothing moved.

2. createLeveragedPosition() at L325:

// Stratax.sol:325
// @> IERC20(_flashLoanToken).transferFrom(msg.sender, address(this), _collateralAmount);

If the token returns false, no collateral is transferred. The function proceeds to initiate the flash loan with zero real collateral. The transaction will likely revert downstream in the Aave callback when the position is under-collateralized, but the error message is misleading.

Risk

Likelihood: Medium

USDT is the 3rd largest stablecoin by market cap and a common Aave collateral asset. The protocol does not restrict which ERC20 tokens can be used. If someone uses USDT as the flash loan token, both vulnerable paths are reachable.

Impact: Medium

In recoverTokens(), admin loses the ability to recover tokens of non-reverting types. In createLeveragedPosition(), the misleading downstream revert wastes gas and confuses users. No funds are permanently lost in the open path (the whole transaction reverts atomically), but the recovery path genuinely fails to move tokens.

Proof of Concept

N/A. The issue is visible by inspection: IERC20.transfer() returns bool per the ERC20 spec, and neither call site checks the return value. The behavior of USDT returning false instead of reverting is well-documented.

Recommended Mitigation

Use OpenZeppelin's SafeERC20 library, which reverts on false returns and also handles tokens that don't return a value (like USDT):

+ import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
+ using SafeERC20 for IERC20;
// recoverTokens (L283)
- IERC20(_token).transfer(owner, _amount);
+ IERC20(_token).safeTransfer(owner, _amount);
// createLeveragedPosition (L325)
- IERC20(_flashLoanToken).transferFrom(msg.sender, address(this), _collateralAmount);
+ IERC20(_flashLoanToken).safeTransferFrom(msg.sender, address(this), _collateralAmount);
Updates

Lead Judging Commences

izuman Lead Judge 16 days ago
Submission Judgement Published
Invalidated
Reason: Out of scope
Assigned finding tags:

WEIRD ERC20 Tokens

Currently there is no support for weird ERC20 tokens i.e. FOT tokens, missing return values, reentrancy etc.

Support

FAQs

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

Give us feedback!