mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-03 09:29:46 +00:00
update to new types
This commit is contained in:
parent
94c16b04b8
commit
06bfd5b6a3
3 changed files with 63 additions and 63 deletions
|
@ -70,6 +70,7 @@ pub mod pallet {
|
|||
|
||||
/// Keeps shares and the amount of coins per account.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn liquidity)]
|
||||
pub(crate) type Liquidity<T: Config> = StorageDoubleMap<
|
||||
_,
|
||||
Identity,
|
||||
|
@ -82,6 +83,7 @@ pub mod pallet {
|
|||
|
||||
/// Keeps the total shares and the total amount of coins per coin.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn supply)]
|
||||
pub(crate) type Supply<T: Config> =
|
||||
StorageMap<_, Identity, ExternalCoin, LiquidityAmount, OptionQuery>;
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
use super::*;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use frame_support::{
|
||||
construct_runtime,
|
||||
traits::{ConstU16, ConstU32, ConstU64},
|
||||
|
@ -141,8 +143,18 @@ impl Config for Test {
|
|||
type RuntimeEvent = RuntimeEvent;
|
||||
}
|
||||
|
||||
pub fn key_shares() -> HashMap<NetworkId, Amount> {
|
||||
HashMap::from([
|
||||
(NetworkId::Serai, Amount(50_000 * 10_u64.pow(8))),
|
||||
(NetworkId::External(ExternalNetworkId::Bitcoin), Amount(1_000_000 * 10_u64.pow(8))),
|
||||
(NetworkId::External(ExternalNetworkId::Ethereum), Amount(1_000_000 * 10_u64.pow(8))),
|
||||
(NetworkId::External(ExternalNetworkId::Monero), Amount(100_000 * 10_u64.pow(8))),
|
||||
])
|
||||
}
|
||||
|
||||
pub(crate) fn new_test_ext() -> sp_io::TestExternalities {
|
||||
let mut t = frame_system::GenesisConfig::<Test>::default().build_storage().unwrap();
|
||||
let networks: Vec<(NetworkId, Amount)> = key_shares().into_iter().collect::<Vec<_>>();
|
||||
|
||||
let validators: Vec<Public> = vec![
|
||||
insecure_pair_from_name("Alice").public(),
|
||||
|
@ -153,16 +165,6 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities {
|
|||
insecure_pair_from_name("Ferdie").public(),
|
||||
];
|
||||
|
||||
let networks = NETWORKS
|
||||
.iter()
|
||||
.map(|network| match network {
|
||||
NetworkId::Serai => (NetworkId::Serai, Amount(50_000 * 10_u64.pow(8))),
|
||||
NetworkId::Bitcoin => (NetworkId::Bitcoin, Amount(1_000_000 * 10_u64.pow(8))),
|
||||
NetworkId::Ethereum => (NetworkId::Ethereum, Amount(1_000_000 * 10_u64.pow(8))),
|
||||
NetworkId::Monero => (NetworkId::Monero, Amount(100_000 * 10_u64.pow(8))),
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
coins::GenesisConfig::<Test> {
|
||||
accounts: validators
|
||||
.clone()
|
||||
|
|
|
@ -14,15 +14,11 @@ use validator_sets_primitives::{ValidatorSet, Session, KeyPair};
|
|||
use serai_primitives::*;
|
||||
|
||||
fn set_up_genesis(
|
||||
values: &HashMap<Coin, u64>,
|
||||
) -> (HashMap<Coin, Vec<(SeraiAddress, Amount)>>, u64) {
|
||||
values: &HashMap<ExternalCoin, u64>,
|
||||
) -> (HashMap<ExternalCoin, Vec<(SeraiAddress, Amount)>>, u64) {
|
||||
// make accounts with amounts
|
||||
let mut accounts = HashMap::new();
|
||||
for coin in COINS {
|
||||
if coin == Coin::Serai {
|
||||
continue;
|
||||
}
|
||||
|
||||
for coin in EXTERNAL_COINS {
|
||||
// make 5 accounts per coin
|
||||
let mut values = vec![];
|
||||
for _ in 0 .. 5 {
|
||||
|
@ -36,17 +32,20 @@ fn set_up_genesis(
|
|||
// add some genesis liquidity
|
||||
for (coin, amounts) in &accounts {
|
||||
for (address, amount) in amounts {
|
||||
let balance = Balance { coin: *coin, amount: *amount };
|
||||
let balance = ExternalBalance { coin: *coin, amount: *amount };
|
||||
|
||||
Coins::mint(GENESIS_LIQUIDITY_ACCOUNT.into(), balance).unwrap();
|
||||
Coins::mint(GENESIS_LIQUIDITY_ACCOUNT.into(), balance.into()).unwrap();
|
||||
GenesisLiquidity::add_coin_liquidity((*address).into(), balance).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
// make genesis liquidity event happen
|
||||
let block_number = MONTHS;
|
||||
let values =
|
||||
Values { monero: values[&Coin::Monero], ether: values[&Coin::Ether], dai: values[&Coin::Dai] };
|
||||
let values = Values {
|
||||
monero: values[&ExternalCoin::Monero],
|
||||
ether: values[&ExternalCoin::Ether],
|
||||
dai: values[&ExternalCoin::Dai],
|
||||
};
|
||||
GenesisLiquidity::oraclize_values(RawOrigin::None.into(), values, Signature([0u8; 64])).unwrap();
|
||||
GenesisLiquidity::on_initialize(block_number);
|
||||
System::set_block_number(block_number);
|
||||
|
@ -65,19 +64,16 @@ fn distances() -> (HashMap<NetworkId, u64>, u64) {
|
|||
let mut total_distance: u64 = 0;
|
||||
|
||||
// calculate distance to economic security per network
|
||||
for n in NETWORKS {
|
||||
if n == NetworkId::Serai {
|
||||
continue;
|
||||
}
|
||||
|
||||
for n in EXTERNAL_NETWORKS {
|
||||
let required = ValidatorSets::required_stake_for_network(n);
|
||||
let mut current = ValidatorSets::total_allocated_stake(n).unwrap_or(Amount(0)).0;
|
||||
let mut current =
|
||||
ValidatorSets::total_allocated_stake(NetworkId::from(n)).unwrap_or(Amount(0)).0;
|
||||
if current > required {
|
||||
current = required;
|
||||
}
|
||||
|
||||
let distance = required - current;
|
||||
distances.insert(n, distance);
|
||||
distances.insert(n.into(), distance);
|
||||
total_distance = total_distance.saturating_add(distance);
|
||||
}
|
||||
|
||||
|
@ -90,14 +86,10 @@ fn distances() -> (HashMap<NetworkId, u64>, u64) {
|
|||
}
|
||||
|
||||
fn set_keys_for_session() {
|
||||
for n in NETWORKS {
|
||||
if n == NetworkId::Serai {
|
||||
continue;
|
||||
}
|
||||
|
||||
for network in EXTERNAL_NETWORKS {
|
||||
ValidatorSets::set_keys(
|
||||
RawOrigin::None.into(),
|
||||
n,
|
||||
network,
|
||||
BoundedVec::new(),
|
||||
KeyPair(insecure_pair_from_name("Alice").public(), vec![].try_into().unwrap()),
|
||||
Signature([0u8; 64]),
|
||||
|
@ -142,15 +134,19 @@ fn make_networks_reach_economic_security(block_number: u64) {
|
|||
|
||||
// make sure we reached economic security
|
||||
EconomicSecurity::on_initialize(block_number);
|
||||
for n in &NETWORKS[1 ..] {
|
||||
EconomicSecurity::economic_security_block(*n).unwrap();
|
||||
for n in EXTERNAL_NETWORKS {
|
||||
EconomicSecurity::economic_security_block(n).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn genesis_liquidity() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let values = HashMap::from([(Coin::Monero, 184100), (Coin::Ether, 4785000), (Coin::Dai, 1500)]);
|
||||
let values = HashMap::from([
|
||||
(ExternalCoin::Monero, 184100),
|
||||
(ExternalCoin::Ether, 4785000),
|
||||
(ExternalCoin::Dai, 1500),
|
||||
]);
|
||||
let (accounts, block_number) = set_up_genesis(&values);
|
||||
|
||||
// check that we minted the correct SRI amount
|
||||
|
@ -169,7 +165,7 @@ fn genesis_liquidity() {
|
|||
let mut total_value = 0u128;
|
||||
for (coin, amounts) in &accounts {
|
||||
let total_coin = amounts.iter().fold(0u128, |acc, value| acc + u128::from(value.1 .0));
|
||||
let value = if *coin != Coin::Bitcoin {
|
||||
let value = if *coin != ExternalCoin::Bitcoin {
|
||||
(total_coin * u128::from(values[coin])) / 10u128.pow(coin.decimals())
|
||||
} else {
|
||||
total_coin
|
||||
|
@ -181,23 +177,23 @@ fn genesis_liquidity() {
|
|||
|
||||
// check distributed SRI per pool
|
||||
let mut total_sri_distributed = 0u128;
|
||||
for coin in &COINS[1 ..] {
|
||||
let sri = if coin == COINS.last().unwrap() {
|
||||
for coin in EXTERNAL_COINS {
|
||||
let sri = if &coin == EXTERNAL_COINS.last().unwrap() {
|
||||
u128::from(GENESIS_SRI).checked_sub(total_sri_distributed).unwrap()
|
||||
} else {
|
||||
(pool_amounts[&coin].1 * u128::from(GENESIS_SRI)) / total_value
|
||||
};
|
||||
total_sri_distributed += sri;
|
||||
|
||||
let reserves = Dex::get_reserves(coin, &Coin::Serai).unwrap();
|
||||
let reserves = Dex::get_reserves(&coin.into(), &Coin::Serai).unwrap();
|
||||
assert_eq!(u128::from(reserves.0), pool_amounts[&coin].0); // coin side
|
||||
assert_eq!(u128::from(reserves.1), sri); // SRI side
|
||||
}
|
||||
|
||||
// check each liquidity provider got liquidity tokens proportional to their value
|
||||
for coin in &COINS[1 ..] {
|
||||
for coin in EXTERNAL_COINS {
|
||||
let liq_supply = GenesisLiquidity::supply(coin).unwrap();
|
||||
for (acc, amount) in &accounts[coin] {
|
||||
for (acc, amount) in &accounts[&coin] {
|
||||
let public: PublicKey = (*acc).into();
|
||||
let acc_liq_shares = GenesisLiquidity::liquidity(coin, public).unwrap().shares;
|
||||
|
||||
|
@ -228,34 +224,30 @@ fn genesis_liquidity() {
|
|||
fn remove_coin_liquidity_genesis_period() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let account = insecure_pair_from_name("random1").public();
|
||||
let coin = Coin::Bitcoin;
|
||||
let balance = Balance { coin, amount: Amount(10u64.pow(coin.decimals())) };
|
||||
let coin = ExternalCoin::Bitcoin;
|
||||
let balance = ExternalBalance { coin, amount: Amount(10u64.pow(coin.decimals())) };
|
||||
|
||||
// add some genesis liquidity
|
||||
// TODO: what probably makes sense is to modify the `add_coin_liquidity` and make it take
|
||||
// the origin parameter and transfer the coins from that to GENESIS_LIQUIDITY_ACCOUNT and
|
||||
// register the liquidity for the account. Otherwise seemingly unrelated following 2 lines are
|
||||
// actually stay related.
|
||||
Coins::mint(GENESIS_LIQUIDITY_ACCOUNT.into(), balance).unwrap();
|
||||
Coins::mint(GENESIS_LIQUIDITY_ACCOUNT.into(), balance.into()).unwrap();
|
||||
GenesisLiquidity::add_coin_liquidity(account, balance).unwrap();
|
||||
|
||||
// amount has to be full amount if removing during genesis period
|
||||
assert_noop!(
|
||||
GenesisLiquidity::remove_coin_liquidity(
|
||||
RawOrigin::Signed(account).into(),
|
||||
Balance { coin, amount: Amount(1_000) }
|
||||
ExternalBalance { coin, amount: Amount(1_000) }
|
||||
),
|
||||
genesis_liquidity::Error::<Test>::CanOnlyRemoveFullAmount
|
||||
);
|
||||
|
||||
assert_ok!(GenesisLiquidity::remove_coin_liquidity(
|
||||
RawOrigin::Signed(account).into(),
|
||||
Balance { coin, amount: Amount(INITIAL_GENESIS_LP_SHARES) }
|
||||
ExternalBalance { coin, amount: Amount(INITIAL_GENESIS_LP_SHARES) }
|
||||
));
|
||||
|
||||
// check that user got back the coins
|
||||
assert_eq!(Coins::balance(GENESIS_LIQUIDITY_ACCOUNT.into(), coin), Amount(0));
|
||||
assert_eq!(Coins::balance(account, coin), balance.amount);
|
||||
assert_eq!(Coins::balance(GENESIS_LIQUIDITY_ACCOUNT.into(), coin.into()), Amount(0));
|
||||
assert_eq!(Coins::balance(account, coin.into()), balance.amount);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -263,8 +255,12 @@ fn remove_coin_liquidity_genesis_period() {
|
|||
fn remove_coin_liquidity_after_genesis_period() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// set up genesis
|
||||
let coin = Coin::Monero;
|
||||
let values = HashMap::from([(Coin::Monero, 184100), (Coin::Ether, 4785000), (Coin::Dai, 1500)]);
|
||||
let coin = ExternalCoin::Monero;
|
||||
let values = HashMap::from([
|
||||
(ExternalCoin::Monero, 184100),
|
||||
(ExternalCoin::Ether, 4785000),
|
||||
(ExternalCoin::Dai, 1500),
|
||||
]);
|
||||
let (accounts, mut block_number) = set_up_genesis(&values);
|
||||
|
||||
// make sure no economic security achieved for the network
|
||||
|
@ -273,12 +269,12 @@ fn remove_coin_liquidity_after_genesis_period() {
|
|||
let account: PublicKey = accounts[&coin][0].0.into();
|
||||
// let account_liquidity = accounts[&coin][0].1 .0;
|
||||
let account_sri_balance = Coins::balance(account, Coin::Serai).0;
|
||||
let account_coin_balance = Coins::balance(account, coin).0;
|
||||
let account_coin_balance = Coins::balance(account, coin.into()).0;
|
||||
|
||||
// try to remove liquidity
|
||||
assert_ok!(GenesisLiquidity::remove_coin_liquidity(
|
||||
RawOrigin::Signed(account).into(),
|
||||
Balance { coin, amount: Amount(INITIAL_GENESIS_LP_SHARES / 2) },
|
||||
ExternalBalance { coin, amount: Amount(INITIAL_GENESIS_LP_SHARES / 2) },
|
||||
));
|
||||
|
||||
// since there is no economic security we shouldn't have received any SRI
|
||||
|
@ -288,7 +284,7 @@ fn remove_coin_liquidity_after_genesis_period() {
|
|||
// TODO: this doesn't exactly line up with `account_liquidity / 2`. Prob due to all the integer
|
||||
// mul_divs? There is no pool movement to attribute it to.
|
||||
// assert_eq!(Coins::balance(account, coin).0 - account_coin_balance, account_liquidity / 2);
|
||||
assert!(Coins::balance(account, coin).0 > account_coin_balance);
|
||||
assert!(Coins::balance(account, coin.into()).0 > account_coin_balance);
|
||||
|
||||
// make networks reach economic security
|
||||
make_networks_reach_economic_security(block_number);
|
||||
|
@ -297,16 +293,16 @@ fn remove_coin_liquidity_after_genesis_period() {
|
|||
block_number += MONTHS;
|
||||
System::set_block_number(block_number);
|
||||
|
||||
let coin = Coin::Ether;
|
||||
let coin = ExternalCoin::Ether;
|
||||
let account: PublicKey = accounts[&coin][0].0.into();
|
||||
// let account_liquidity = accounts[&coin][0].1 .0;
|
||||
let account_sri_balance = Coins::balance(account, Coin::Serai).0;
|
||||
let account_coin_balance = Coins::balance(account, coin).0;
|
||||
let account_coin_balance = Coins::balance(account, coin.into()).0;
|
||||
|
||||
// try to remove liquidity
|
||||
assert_ok!(GenesisLiquidity::remove_coin_liquidity(
|
||||
RawOrigin::Signed(account).into(),
|
||||
Balance { coin, amount: Amount(INITIAL_GENESIS_LP_SHARES / 2) },
|
||||
ExternalBalance { coin, amount: Amount(INITIAL_GENESIS_LP_SHARES / 2) },
|
||||
));
|
||||
|
||||
// TODO: this doesn't exactly line up with `account_liquidity / 2`. Prob due to all the integer
|
||||
|
@ -333,6 +329,6 @@ fn remove_coin_liquidity_after_genesis_period() {
|
|||
// TODO: this doesn't exactly line up with `account_liquidity / 2`. Prob due to all the integer
|
||||
// mul_divs? There is no pool movement to attribute it to.
|
||||
// assert_eq!(Coins::balance(account, coin).0 - account_coin_balance, account_liquidity / 2);
|
||||
assert!(Coins::balance(account, coin).0 > account_coin_balance);
|
||||
assert!(Coins::balance(account, coin.into()).0 > account_coin_balance);
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue