Per the docs, the price smoothening mechanism in ScrvusdOracleV2
is intended to prevent sandwich attacks, but cause we have this in the form of an abrupt max_change
limitation and not a TWAP
this actually enables a different form of slow sandwiching or better still (front/back run).. Since the maximum price change is calculated deterministically based on timestamp differences, attackers can precisely predict future price movements and position themselves to profit from this knowledge, essentially creating a more sophisticated form of sandwiching.
The intended price smoothening logic from the docs is implemented in ScrvusdOracleV2#_smoothed_price() where we restrict the change based on the max_price_increment
:
But the max_change
calculation is entirely deterministic and based on:
The current timestamp (block.timestamp
)
The last update timestamp (self.last_update
)
The last price (last_price
)
The max_price_increment
constant
All of these values can be easily calculated. Now, when the difference between the raw price and last price exceeds max_change
, the function returns a price that is exactly at the limit on the upside (if going up) or last_price - max_change
(if going down).
This however creates a situation where attackers can:
Observe that a price update is coming since they know the price on mainnet
Calculate the exact future price that will be returned by the smoothened functions
Position themselves to profit from this knowledge
Execute their strategy after the price update
Even more problematically, they can wait for the optimal moment to execute their strategy, as the max_change
grows linearly with time due to the (block.timestamp - self.last_update)
component in the calculation.
This predictable smoothening mechanism undermines the very purpose of the price protection and still allows for sandwiching, just that in this case it's quite slow.
So attackers can calculate exactly how much the price will move in a given update, determine the best time to execute their strategy based on the growing max_change
and take positions in DeFi protocols that benefit from the predictable price movement, based on the context of the defi protocol ingesting this.
Manual review
Consider using a time-weighted average price (TWAP) mechanism instead of the current smoothening that still has an abrupt max_change
factor.
This issue and its duplicates lack sufficient proof of the impact of a sudden change in `profit_max_unlock_time`. Both price parameters and `profit_max_unlock_time` can be adjusted immediately, However, the whole purpose of `_smoothed_price` is to limit sudden updates. This is performed when the raw price and last price is compared within the `_price_v0/v1/v2` function calls to limit price updates to `max_change` The slowed price lag can then be safely arbitrage as mentioned in the docs > Smoothing is introduced for sudden updates, so the price slowly catches up with the price, while the pool is being arbitraged safely. Though, smoothing limits the upper bound of price growth. Therefore, we consider that scrvUSD will never be over 60% APR.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.