Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support all fractional places #1049

Merged
merged 19 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/changelog_for_devs.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,23 @@ https://keepachangelog.com/en/1.0.0/ and ⚠️ marks changes that might break
components which query the chain's storage, the extrinsics or the runtime
APIs/RPC interface.

## v0.3.11

[#1049]: https://github.com/zeitgeistpm/zeitgeist/pull/1049

### Changed

- ⚠️ All tokens now use 10 fractional decimal places.
- cross-consensus messages (XCM) assume the global canonical representation for token balances.
- The token metadata in the asset registry now assumes that the existential deposit and fee factor
are stored in base 10,000,000,000.
Comment on lines +21 to +24
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be reformatted using prettier.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alignment of line 22 is intentional, it is a sub point of the one in line 21.


### Added

- Use pallet-asset-tx-payment for allowing to pay transaction fees in foreign
currencies ([#1022]). This requires each transaction to specify the fee
payment token with `asset_id` (`None` is ZTG).

## v0.3.10

[#1022]: https://github.com/zeitgeistpm/zeitgeist/pull/1022
Expand Down
68 changes: 48 additions & 20 deletions runtime/battery-station/src/integration_tests/xcm/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,41 @@ pub const PARA_ID_SIBLING: u32 = 3000;
pub const FOREIGN_ZTG_ID: Asset<u128> = CurrencyId::ForeignAsset(0);
pub const FOREIGN_PARENT_ID: Asset<u128> = CurrencyId::ForeignAsset(1);
pub const FOREIGN_SIBLING_ID: Asset<u128> = CurrencyId::ForeignAsset(2);
pub const BTC_ID: Asset<u128> = CurrencyId::ForeignAsset(3);

#[inline]
pub(super) const fn ztg(amount: Balance) -> Balance {
amount * dollar(10)
}

#[inline]
pub(super) const fn roc(amount: Balance) -> Balance {
foreign(amount, 12)
}

#[inline]
pub(super) const fn btc(amount: Balance) -> Balance {
foreign(amount, 8)
}

#[inline]
pub(super) const fn foreign(amount: Balance, decimals: u32) -> Balance {
amount * dollar(decimals)
}

#[inline]
pub(super) const fn dollar(decimals: u32) -> Balance {
10u128.saturating_pow(decimals)
}

#[inline]
pub(super) const fn adjusted_balance(foreign_base: Balance, amount: Balance) -> Balance {
if foreign_base > ztg(1) {
amount.saturating_div(foreign_base / ztg(1))
} else {
amount.saturating_mul(ztg(1) / foreign_base)
}
}

// Multilocations that are used to represent tokens from other chains
#[inline]
Expand Down Expand Up @@ -138,6 +173,19 @@ pub(super) fn register_foreign_ztg(additional_meta: Option<CustomMetadata>) {
assert_ok!(AssetRegistry::register_asset(RuntimeOrigin::root(), meta, Some(FOREIGN_ZTG_ID)));
}

pub(super) fn register_btc(additional_meta: Option<CustomMetadata>) {
let meta: AssetMetadata<Balance, CustomMetadata> = AssetMetadata {
decimals: 8,
name: "Bitcoin".into(),
symbol: "BTC".into(),
existential_deposit: ExistentialDeposit::get(),
location: Some(VersionedMultiLocation::V1(foreign_sibling_multilocation())),
additional: additional_meta.unwrap_or_default(),
};

assert_ok!(AssetRegistry::register_asset(RuntimeOrigin::root(), meta, Some(BTC_ID)));
}

pub(super) fn register_foreign_sibling(additional_meta: Option<CustomMetadata>) {
// Register native Sibling token as foreign asset.
let meta: AssetMetadata<Balance, CustomMetadata> = AssetMetadata {
Expand Down Expand Up @@ -170,26 +218,6 @@ pub(super) fn register_foreign_parent(additional_meta: Option<CustomMetadata>) {
assert_ok!(AssetRegistry::register_asset(RuntimeOrigin::root(), meta, Some(FOREIGN_PARENT_ID)));
}

#[inline]
pub(super) fn ztg(amount: Balance) -> Balance {
amount * dollar(10)
}

#[inline]
pub(super) fn roc(amount: Balance) -> Balance {
foreign(amount, 12)
}

#[inline]
pub(super) fn foreign(amount: Balance, decimals: u32) -> Balance {
amount * dollar(decimals)
}

#[inline]
pub(super) fn dollar(decimals: u32) -> Balance {
10u128.saturating_pow(decimals)
}

#[inline]
pub(super) fn sibling_parachain_account() -> AccountId {
parachain_account(PARA_ID_SIBLING)
Expand Down
145 changes: 134 additions & 11 deletions runtime/battery-station/src/integration_tests/xcm/tests/transfers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
use crate::{
integration_tests::xcm::{
setup::{
register_foreign_parent, register_foreign_ztg, roc, sibling_parachain_account,
zeitgeist_parachain_account, ztg, ALICE, BOB, FOREIGN_PARENT_ID, FOREIGN_ZTG_ID,
PARA_ID_SIBLING,
adjusted_balance, btc, register_btc, register_foreign_parent, register_foreign_ztg,
roc, sibling_parachain_account, zeitgeist_parachain_account, ztg, ALICE, BOB, BTC_ID,
FOREIGN_PARENT_ID, FOREIGN_ZTG_ID, PARA_ID_SIBLING,
},
test_net::{RococoNet, Sibling, TestNet, Zeitgeist},
},
Expand All @@ -33,7 +33,7 @@ use crate::{
use frame_support::assert_ok;
use orml_traits::MultiCurrency;
use xcm::latest::{Junction, Junction::*, Junctions::*, MultiLocation, NetworkId};
use xcm_emulator::TestExt;
use xcm_emulator::{Limited, TestExt};
use zeitgeist_primitives::{
constants::BalanceFractionalDecimals,
types::{CustomMetadata, XcmMetadata},
Expand Down Expand Up @@ -71,7 +71,7 @@ fn transfer_ztg_to_sibling() {
)
.into()
),
xcm_emulator::Limited(4_000_000_000),
Limited(4_000_000_000),
));

// Confirm that Alice's balance is initial_balance - amount_transferred
Expand Down Expand Up @@ -141,7 +141,7 @@ fn transfer_ztg_sibling_to_zeitgeist() {
)
.into()
),
xcm_emulator::Limited(4_000_000_000),
Limited(4_000_000_000),
));

// Confirm that Bobs's balance is initial balance - amount transferred
Expand Down Expand Up @@ -172,6 +172,121 @@ fn transfer_ztg_sibling_to_zeitgeist() {
});
}

#[test]
fn transfer_btc_sibling_to_zeitgeist() {
TestNet::reset();

let sibling_alice_initial_balance = ztg(10);
let zeitgeist_alice_initial_balance = btc(0);
let initial_sovereign_balance = btc(100);
let transfer_amount = btc(100);

Zeitgeist::execute_with(|| {
register_btc(None);

assert_eq!(Tokens::free_balance(BTC_ID, &ALICE), zeitgeist_alice_initial_balance,);
});

Sibling::execute_with(|| {
assert_eq!(Balances::free_balance(&ALICE), sibling_alice_initial_balance);
// Set the sovereign balance such that it is not subject to dust collection
assert_ok!(Balances::set_balance(
RuntimeOrigin::root(),
zeitgeist_parachain_account().into(),
initial_sovereign_balance,
0
));
assert_ok!(XTokens::transfer(
RuntimeOrigin::signed(ALICE),
// Target chain will interpret CurrencyId::Ztg as BTC in this context.
CurrencyId::Ztg,
transfer_amount,
Box::new(
MultiLocation::new(
1,
X2(
Parachain(battery_station::ID),
Junction::AccountId32 { network: NetworkId::Any, id: ALICE.into() }
)
)
.into()
),
Limited(4_000_000_000),
));

// Confirm that Alice's balance is initial_balance - amount_transferred
assert_eq!(Balances::free_balance(&ALICE), sibling_alice_initial_balance - transfer_amount);

// Verify that the amount transferred is now part of the zeitgeist account here
assert_eq!(
Balances::free_balance(zeitgeist_parachain_account()),
initial_sovereign_balance + transfer_amount
);
});

Zeitgeist::execute_with(|| {
let expected = transfer_amount - btc_fee();
let expected_adjusted = adjusted_balance(btc(1), expected);

// Verify that remote Alice now has initial balance + amount transferred - fee
assert_eq!(
Tokens::free_balance(BTC_ID, &ALICE),
zeitgeist_alice_initial_balance + expected_adjusted,
);
});
}

#[test]
fn transfer_btc_zeitgeist_to_sibling() {
TestNet::reset();

let transfer_amount = btc(100) - btc_fee();
let initial_sovereign_balance = 2 * btc(100);
let sibling_bob_initial_balance = btc(0);

transfer_btc_sibling_to_zeitgeist();

Sibling::execute_with(|| {
assert_eq!(Tokens::free_balance(BTC_ID, &BOB), sibling_bob_initial_balance,);
});

Zeitgeist::execute_with(|| {
assert_ok!(XTokens::transfer(
RuntimeOrigin::signed(ALICE),
BTC_ID,
transfer_amount,
Box::new(
MultiLocation::new(
1,
X2(
Parachain(PARA_ID_SIBLING),
Junction::AccountId32 { network: NetworkId::Any, id: BOB.into() }
)
)
.into()
),
Limited(4_000_000_000),
));

// Confirm that Alice's balance is initial_balance - amount_transferred
assert_eq!(Tokens::free_balance(BTC_ID, &ALICE), 0);
});

Sibling::execute_with(|| {
let fee_adjusted = adjusted_balance(btc(1), btc_fee());
let expected = transfer_amount - fee_adjusted;

// Verify that Bob now has initial balance + amount transferred - fee
assert_eq!(Balances::free_balance(&BOB), sibling_bob_initial_balance + expected,);

// Verify that the amount transferred is now subtracted from the zeitgeist account at sibling
assert_eq!(
Balances::free_balance(zeitgeist_parachain_account()),
initial_sovereign_balance - transfer_amount
);
});
}

#[test]
fn transfer_roc_from_relay_chain() {
TestNet::reset();
Expand All @@ -198,7 +313,9 @@ fn transfer_roc_from_relay_chain() {
});

Zeitgeist::execute_with(|| {
assert_eq!(Tokens::free_balance(FOREIGN_PARENT_ID, &BOB), transfer_amount - roc_fee());
let expected = transfer_amount - roc_fee();
let expected_adjusted = adjusted_balance(roc(1), expected);
assert_eq!(Tokens::free_balance(FOREIGN_PARENT_ID, &BOB), expected_adjusted);
});
}

Expand All @@ -207,6 +324,7 @@ fn transfer_roc_to_relay_chain() {
TestNet::reset();

let transfer_amount: Balance = roc(1);
let transfer_amount_local: Balance = adjusted_balance(roc(1), transfer_amount);
transfer_roc_from_relay_chain();

Zeitgeist::execute_with(|| {
Expand All @@ -224,12 +342,12 @@ fn transfer_roc_to_relay_chain() {
)
.into()
),
xcm_emulator::Limited(4_000_000_000)
Limited(4_000_000_000)
));

assert_eq!(
Tokens::free_balance(FOREIGN_PARENT_ID, &ALICE),
initial_balance - transfer_amount
initial_balance - transfer_amount_local
)
});

Expand Down Expand Up @@ -286,7 +404,7 @@ fn transfer_ztg_to_sibling_with_custom_fee() {
)
.into()
),
xcm_emulator::Limited(4_000_000_000),
Limited(4_000_000_000),
));

// Confirm that Alice's balance is initial_balance - amount_transferred
Expand Down Expand Up @@ -337,7 +455,12 @@ fn roc_fee() -> Balance {
}

#[inline]
fn calc_fee(fee_per_second: Balance) -> Balance {
fn btc_fee() -> Balance {
fee(8)
}

#[inline]
const fn calc_fee(fee_per_second: Balance) -> Balance {
// We divide the fee to align its unit and multiply by 8 as that seems to be the unit of
// time the tests take.
// NOTE: it is possible that in different machines this value may differ. We shall see.
Expand Down
Loading
Loading