DeFiHardhat
35,000 USDC
View results
Submission Details
Severity: low
Invalid

[M] Timestamp in addLiquidity is of type max timestamp, leaving hanging transactions causing users to lose out on expected Fertilizer.

Summary

mintFertilizer allows users to purchase Fertilizer specifying a minimum amount of Fertilizer they expect to receive.
minLPAmountOut.

function mintFertilizer(uint256 tokenAmountIn, uint256 minFertilizerOut, uint256 minLPTokensOut)
external payable returns (uint256 fertilizerAmountOut) {
fertilizerAmountOut = _getMintFertilizerOut(tokenAmountIn, LibBarnRaise.getBarnRaiseToken());
require(fertilizerAmountOut >= minFertilizerOut, "Fertilizer: Not enough bought.");
require(fertilizerAmountOut > 0, "Fertilizer: None bought.");
uint128 remaining = uint128(LibFertilizer.remainingRecapitalization().div(1e6)); // remaining <= 77_000_000 so downcasting is safe.
require(fertilizerAmountOut <= remaining, "Fertilizer: Not enough remaining.");
uint128 id = LibFertilizer.addFertilizer(
uint128(s.season.current),
tokenAmountIn,
fertilizerAmountOut,
minLPTokensOut
);
C.fertilizer().beanstalkMint(msg.sender, uint256(id), (fertilizerAmountOut).toUint128(), s.bpf);
}

Vulnerability Details

However, despite the initial security check in the well for minLPAmountOut below...

lpAmountOut = _calcLpTokenSupply(wellFunction(), reserves) - totalSupply();
if (lpAmountOut < minLpAmountOut) {
revert SlippageOut(lpAmountOut, minLpAmountOut);
}

By the time we arrive at addUnderlying, the timestamp is set to the maximum value, leaving the user's transaction hanging.

uint256 newLP = IWell(barnRaiseWell).addLiquidity(
tokenAmountsIn,
minAmountOut,
address(this),
type(uint256).max//@audit
);

POC:

A user submits a tx to mintFertilizer but with a low gas fee.

The same user specified a slippage tolerance of 1% in the minLPTokensOut parameter.

The price in the well increases drastically, leading to increased slippage.

Now, the slippage has increased to 50%.

The user's tx is eventually included in the block.timestamp, but the user now gets a worse execution price.

Impact

The user will receive a lower amount of Fertilizer than expected due to the increased slippage, causing
a revert. This will lead to a loss of prospective accumulated fertilizer tokens. Also considering the amount of Fertilizer issued to a buyer is determined by the oracle, if any expected price deviations occur as well, the user will receive a lower amount of Fertilizer than expected.

Tools Used

Manual Review

Recommendations

As in the IWell interface, AND Uniswap models, the timestamp should be set by the user.

function mintFertilizer(uint256 tokenAmountIn, uint256 minFertilizerOut, uint256 minLPTokensOut, uint256 deadline)

Pass in a user defined timestamp to the mintFertilizer function, and use this timestamp in the
addLiquidity function call in addUnderlying.

uint256 newLP = IWell(barnRaiseWell).addLiquidity(
tokenAmountsIn,
minAmountOut,
address(this),
uint256(deadline)
);
Updates

Lead Judging Commences

giovannidisiena Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

Fertilizer deadline

golanger85 Submitter
over 1 year ago
giovannidisiena Lead Judge
over 1 year ago
golanger85 Submitter
over 1 year ago
giovannidisiena Lead Judge
over 1 year ago
golanger85 Submitter
over 1 year ago
giovannidisiena Lead Judge
over 1 year ago
golanger85 Submitter
over 1 year ago
giovannidisiena Lead Judge
over 1 year ago
giovannidisiena Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

Fertilizer deadline

Support

FAQs

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