mirror of
https://github.com/serai-dex/serai.git
synced 2025-04-22 22:18:15 +00:00
If the pool has yet to start, insert a price of 0
The test failures were caused by not inserting any price, causing the first price to immediately become the oraclized price. While that's not inherently invalid, suggesting the tests should've been the ones updated, it opens an exploit where whoever first adds liquidity has the opportunity to set a ridiculous price and DoS the set. Not oraclizing until we have an entire period, achieved by inserting 0s during the initial blocks, ensures an open launch for such discovery.
This commit is contained in:
parent
095ac50ba7
commit
62fa31de07
1 changed files with 18 additions and 17 deletions
|
@ -360,22 +360,23 @@ pub mod pallet {
|
|||
for coin in Pools::<T>::iter_keys() {
|
||||
// insert the new price to our oracle window
|
||||
// The spot price for 1 coin, in atomic units, to SRI is used
|
||||
let Ok((sri_balance, coin_balance)) = Self::get_reserves(&Coin::native(), &coin) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// We use 1 coin to handle rounding errors which may occur with atomic units
|
||||
// If we used atomic units, any coin whose atomic unit is worth less than SRI's atomic unit
|
||||
// would cause a 'price' of 0
|
||||
// If the decimals aren't large enough to provide sufficient buffer, use 10,000
|
||||
let coin_decimals = coin.decimals().max(5);
|
||||
let accuracy_increase =
|
||||
HigherPrecisionBalance::from(SubstrateAmount::pow(10, coin_decimals));
|
||||
let sri_per_coin = u64::try_from(
|
||||
accuracy_increase * HigherPrecisionBalance::from(sri_balance) /
|
||||
HigherPrecisionBalance::from(coin_balance),
|
||||
)
|
||||
.unwrap_or(u64::MAX);
|
||||
let sri_per_coin =
|
||||
if let Ok((sri_balance, coin_balance)) = Self::get_reserves(&Coin::native(), &coin) {
|
||||
// We use 1 coin to handle rounding errors which may occur with atomic units
|
||||
// If we used atomic units, any coin whose atomic unit is worth less than SRI's atomic
|
||||
// unit would cause a 'price' of 0
|
||||
// If the decimals aren't large enough to provide sufficient buffer, use 10,000
|
||||
let coin_decimals = coin.decimals().max(5);
|
||||
let accuracy_increase =
|
||||
HigherPrecisionBalance::from(SubstrateAmount::pow(10, coin_decimals));
|
||||
u64::try_from(
|
||||
accuracy_increase * HigherPrecisionBalance::from(sri_balance) /
|
||||
HigherPrecisionBalance::from(coin_balance),
|
||||
)
|
||||
.unwrap_or(u64::MAX)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let sri_per_coin = sri_per_coin.to_be_bytes();
|
||||
|
||||
SpotPriceForBlock::<T>::set(n, coin, sri_per_coin);
|
||||
|
@ -393,7 +394,7 @@ pub mod pallet {
|
|||
SpotPriceForBlock::<T>::remove(start_of_window, coin);
|
||||
// Remove this price from the multiset
|
||||
OraclePrices::<T>::mutate_exists(coin, start_spot_price, |v| {
|
||||
*v = Some(v.unwrap() - 1);
|
||||
*v = Some(v.unwrap_or(1) - 1);
|
||||
if *v == Some(0) {
|
||||
*v = None;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue