DeFiHardhat
21,000 USDC
View results
Submission Details
Severity: high
Invalid

An Insufficient Check in Token Balance in _withdrawTokens

Summary

the root of the bug is that the _withdrawTokens function does not check if the account has sufficient tokens before attempting to withdraw, and this leading to overdraw attempts and transaction failures.

Vulnerability Details

The function relies on the internal logic of LibTokenSilo.removeDepositFromAccount to handle token removal but does not ensure the account balance is sufficient beforehand, and this leads to state inconsistencies where the function attempts to remove more tokens than available, causing errors.
here is the vulnerable line here https://github.com/Cyfrin/2024-05-Beanstalk-3/blob/662d26f12ee219ee92dc485c06e01a4cb5ee8dfb/protocol/contracts/beanstalk/silo/ConvertFacet.sol#L156:

if (a.active.tokens.add(amounts[i]) >= maxTokens) amounts[i] = maxTokens.sub(a.active.tokens);

here it's updates amounts[i] without verifying if the total available tokens in the account are sufficient to meet the maxTokens requirement.
this affected this https://github.com/Cyfrin/2024-05-Beanstalk-3/blob/662d26f12ee219ee92dc485c06e01a4cb5ee8dfb/protocol/contracts/beanstalk/silo/ConvertFacet.sol#L157C15-L162C23 here is attempts to remove deposits from the account without prior balance checks:

depositBDV = LibTokenSilo.removeDepositFromAccount(
account,
token,
stems[i],
amounts[i]
);

and final Validation here https://github.com/Cyfrin/2024-05-Beanstalk-3/blob/662d26f12ee219ee92dc485c06e01a4cb5ee8dfb/protocol/contracts/beanstalk/silo/ConvertFacet.sol#L200C1-L204C11 and this is checks if the tokens removed meet the maxTokens requirement, which fails due to the above inconsistency.

require(
a.active.tokens == maxTokens,
"Convert: Not enough tokens removed."
);
  • scenario show the issue :
    i test with this scenario for confirmation :

  • Account has 50 tokens.

  • maxTokens is set to 100.
    Input Values:

  • stems = [1, 2, 3]

  • amounts = [30, 20, 50] (total 100)
    as result the function attempts to withdraw 100 tokens, causing a failure since the account only has 50 tokens.

Impact

The function tries to remove more tokens than the account holds and this causing the contract to fail as result it's lead to Inconsistency state.
so Malicious users can exploit the lack of balance checks to disrupt the contract's functionality

Tools Used

manual review

Recommendations

need to check to ensure sufficient balances before attempting token withdrawals.

Updates

Lead Judging Commences

giovannidisiena Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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