DeFiHardhatFoundry
250,000 USDC
View results
Submission Details
Severity: high
Valid

Incorrect calculation of `beanUsdPrice` in LibEvaluate::evalPrice

Summary

Inside library LibEvaluate, In the function evalPrice(). beanUsdPrice is being calculated wrongly

beanUsdPrice = 1e30 / ((usd/tkn)*(bean/tkn))

Vulnerability Details

function evalPrice(int256 deltaB, address well) internal view returns (uint256 caseId) {
AppStorage storage s = LibAppStorage.diamondStorage();
// p > 1
if (deltaB > 0) {
// Beanstalk will only use the largest liquidity well to compute the Bean price,
// and thus will skip the p > EXCESSIVE_PRICE_THRESHOLD check if the well oracle fails to
// compute a valid price this Season.
// deltaB > 0 implies that address(well) != address(0).
uint256 beanTknPrice = LibWell.getBeanTokenPriceFromTwaReserves(well);
if (beanTknPrice > 1) {
> uint256 beanUsdPrice = uint256(1e30).div(
> LibWell.getUsdTokenPriceForWell(well) // @ returns usd/tkn price
> .mul(beanTknPrice) // @ returns bean/tkn price
);
if (beanUsdPrice > s.sys.seedGaugeSettings.excessivePriceThreshold) {
// p > excessivePriceThreshold
return caseId = 6;
}
}
caseId = 3;
}
// p < 1
}

Here LibWell.getUsdTokenPriceForWell(well) returns value in terms of usd/tkn price.

function getUsdTokenPriceForWell(address well) internal view returns (uint tokenUsd) {
> tokenUsd = LibAppStorage.diamondStorage().sys.usdTokenPrice[well]; // @ returns usd/tkn price
}

and LibWell.getBeanTokenPriceFromTwaReserves(well) return value in terms of bean/tkn price.

function getBeanTokenPriceFromTwaReserves(address well) internal view returns (uint256 price) {
AppStorage storage s = LibAppStorage.diamondStorage();
// s.sys.twaReserve[well] should be set prior to this function being called.
// 'price' is in terms of reserve0:reserve1.
if (s.sys.twaReserves[well].reserve0 == 0 || s.sys.twaReserves[well].reserve1 == 0) {
price = 0;
} else {
// fetch the bean index from the well in order to properly return the bean price.
if (getBeanIndexFromWell(well) == 0) {
> price = uint256(s.sys.twaReserves[well].reserve0).mul(1e18).div( // @ returns bean/tkn price
s.sys.twaReserves[well].reserve1
);
} else {
price = uint256(s.sys.twaReserves[well].reserve1).mul(1e18).div(
s.sys.twaReserves[well].reserve0
);
}
}
}

Combining above beanUsdPrice will be wrongly calculated in the form of 1e30 / ((usd/tkn)*(bean/tkn)) .

Impact

Wrong calculation of caseId which could result error in the evaluation of beanstalk causing wrong updation of temperature, BeanToMaxLPRatio, incorrect handling of rain and issuing wrong soil.

Tools Used

Manual review

Recommendations

- uint256 beanUsdPrice = uint256(1e30).div(
- LibWell.getUsdTokenPriceForWell(well).mul(beanTknPrice)
- );
+ uint256 beanUsdPrice = beanTknPrice.mul(1e18)
+ .div(LibWell.getUsdTokenPriceForWell(well)
+ );
Updates

Lead Judging Commences

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

Appeal created

psb01 Submitter
about 1 year ago
inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Incorrect calculation of `beanUsdPrice` in LibEvaluate::evalPrice

Support

FAQs

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