2025-03-06 05:53:18 -05:00
|
|
|
use sp_core::{Pair as _, sr25519::Pair};
|
2024-10-30 23:05:56 +03:00
|
|
|
use frame_system::RawOrigin;
|
|
|
|
|
|
2025-09-19 22:12:45 -04:00
|
|
|
use serai_abi::primitives::{coin::*, balance::*, address::*, instructions::*};
|
2025-03-06 05:53:18 -05:00
|
|
|
|
|
|
|
|
use crate::mock::*;
|
2024-10-30 23:05:56 +03:00
|
|
|
|
2025-09-19 22:12:45 -04:00
|
|
|
pub type CoinsEvent = serai_abi::coins::Event;
|
2024-10-30 23:05:56 +03:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn mint() {
|
|
|
|
|
new_test_ext().execute_with(|| {
|
2025-09-19 22:12:45 -04:00
|
|
|
Core::start_transaction();
|
|
|
|
|
|
2024-10-30 23:05:56 +03:00
|
|
|
// minting u64::MAX should work
|
|
|
|
|
let coin = Coin::Serai;
|
2025-03-06 05:53:18 -05:00
|
|
|
let to = Pair::generate().0.public();
|
2024-10-30 23:05:56 +03:00
|
|
|
let balance = Balance { coin, amount: Amount(u64::MAX) };
|
|
|
|
|
|
|
|
|
|
Coins::mint(to, balance).unwrap();
|
|
|
|
|
assert_eq!(Coins::balance(to, coin), balance.amount);
|
|
|
|
|
|
|
|
|
|
// minting more should fail
|
|
|
|
|
assert!(Coins::mint(to, Balance { coin, amount: Amount(1) }).is_err());
|
|
|
|
|
|
|
|
|
|
// supply now should be equal to sum of the accounts balance sum
|
2025-03-06 05:53:18 -05:00
|
|
|
assert_eq!(Coins::supply(coin), balance.amount);
|
2024-10-30 23:05:56 +03:00
|
|
|
|
|
|
|
|
// test events
|
2025-09-19 22:12:45 -04:00
|
|
|
let mint_events = Core::events()
|
2024-10-30 23:05:56 +03:00
|
|
|
.iter()
|
2025-11-13 04:50:54 -05:00
|
|
|
.map(|event| borsh::from_slice::<serai_abi::Event>(event.as_slice()).unwrap())
|
2024-10-30 23:05:56 +03:00
|
|
|
.filter_map(|event| {
|
2025-09-19 22:12:45 -04:00
|
|
|
if let serai_abi::Event::Coins(e) = &event {
|
2024-10-30 23:05:56 +03:00
|
|
|
if matches!(e, CoinsEvent::Mint { .. }) {
|
|
|
|
|
Some(e.clone())
|
|
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
2025-09-19 22:12:45 -04:00
|
|
|
assert_eq!(mint_events, vec![CoinsEvent::Mint { to: to.into(), coins: balance }]);
|
2024-10-30 23:05:56 +03:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn burn_with_instruction() {
|
|
|
|
|
new_test_ext().execute_with(|| {
|
2025-09-19 22:12:45 -04:00
|
|
|
Core::start_transaction();
|
|
|
|
|
|
2024-10-30 23:05:56 +03:00
|
|
|
// mint some coin
|
|
|
|
|
let coin = Coin::External(ExternalCoin::Bitcoin);
|
2025-03-06 05:53:18 -05:00
|
|
|
let to = Pair::generate().0.public();
|
2024-10-30 23:05:56 +03:00
|
|
|
let balance = Balance { coin, amount: Amount(10 * 10u64.pow(coin.decimals())) };
|
|
|
|
|
|
|
|
|
|
Coins::mint(to, balance).unwrap();
|
|
|
|
|
assert_eq!(Coins::balance(to, coin), balance.amount);
|
2025-03-06 05:53:18 -05:00
|
|
|
assert_eq!(Coins::supply(coin), balance.amount);
|
2024-10-30 23:05:56 +03:00
|
|
|
|
|
|
|
|
// we shouldn't be able to burn more than what we have
|
|
|
|
|
let mut instruction = OutInstructionWithBalance {
|
2025-03-06 05:53:18 -05:00
|
|
|
instruction: OutInstruction::Transfer(ExternalAddress::try_from(vec![]).unwrap()),
|
2024-10-30 23:05:56 +03:00
|
|
|
balance: ExternalBalance {
|
|
|
|
|
coin: coin.try_into().unwrap(),
|
2025-03-06 05:53:18 -05:00
|
|
|
amount: (balance.amount + Amount(1)).unwrap(),
|
2024-10-30 23:05:56 +03:00
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
assert!(
|
|
|
|
|
Coins::burn_with_instruction(RawOrigin::Signed(to).into(), instruction.clone()).is_err()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// it should now work
|
|
|
|
|
instruction.balance.amount = balance.amount;
|
|
|
|
|
Coins::burn_with_instruction(RawOrigin::Signed(to).into(), instruction.clone()).unwrap();
|
|
|
|
|
|
|
|
|
|
// balance & supply now should be back to 0
|
|
|
|
|
assert_eq!(Coins::balance(to, coin), Amount(0));
|
2025-03-06 05:53:18 -05:00
|
|
|
assert_eq!(Coins::supply(coin), Amount(0));
|
2024-10-30 23:05:56 +03:00
|
|
|
|
2025-09-19 22:12:45 -04:00
|
|
|
let burn_events = Core::events()
|
2024-10-30 23:05:56 +03:00
|
|
|
.iter()
|
2025-11-13 04:50:54 -05:00
|
|
|
.map(|event| borsh::from_slice::<serai_abi::Event>(event.as_slice()).unwrap())
|
2024-10-30 23:05:56 +03:00
|
|
|
.filter_map(|event| {
|
2025-09-19 22:12:45 -04:00
|
|
|
if let serai_abi::Event::Coins(e) = &event {
|
2024-10-30 23:05:56 +03:00
|
|
|
if matches!(e, CoinsEvent::BurnWithInstruction { .. }) {
|
|
|
|
|
Some(e.clone())
|
|
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
2025-09-19 22:12:45 -04:00
|
|
|
assert_eq!(burn_events, vec![CoinsEvent::BurnWithInstruction { from: to.into(), instruction }]);
|
2024-10-30 23:05:56 +03:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn transfer() {
|
|
|
|
|
new_test_ext().execute_with(|| {
|
2025-09-19 22:12:45 -04:00
|
|
|
Core::start_transaction();
|
|
|
|
|
|
2024-10-30 23:05:56 +03:00
|
|
|
// mint some coin
|
|
|
|
|
let coin = Coin::External(ExternalCoin::Bitcoin);
|
2025-03-06 05:53:18 -05:00
|
|
|
let from = Pair::generate().0.public();
|
2024-10-30 23:05:56 +03:00
|
|
|
let balance = Balance { coin, amount: Amount(10 * 10u64.pow(coin.decimals())) };
|
|
|
|
|
|
|
|
|
|
Coins::mint(from, balance).unwrap();
|
|
|
|
|
assert_eq!(Coins::balance(from, coin), balance.amount);
|
2025-03-06 05:53:18 -05:00
|
|
|
assert_eq!(Coins::supply(coin), balance.amount);
|
2024-10-30 23:05:56 +03:00
|
|
|
|
|
|
|
|
// we can't send more than what we have
|
2025-03-06 05:53:18 -05:00
|
|
|
let to = Pair::generate().0.public();
|
2024-10-30 23:05:56 +03:00
|
|
|
assert!(Coins::transfer(
|
|
|
|
|
RawOrigin::Signed(from).into(),
|
|
|
|
|
to,
|
2025-03-06 05:53:18 -05:00
|
|
|
Balance { coin, amount: (balance.amount + Amount(1)).unwrap() }
|
2024-10-30 23:05:56 +03:00
|
|
|
)
|
|
|
|
|
.is_err());
|
|
|
|
|
|
|
|
|
|
// we can send it all
|
|
|
|
|
Coins::transfer(RawOrigin::Signed(from).into(), to, balance).unwrap();
|
|
|
|
|
|
|
|
|
|
// check the balances
|
|
|
|
|
assert_eq!(Coins::balance(from, coin), Amount(0));
|
|
|
|
|
assert_eq!(Coins::balance(to, coin), balance.amount);
|
|
|
|
|
|
|
|
|
|
// supply shouldn't change
|
2025-03-06 05:53:18 -05:00
|
|
|
assert_eq!(Coins::supply(coin), balance.amount);
|
2024-10-30 23:05:56 +03:00
|
|
|
})
|
|
|
|
|
}
|