This repository has been archived by the owner on May 26, 2024. It is now read-only.
xiaoming90 - Incorrect scaling of the spot price #79
Labels
Has Duplicates
A valid issue with 1+ other issues describing the same vulnerability
High
A valid High severity issue
Reward
A payout will be made for this issue
Sponsor Confirmed
The sponsor acknowledged this issue is valid
Will Fix
The sponsor confirmed this issue will be fixed
xiaoming90
high
Incorrect scaling of the spot price
Summary
The incorrect scaling of the spot price leads to the incorrect spot price, which is later compared with the oracle price.
If the spot price is incorrect, it might potentially fail to detect the pool has been manipulated or result in unintended reverts due to false positives. In the worst-case scenario, the trade proceeds to execute against the manipulated pool, leading to a loss of assets.
Vulnerability Detail
Per the comment and source code at Lines 97 to 103, the
SPOT_PRICE.getComposableSpotPrices
is expected to return the spot price in native decimals.https://github.com/sherlock-audit/2023-10-notional/blob/main/leveraged-vaults/contracts/vaults/BalancerComposableAuraVault.sol#L97
Within the
getComposableSpotPrices
function, it will trigger the_calculateStableMathSpotPrice
function. When the primary and secondary balances are passed into theStableMath._calculateInvariant
andStableMath._calcSpotPrice
functions, they are scaled up to 18 decimals precision as StableMath functions only work with balances that have been normalized to 18 decimals.Assuming that the following states:
After scaling the primary and secondary balances, the scaled balances will be as follows:
The spot price returned from the
StableMath._calcSpotPrice
function at Line 93 will be1e18
(1:1).https://github.com/sherlock-audit/2023-10-notional/blob/main/leveraged-vaults/contracts/vaults/balancer/BalancerSpotPrice.sol#L93
Subsequently, in Line 96 above, the code attempts to remove the scaling factor from the spot price (1e18).
The
spotPrice[DAI-Secondary]
is not denominated in native precision after the scaling. TheSPOT_PRICE.getComposableSpotPrices
will return the following spot prices:The returned spot prices will be scaled to POOL_PRECISION (1e18). After the scaling, the spot price remains the same:
The converted spot prices will be passed into the
_calculateLPTokenValue
function. Within the_calculateLPTokenValue
function, the oracle price for DAI<>USDC will be1e18
. From here, thespotPrice[DAI-Secondary]
(1e12 * 1e18) is significantly different from the oracle price (1e18), which will cause the pool manipulation check to revert.https://github.com/sherlock-audit/2023-10-notional/blob/main/leveraged-vaults/contracts/vaults/BalancerComposableAuraVault.sol#L97
Impact
The spot price is used to verify if the pool has been manipulated before executing certain key vault actions (e.g. reinvest rewards).
If the spot price is incorrect, it might potentially result in the following:
_checkPriceAndCalculateValue
function.The affected
_checkPriceAndCalculateValue
function was found to be used within the following functions:reinvestReward
- If the_checkPriceAndCalculateValue
function is malfunctioning or reverts unexpectedly, the protocol will not be able to reinvest, leading to a loss of value for the vault shareholders.convertStrategyToUnderlying
- This function is used by Notional V3 for the purpose of computing the collateral values and the account's health factor. If the_checkPriceAndCalculateValue
function reverts unexpectedly due to an incorrect invariant/spot price, many of Notional's core functions will break. In addition, the collateral values and the account's health factor might be inflated if it fails to detect a manipulated pool due to incorrect invariant/spot price, potentially allowing the malicious actors to drain the main protocol.Code Snippet
https://github.com/sherlock-audit/2023-10-notional/blob/main/leveraged-vaults/contracts/vaults/BalancerComposableAuraVault.sol#L97
https://github.com/sherlock-audit/2023-10-notional/blob/main/leveraged-vaults/contracts/vaults/balancer/BalancerSpotPrice.sol#L93
Tool used
Manual Review
Recommendation
The spot price returned from
StableMath._calcSpotPrice
is denominated in 1e18 (POOL_PRECISION) since the inputted balances are normalized to 18 decimals. The scaling factors are used to normalize a balance to 18 decimals. By dividing or scaling down the spot price by the scaling factor, the native spot price will be returned.The text was updated successfully, but these errors were encountered: