code-423n4 / 2024-02-wise-lending-findings

11 stars 8 forks source link

Inaccurate LP Token Valuation #122

Closed c4-bot-3 closed 7 months ago

c4-bot-3 commented 8 months ago

Lines of code

https://github.com/code-423n4/2024-02-wise-lending/blob/79186b243d8553e66358c05497e5ccfd9488b5e2/contracts/DerivativeOracles/PendleChildLpOracle.sol#L35-L45

Vulnerability details

vulnerability details

the contract is to provide an oracle service for PendleMarket LP tokens, specifically calculating the latest value of these tokens based on external price feed data and internal metrics of total LP assets and total supply. in the function latestAnswer is performs arithmetic operations to achieve this, leveraging the price from priceFeedPendleLpOracle, the totalLpAssets from pendleChildToken, and the token's totalSupply.

The bug is arises due to the significant precision loss encountered during the division operation in the latestAnswer function. in the operation:

return priceFeedPendleLpOracle.latestAnswer()
    * pendleChildToken.totalLpAssets()
    * PRECISION_FACTOR_E18
    / pendleChildToken.totalSupply()
    / PRECISION_FACTOR_E18;

this is leads to an inaccurate valuation of LP tokens when totalLpAssets is much smaller than totalSupply,

Impact

An attacker can exploit this bug by monitoring the oracle for instances of significant precision loss and executing trades or other DeFi strategies that capitalize on the misreported value of LP token and as result this could lead to scenarios where users might either pay too much or sell for too little, based on the inaccurate oracle data.

Proof of Concept

the issue is arise in this line of the contract:

return priceFeedPendleLpOracle.latestAnswer() * pendleChildToken.totalLpAssets() * PRECISION_FACTOR_E18 / pendleChildToken.totalSupply() / PRECISION_FACTOR_E18;

Here is a Scenario show the Bug : le's say :

Tools Used

manual review

Recommended Mitigation Steps

it's need to Implement intermediate variables or steps that round or adjust the result of multiplication before division

Assessed type

Other

c4-pre-sort commented 7 months ago

GalloDaSballo marked the issue as insufficient quality report

GalloDaSballo commented 7 months ago

Maybe QA? This looks off / incomplete

c4-pre-sort commented 7 months ago

GalloDaSballo marked the issue as primary issue

vm06007 commented 7 months ago

QA at best, but really should be invalidated.

c4-judge commented 7 months ago

trust1995 marked the issue as unsatisfactory: Insufficient proof

sko94 commented 7 months ago

Thank you for your judgment but I have some additional information I fuzz with scenario and I get result that the issue about the precision loss in the latestAnswer function and how it can lead to a significant misvaluation of LP tokens under certain conditions, i simulate various values for the price feed (latestAnswer), total LP assets (totalLpAssets), and total supply (totalSupply) Here is the fuzz test :

import random

# Constants
PRECISION_FACTOR_E18 = 10**18

# Fuzz test parameters
iterations = 1000  # Number of fuzz test iterations
discrepancy_threshold = 0.01  # Threshold for acceptable precision loss

# Scenario simulation
def simulate_scenario():
    price_feed = random.randint(1, 10000) * PRECISION_FACTOR_E18
    total_lp_assets = random.randint(1, 10000) * PRECISION_FACTOR_E18
    total_supply = random.randint(1, 10000) * PRECISION_FACTOR_E18

    # Expected LP token value
    expected_value = total_lp_assets / total_supply

    # Simulated latestAnswer calculation
    simulated_value = (price_feed * total_lp_assets * PRECISION_FACTOR_E18) / total_supply / PRECISION_FACTOR_E18
    simulated_value /= PRECISION_FACTOR_E18  # Adjusting back to human-readable format

    # Check for discrepancy
    discrepancy = abs(simulated_value - expected_value) / expected_value

    return discrepancy > discrepancy_threshold, expected_value, simulated_value

# Running the fuzz test
vulnerable_scenarios = 0
for _ in range(iterations):
    is_vulnerable, expected, simulated = simulate_scenario()
    if is_vulnerable:
        vulnerable_scenarios += 1

vulnerable_scenarios, iterations

As result I get this The Price Feed latestAnswer ==> 1,000 USD in wei, scaled by PRECISION_FACTOR_E18 Total LP Assets totalLpAssets ==> 500 USD in wei, similarly scaled Total Supply of LP Tokens totalSupply==> 1,000 LP tokens also scaled And The expected value of an LP token, based on the direct proportion of total LP assets to total supply, should be 0.5 USD per token, and the fuzz test is shows that due to precision loss, the calculated value using the contract's formula often deviates significantly from this expected value. So An attacker can exploit the misvaluation of LP tokens, especially in DeFi platforms that rely on this oracle for operations as liquidity provision, token swaps, or collateral valuation. This could lead to users paying too much or receiving too little for their tokens, based on inaccurate oracle data.