DeFiHardhatOracleProxyUpdates
100,000 USDC
View results
Submission Details
Severity: low
Invalid

Precision error in `setSoilAbovePeg`

Summary

setSoilAbovePeg from Sun.sol contains two instances of precision loss due to division before multiplication which lowers the newSoil issued both when Pod Rate is high and Pod Rate is low.

Vulnerability Details

The setSoilAbovePeg function first computes the newSoil by multiplying the newHarvestable with 100 and dividing it by (100 + s.w.t), then depending on the caseId this is again multiplied by the appropriate SOIL_COEFFICIENT(be it HIGH or LOW) then again it's divided by the C.PRECISION.

The newSoil ends up truncated twice, resulting in a lower overall value.

function setSoilAbovePeg(uint256 newHarvestable, uint256 caseId) internal {
uint256 newSoil = newHarvestable.mul(100).div(100 + s.w.t);
if (caseId >= 24) {
newSoil = newSoil.mul(SOIL_COEFFICIENT_HIGH).div(C.PRECISION); // high podrate
} else if (caseId < 8) {
newSoil = newSoil.mul(SOIL_COEFFICIENT_LOW).div(C.PRECISION); // low podrate
}
setSoil(newSoil);
}

Impact

This has various consequences. The inline comments describe the following mechanism:

`* When the Pod Rate is high, Beanstalk issues less Soil.` - even less soil will be issued
`* When the Pod Rate is low, Beanstalk issues more Soil.` - it won't be that `more` because it's truncated twice.

Likelihood is High because it happens everytime.

Impact is low/medium because the truncated amount is small, but still, it happens very often.

Tools Used

Manual review

Recommendations

Perform the following changes:

function setSoilAbovePeg(uint256 newHarvestable, uint256 caseId) internal {
-- uint256 newSoil = newHarvestable.mul(100).div(100 + s.w.t);
-- if (caseId >= 24) {
-- newSoil = newSoil.mul(SOIL_COEFFICIENT_HIGH).div(C.PRECISION); // high podrate
-- } else if (caseId < 8) {
-- newSoil = newSoil.mul(SOIL_COEFFICIENT_LOW).div(C.PRECISION); // low podrate
-- }
++ uint256 newSoil;
++ if (caseId >= 24) {
++ newSoil = newHarvestable.mul(100).mul(SOIL_COEFFICIENT_HIGH).div(100 + s.w.t).div(C.PRECISION); // high podrate
++ } else if (caseId < 8) {
++ newSoil = newHarvestable.mul(100).mul(SOIL_COEFFICIENT_LOW).div(100 + s.w.t).div(C.PRECISION); // low podrate
++ }
setSoil(newSoil);
}
Updates

Lead Judging Commences

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

Soil precision

Support

FAQs

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