code-423n4 / 2024-03-abracadabra-money-findings

9 stars 7 forks source link

`MagicLPAggregator` will return wrong price for base tokens less than 18 decimals. #165

Closed c4-bot-7 closed 8 months ago

c4-bot-7 commented 8 months ago

Lines of code

https://github.com/code-423n4/2024-03-abracadabra-money/blob/main/src/oracles/aggregators/MagicLpAggregator.sol#L37-L46

Vulnerability details

Impact

MagicLPAggregator will return wrong price for tokens less than 18 decimals.

The MagicLPAggregator intends to return price of a LP in terms of USD in 18 decimals.

MagicLpAggregator.sol#L29-L31

 function decimals() external pure override returns (uint8) {
        return 18;
}

But let's take a look at the following function. MagicLpAggregator.sol#L37-L46

    function latestAnswer() public view override returns (int256) {
        uint256 baseAnswerNomalized = uint256(baseOracle.latestAnswer()) * (10 ** (WAD - baseOracle.decimals()));
        uint256 quoteAnswerNormalized = uint256(quoteOracle.latestAnswer()) * (10 ** (WAD - quoteOracle.decimals()));
        uint256 minAnswer = baseAnswerNomalized < quoteAnswerNormalized ? baseAnswerNomalized : quoteAnswerNormalized;

        (uint256 baseReserve, uint256 quoteReserve) = _getReserves();
        baseReserve = baseReserve * (10 ** (WAD - baseDecimals));
        quoteReserve = quoteReserve * (10 ** (WAD - quoteDecimals));
        return int256(minAnswer * (baseReserve + quoteReserve) / pair.totalSupply());
    }

Let us break down the above function, it first:

But if you look at the above closely, you will notice that although the function seems correct it outputs the price in the wrong decimals (not 18):

MagicLP.sol#L163-L165

    function decimals() public view override returns (uint8) {
        return IERC20Metadata(_BASE_TOKEN_).decimals();
    }

Therefore if IERC20Metadata(_BASE_TOKEN_).decimals() is not 18 decimals, let us say 6 decimals (ie. USDT token)

Than the decimals for the final output isn't correct as 18 + 18 - 6 = 30 decimals which is 10^12 times the intended price we wanted to return.

Tools Used

Manual Review

Recommended Mitigation Steps

Normalize pair.totalSupply() to 18 decimals so that the final output is 18 + 18 - 18 = 18 decimals.

Assessed type

Oracle

0xm3rlin commented 8 months ago

duplicate #191

c4-pre-sort commented 8 months ago

141345 marked the issue as duplicate of #64

c4-judge commented 8 months ago

thereksfour marked the issue as duplicate of #90

c4-judge commented 8 months ago

thereksfour marked the issue as satisfactory

c4-judge commented 8 months ago

thereksfour changed the severity to 2 (Med Risk)