code-423n4 / 2024-07-basin-validation

0 stars 0 forks source link

Potential Inaccurate Reserve Calculations Due To Hardcoded decimals #100

Closed c4-bot-9 closed 3 months ago

c4-bot-9 commented 3 months ago

Lines of code

https://github.com/code-423n4/2024-07-basin/blob/main/src/functions/Stable2.sol#L224

Vulnerability details

Vulnerability Details

The calcReserveAtRatioSwap function calls calcReserve(scaledReserves, i, lpTokenSupply, abi.encode(18, 18)) to calculate the scaledReserves[i] value. However, the calcReserve function expects the decimals parameter to be the actual decimal values of the tokens in the well, not hardcoded 18.

Code

scaledReserves[i] = calcReserve(scaledReserves, i, lpTokenSupply, abi.encode(18, 18));

Impact

If the reserve calculation is inaccurate, it can result in incorrect pricing and resource allocation within the well. This could lead to users experiencing losses when performing swaps or providing liquidity, as the contract may not be able to accurately track the true value of the assets.

Poc

function test_calcReserveAtRatioSwap() public {
    uint256[] memory reserves = new uint256[](2);
    uint256[] memory ratios = new uint256[](2);

    reserves[0] = 1000 * 1e18; 
    reserves[1] = 2000 * 1e6; 
    ratios[0] = 1 * 1e6; 
    ratios[1] = 2 * 1e6;

    // Encode well data with different decimal values
    _data = abi.encode(18, 6);

    uint256 reserve = _function.calcReserveAtRatioSwap(reserves, 1, ratios, _data);
    uint256 expectedReserve = 1000 * 1e6; // 1000 tokens with 6 decimals
    assertEq(reserve, expectedReserve, "Incorrect reserve calculated");
}

Mitigation

The correct way to calculate scaledReserves[i] would be to use the decodeWellData function to get the actual decimal values of the tokens, and then use those values when calling calcReserve.

The corrected code would look like this:

uint256[] memory decimals = decodeWellData(data);
uint256 lpTokenSupply = calcLpTokenSupply(scaledReserves, abi.encode(decimals[0], decimals[1]));
scaledReserves[i] = calcReserve(scaledReserves, i, lpTokenSupply, abi.encode(decimals[0], decimals[1]));

Assessed type

Decimal