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

```LibWellBdv::bdv``` doesn't manages properly external call failures due to missing error handling

Summary

The LibWellBdv::bdv function performs an external call to IInstantaneousPump(pumps[0].target).readInstantaneousReserves(well, pumps[0].data) without employing a try/catch block for error handling. This implementation leaves the function — and by extension, any other function relying on bdv — vulnerable to unhandled exceptions. When an external call fails (e.g., due to the called contract reverting for any reason), the failure cascades and causes the entire transaction stack to revert. The function as written leaves all the transactions to revert without managing the failure. This implementation seems not in line with the project design where the call to the IInstantaneousPump(pumps[0].target).readInstantaneousReserves(well, pumps[0].data) in other functions across the project is managed using a try/catch block (for example: LibWell:getTwaReservesFromBeanstalkPump, LibWell::getTwaLiquidityFromBeanstalkPump and others).

Vulnerability Details

function bdv(
address well,
uint amount
) internal view returns (uint _bdv) {
uint beanIndex = LibWell.getBeanIndexFromWell(well);
// For now, assume Beanstalk should always use the first pump and given that the Well has been whitelisted, it should be assumed
// that the first Pump has been verified when the Well was whitelisted.
@> Call[] memory pumps = IWell(well).pumps();
@> uint[] memory reserves = IInstantaneousPump(pumps[0].target).readInstantaneousReserves(well, pumps[0].data);
// If the Bean reserve is beneath the minimum balance, the oracle should be considered as off.
require(reserves[beanIndex] >= C.WELL_MINIMUM_BEAN_BALANCE, "Silo: Well Bean balance below min");
Call memory wellFunction = IWell(well).wellFunction();
uint lpTokenSupplyBefore = IWellFunction(wellFunction.target).calcLpTokenSupply(reserves, wellFunction.data);
reserves[beanIndex] = reserves[beanIndex].sub(BEAN_UNIT); // remove one Bean
uint deltaLPTokenSupply = lpTokenSupplyBefore.sub(
IWellFunction(wellFunction.target).calcLpTokenSupply(reserves, wellFunction.data)
);
_bdv = amount.mul(BEAN_UNIT).div(deltaLPTokenSupply);
}

Impact

The bdv function is central to the Beanstalk project's operations, as it calculates the bdv of a given Well LP Token. This calculation is crucial for determining the value of liquidity provided to the Beanstalk ecosystem.

The revert of bdv leads the functionalities that depend on the successful execution of bdv to fail unexpectedly. This includes any logic that relies on the BDV calculation for further processing or decision-making within the contract. The abrupt reversion of transactions can halt these operations, affecting the contract's and the protocol.

Tools Used

Manual review

Recommendations

Modify the bdv function to wrap the external call in a try/catch block (as is in the other functions).

Updates

Lead Judging Commences

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

Informational/Invalid

Support

FAQs

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