The ScrvusdOracleV2
contract's implementation of update_profit_max_unlock_time()
doesn't handle the case when setting the time to zero, unlike the original VaultV3
implementation. In VaultV3
, setting this value to zero immediately unlocks all profit by burning shares and resetting variables, causing an immediate price increase whcih would cause for an inconsistent price reporting across chains wher an attacker can exploit the arbitrage since they know unlike the mainnet the price per share is not going to be updated on the destination chain.
VaultV3::setProfitMaxUnlockTime()
at https://www.contractreader.io/contract/mainnet/0x0655977FEb2f289A4aB78af67BAB0d17aAb84367
Now compare this with whats in the oracle in-scope: scrvusdOracleV2::update_profit_max_unlock_time()
at ScrvusdOracleV2.vy#L333-L349
We can see that the differences the VaultV3
implementation has special handling when new_profit_max_unlock_time
is set to 0:
It burns any shares the vault holds: self._burn_shares(share_balance, self)
It resets unlocking variables: self.profit_unlocking_rate = 0
and self.full_profit_unlock_date = 0
Crucially, this causes "any currently locked profit to instantly unlock and an immediate increase in the vaults Price Per Share"
Our ScrvusdOracleV2
implementation however:
Does not have any special handling for when _profit_max_unlock_time
is set to 0
Simply updates the value without any additional logic
Does not have the mechanisms to unlock profits by burning shares or resetting variables
This is particularly problematic because ScrvusdOracleV2
is intended to mimic the behavior of VaultV3
for cross-chain price calculations.
Inconsistent price calculations between chains when the profit max unlock time is set to zero since in VaultV3
, setting to zero causes an immediate price increase as locked profits are released, but in ScrvusdOracleV2
, no such price adjustment occurs, leading to price divergence which can be exploited for cross-chain arbitrage opportunities due to the price difference
Since the oracle is used to calculate prices across chains, this inconsistency undermines the integrity of the cross-chain price mechanisms and can create arbitrage opportunities that shouldn't exist especially when this system is then leveraged to create stableswapng-pools.
Manual review
Modify the update_profit_max_unlock_time()
function in ScrvusdOracleV2
to include similar logic as VaultV3
when the profit max unlock time is set to zero:
Pseudo implementation:
This ensures that the oracle's price calculations remain consistent with the actual vault behavior when profit max unlock time is set to zero.
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.