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

Potential Out-of-Bounds Error in `LibWellMinting::getDeltaBInfoFromWell` Function

Summary

The LibWellMinting contract is designed to compute the time-weighted average deltaB for a given Well. However, it contains a potential out-of-bounds error when handling arrays of different lengths, particularly when the number of tokens returned by the IWell(well).tokens() function does not match the length of other arrays used in calculations.

Vulnerability Details

If the IWell(well).tokens(); return more then 2 tokens.

function getDeltaBInfoFromWell(address well, uint[] memory reserves, bytes memory snapshot, uint256 lookback
) internal view returns (int256, bytes memory, uint256[] memory, uint256[] memory) {
// get well tokens
IERC20[] memory tokens = IWell(well).tokens();
(
uint256[] memory ratios,
uint256 beanIndex,
bool success
) = LibWell.getRatiosAndBeanIndex(tokens, lookback);

The tokens is pass to the getRatiosAndBeanIndex function.

In the getRatiosAndBeanIndex function generates the ratios array based on the tokens returned by IWell(well).tokens(), which may have a variable length depending on the Well's configuration.

function getRatiosAndBeanIndex(IERC20[] memory tokens, uint256 lookback) internal view returns (
uint[] memory ratios,
uint beanIndex,
bool success
) {
success = true;
ratios = new uint[](tokens.length);
beanIndex = type(uint256).max;
for (uint i; i < tokens.length; ++i) {
if (C.BEAN == address(tokens[i])) {
beanIndex = i;
ratios[i] = 1e6;
} else {
ratios[i] = LibUsdOracle.getUsdPrice(address(tokens[i]), lookback);
if (ratios[i] == 0) {
success = false;
}
}
}
require(beanIndex != type(uint256).max, "Bean not in Well.");
}

The number of tokens can vary, potentially returning more than two tokens (e.g., BEAN, WETH, WSTETH) and this is all supported by getUsdPrice function.

The core issue lies in the calculateDeltaBAtBeanIndex function, which takes in two arrays, reserves and ratios, and performs calculations assuming they are of the same length. This assumption can lead to an out-of-bounds error if the arrays have different lengths.

function calculateDeltaBAtBeanIndex(address well, uint[] memory reserves, uint256[] memory ratios, uint256 beanIndex
) internal view returns (int256) {
Call memory wellFunction = IWell(well).wellFunction();
return int256(IBeanstalkWellFunction(wellFunction.target).calcReserveAtRatioSwap(
reserves,
beanIndex,
ratios,
wellFunction.data
)).sub(int256(reserves[beanIndex]));
}

Impact

An out-of-bounds error can cause the contract to revert, preventing any operations dependent on these calculations from succeeding. This could disrupt the normal functioning of the LibWellMinting, leading to failed updates to deltaB calculations.

Tools Used

Manual Review

Recommendations

Ensure that the lengths of reserves and ratios arrays are the same in the calculateDeltaBAtBeanIndex function before pass to calcReserveAtRatioSwap function.

Updates

Lead Judging Commences

giovannidisiena Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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