sherlock-audit / 2023-11-olympus-judging

9 stars 7 forks source link

tvdung94 - BalancerPoolTokenPrice::getStablePoolTokenPrice() returns price in wrong decimals when poolDecimals is not 18 #140

Closed sherlock-admin2 closed 6 months ago

sherlock-admin2 commented 6 months ago

tvdung94

high

BalancerPoolTokenPrice::getStablePoolTokenPrice() returns price in wrong decimals when poolDecimals is not 18

Summary

BalancerPoolTokenPrice::getStablePoolTokenPrice() returns incorrect price when poolDecimals is not 18

Vulnerability Detail

In this final conversion to get token price

 uint256 poolValue = poolRate.mulDiv(minimumPrice, 10 ** poolDecimals);

Token price will be in wrong decimals, since poolRate is assumed to be in poolDecimals. However, in fact, poolRate is in 18 fixed decimals. This leads to incorrect conversion when poolDecimals is not 18. Reference: https://github.com/balancer/balancer-v2-monorepo/blob/master/pkg/interfaces/contracts/pool-utils/IRateProvider.sol

      >>>    try pool.getRate() returns (uint256 rate_) { //@audit - pool.getRate() is 18 fixed decimals
                if (rate_ == 0) {
                    revert Balancer_PoolStableRateInvalid(poolId, 0);
                }

                poolRate = rate_;
            } catch {
                // Exit if it is not a stable pool
                revert Balancer_PoolTypeNotStable(poolId);
            }

Impact

Core price function returns incorrect price.

Code Snippet

https://github.com/sherlock-audit/2023-11-olympus/blob/main/bophades/src/modules/PRICE/submodules/feeds/BalancerPoolTokenPrice.sol#L548-L550

Tool used

Manual Review

Recommendation

Consider this change

uint256 poolValue = poolRate.mulDiv(minimumPrice, 10 ** 18);
nevillehuang commented 6 months ago

Invalid, all token balances in balancer pools are normalized to 18 decimals with scaling factors, so no issue here.