DeFiLayer 1Layer 2
14,723 OP
View results
Submission Details
Severity: high
Invalid

Incorrect Effective Supply Calculation in `ScrvusdOracleV2`

Summary

The _total_supply() function in the ScrvusdOracleV2.vy contract contains a critical logic error in how it calculates the effective supply of scrvUSD. The function incorrectly subtracts unlocked shares from the total supply when it should be subtracting the remaining locked shares. This leads to an overestimated effective supply and consequently undervalued token prices, potentially resulting in significant economic impact on users and the protocol.

Vulnerability Details

The core of the issue is in the implementation of the _total_supply() function:

@view
def _total_supply(p: PriceParams, ts: uint256) -> uint256:
# Need to account for the shares issued to the vault that have unlocked.
return p.total_supply - self._unlocked_shares(
p.full_profit_unlock_date,
p.profit_unlocking_rate,
p.last_profit_update,
p.balance_of_self,
ts, # block.timestamp
)

When profit is earned, shares are minted to the vault itself (balance_of_self), and these shares gradually unlock over time.

The _unlocked_shares() function correctly returns the amount of shares that have been unlocked from the vault's balance. However, the _total_supply() function incorrectly subtracts these unlocked shares from the total supply, which has the opposite effect of what's intended.

The correct implementation should subtract the remaining locked shares (balance_of_self - unlocked_shares) from the total supply to get the effective supply.

Conceptually:

Total supply = All shares (including those locked in the vault)

Effective supply = Total supply - Remaining locked shares

Remaining locked shares = balance_of_self - unlocked_shares

Therefore, the correct implementation should be:

effective_supply = total_supply - (balance_of_self - unlocked_shares)

But the current implementation does:

effective_supply = total_supply - unlocked_shares

This results in an effective supply that's higher than it should be, which leads to a lower calculated price when computing total_assets / effective_supply.

Impact

  • Price Undervaluation: The share price of scrvUSD is calculated using the formula total_assets / effective_supply. An overestimated effective supply leads to undervalued token prices.

  • Economic Loss: Users redeeming tokens would receive less value than they should, while minters would get more shares than warranted, creating an imbalance that can be exploited.

To quantify the impact with an example:

  • If total_supply = 1000, balance_of_self = 100 (locked), and unlocked_shares = 30

  • Current calculation: effective supply = 1000 - 30 = 970

  • Correct calculation: effective supply = 1000 - (100 - 30) = 930

  • This represents a ~4.3% overestimation of supply, resulting in a ~4.1% undervaluation of the token price

  • The price discrepancy grows as more shares become unlocked, potentially leading to significant economic damage.

Tools Used

  • Manual code review

Recommendations

  • Update the _total_supply() function to correctly account for remaining locked shares:

@view
def _total_supply(p: PriceParams, ts: uint256) -> uint256:
unlocked_shares: uint256 = self._unlocked_shares(
p.full_profit_unlock_date,
p.profit_unlocking_rate,
p.last_profit_update,
p.balance_of_self,
ts
)
remaining_locked: uint256 = p.balance_of_self - unlocked_shares
return p.total_supply - remaining_locked
Updates

Lead Judging Commences

0xnevi Lead Judge
3 months ago
0xnevi Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.