Thunder Loan

AI First Flight #7
Beginner FriendlyFoundryDeFiOracle
EXP
View results
Submission Details
Impact: low
Likelihood: medium
Invalid

Missing explicit allowlist check in flashloan() allows unintended token usage

Root + Impact

Description

  • The flashloan() function is intended to operate only on approved tokens that have been explicitly added via setAllowedToken.

  • However, the function does not enforce this requirement and directly fetches the AssetToken from the mapping without verifying that the token is allowed.

// Root cause in the codebase with @> marks to highlight the relevant section
function flashloan(address receiverAddress, IERC20 token, uint256 amount, bytes calldata params) external {
// @> No check that token is allowed
AssetToken assetToken = s_tokenToAssetToken[token];
uint256 startingBalance = IERC20(token).balanceOf(address(assetToken));

If the token is not allowed:

  • assetToken will be address(0)

  • The function continues execution until it later interacts with this invalid reference

uint256 fee = getCalculatedFee(token, amount);
// @> Will revert when calling function on address(0)
assetToken.updateExchangeRate(fee);

Risk

Likelihood:

  • Function is externally callable with arbitrary token addresses

  • No early validation ensures only approved tokens are used

Impact:

  • Unintended tokens can be passed into the flashloan flow

  • Execution reverts later in the function rather than failing early

  • Leads to poor validation design and unnecessary gas consumption


Proof of Concept

  • Call flashloan with a non-approved token:

flashloan(address(this), IERC20(nonAllowedToken), 100, "");
  • Behavior:

    • assetToken = address(0)

    • Function proceeds

    • Reverts when calling:

assetToken.updateExchangeRate(fee);

Recommended Mitigation

  • Add explicit validation to ensure only allowed tokens are used

function flashloan(address receiverAddress, IERC20 token, uint256 amount, bytes calldata params) external {
+ require(address(s_tokenToAssetToken[token]) != address(0), "Token not allowed");
AssetToken assetToken = s_tokenToAssetToken[token];

Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 13 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!