DeFiHardhatFoundry
250,000 USDC
View results
Submission Details
Severity: low
Invalid

Front-Running Vulnerability in ApprovalFacet.sol Contract

Summary

The ApprovalFacet.sol contract in the Beanstalk project has a potential front-running vulnerability in the increaseDepositAllowance and decreaseDepositAllowance functions. This vulnerability could be exploited to manipulate the contract's state before a transaction is executed, leading to unintended consequences.

Vulnerability Details

The increaseDepositAllowance and decreaseDepositAllowance functions in ApprovalFacet.sol perform two separate steps:

  • Check current allowance: Verify if the current allowance is sufficient to increase/decrease by the desired amount.

  • Update allowance: If sufficient, the function increases/decreases the allowance accordingly.

However, the separation of these two steps creates a small window of time between checking and updating the allowance. An attacker could exploit this time gap to execute another transaction before the allowance is updated.

Example:

  • In increaseDepositAllowance: An attacker could send a transaction to transfer a large amount of deposit before the allowance is increased.

  • In decreaseDepositAllowance: An attacker could send a transaction to transfer a large amount of deposit before the allowance is decreased.

Impact

Users could lose their deposits because the attacker transferred them before the allowance was updated.

Tools Used

Manual

Recommendations

Add the functions _increaseDepositAllowance and _decreaseDepositAllowance in LibSiloPermit.

import {LibRedundantMath256} from "contracts/libraries/LibRedundantMath256.sol";
// ...
library LibSiloPermit {
using LibRedundantMath256 for uint256;
// ...
function _increaseDepositAllowance(address owner, address spender, address token, uint256 addedValue) internal {
AppStorage storage s = LibAppStorage.diamondStorage();
uint256 newAllowance = s.a[owner].depositAllowances[spender][token].add(addedValue);
s.a[owner].depositAllowances[spender][token] = newAllowance;
emit DepositApproval(owner, spender, token, newAllowance);
}
function _decreaseDepositAllowance(address owner, address spender, address token, uint256 subtractedValue) internal {
AppStorage storage s = LibAppStorage.diamondStorage();
uint256 currentAllowance = s.a[owner].depositAllowances[spender][token];
require(currentAllowance >= subtractedValue, "Silo: decreased allowance below zero");
uint256 newAllowance = currentAllowance.sub(subtractedValue);
s.a[owner].depositAllowances[spender][token] = newAllowance;
emit DepositApproval(owner, spender, token, newAllowance);
}
}

Use these functions in LibSiloPermit to increase/decrease allowance more securely.

function increaseDepositAllowance(
address spender,
address token,
uint256 addedValue
) public virtual fundsSafu noNetFlow noSupplyChange nonReentrant returns (bool) {
LibSiloPermit._increaseDepositAllowance(LibTractor._user(), spender, token, addedValue);
return true;
}
function decreaseDepositAllowance(
address spender,
address token,
uint256 subtractedValue
) public virtual fundsSafu noNetFlow noSupplyChange nonReentrant returns (bool) {
LibSiloPermit._decreaseDepositAllowance(LibTractor._user(), spender, token, subtractedValue);
return true;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Informational/Gas

Invalid as per docs https://docs.codehawks.com/hawks-auditors/how-to-determine-a-finding-validity

Support

FAQs

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