diff --git a/Cargo.lock b/Cargo.lock index a7e18ef2d..564db9f5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -861,6 +861,67 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bb-bnc" +version = "0.8.0" +dependencies = [ + "bifrost-asset-registry", + "bifrost-currencies", + "bifrost-primitives", + "bifrost-runtime-common", + "bifrost-slp", + "bifrost-vtoken-minting", + "cumulus-primitives-core", + "env_logger", + "frame-benchmarking", + "frame-support", + "frame-system", + "hex-literal 0.4.1", + "log", + "orml-tokens", + "orml-traits", + "orml-xtokens", + "pallet-balances", + "pallet-collective", + "pallet-xcm", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.13.0)", + "staging-xcm", + "staging-xcm-builder", + "staging-xcm-executor", +] + +[[package]] +name = "bb-bnc-rpc" +version = "0.8.0" +dependencies = [ + "bb-bnc-rpc-runtime-api", + "bifrost-primitives", + "jsonrpsee", + "parity-scale-codec", + "serde", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-rpc", + "sp-runtime", +] + +[[package]] +name = "bb-bnc-rpc-runtime-api" +version = "0.8.0" +dependencies = [ + "bifrost-primitives", + "parity-scale-codec", + "sp-api", + "sp-core", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.13.0)", +] + [[package]] name = "beef" version = "0.5.2" @@ -895,11 +956,12 @@ dependencies = [ name = "bifrost-buy-back" version = "0.8.0" dependencies = [ + "bb-bnc", "bifrost-asset-registry", "bifrost-currencies", "bifrost-primitives", + "bifrost-runtime-common", "bifrost-slp", - "bifrost-ve-minting", "bifrost-vtoken-minting", "cumulus-primitives-core", "env_logger", @@ -926,25 +988,6 @@ dependencies = [ "zenlink-protocol", ] -[[package]] -name = "bifrost-call-switchgear" -version = "0.8.0" -dependencies = [ - "bifrost-primitives", - "frame-benchmarking", - "frame-support", - "frame-system", - "orml-tokens", - "orml-traits", - "pallet-balances", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.13.0)", -] - [[package]] name = "bifrost-channel-commission" version = "0.8.0" @@ -968,7 +1011,7 @@ dependencies = [ [[package]] name = "bifrost-cli" -version = "0.12.1" +version = "0.13.0" dependencies = [ "bifrost-primitives", "bifrost-service", @@ -1002,10 +1045,10 @@ dependencies = [ name = "bifrost-clouds-convert" version = "0.8.0" dependencies = [ + "bb-bnc", "bifrost-asset-registry", "bifrost-currencies", "bifrost-primitives", - "bifrost-ve-minting", "frame-benchmarking", "frame-support", "frame-system", @@ -1065,11 +1108,11 @@ dependencies = [ name = "bifrost-farming" version = "0.8.0" dependencies = [ + "bb-bnc", "bifrost-asset-registry", "bifrost-currencies", "bifrost-primitives", "bifrost-runtime-common", - "bifrost-ve-minting", "env_logger", "frame-benchmarking", "frame-support", @@ -1128,15 +1171,19 @@ dependencies = [ "bifrost-slp", "bifrost-vtoken-minting", "cumulus-primitives-core", + "env_logger", "frame-benchmarking", "frame-support", "frame-system", "hex-literal 0.4.1", "log", + "orml-oracle", "orml-tokens", "orml-traits", "orml-xtokens", "pallet-balances", + "pallet-prices", + "pallet-traits", "pallet-xcm", "parity-scale-codec", "scale-info", @@ -1286,6 +1333,7 @@ dependencies = [ "bifrost-system-maker", "bifrost-system-staking", "bifrost-token-issuer", + "bifrost-vbnc-convert", "bifrost-vesting", "bifrost-vsbond-auction", "bifrost-vstoken-conversion", @@ -1342,6 +1390,7 @@ dependencies = [ "pallet-referenda", "pallet-scheduler", "pallet-session", + "pallet-staking", "pallet-timestamp", "pallet-tips", "pallet-transaction-payment", @@ -1417,6 +1466,8 @@ dependencies = [ name = "bifrost-polkadot-runtime" version = "0.8.0" dependencies = [ + "bb-bnc", + "bb-bnc-rpc-runtime-api", "bifrost-asset-registry", "bifrost-buy-back", "bifrost-channel-commission", @@ -1433,14 +1484,13 @@ dependencies = [ "bifrost-salp", "bifrost-salp-rpc-runtime-api", "bifrost-slp", + "bifrost-slp-v2", "bifrost-slpx", "bifrost-stable-asset", "bifrost-stable-pool", "bifrost-stable-pool-rpc-runtime-api", "bifrost-system-maker", "bifrost-system-staking", - "bifrost-ve-minting", - "bifrost-ve-minting-rpc-runtime-api", "bifrost-vesting", "bifrost-vstoken-conversion", "bifrost-vtoken-minting", @@ -1518,6 +1568,7 @@ dependencies = [ "pallet-referenda", "pallet-scheduler", "pallet-session", + "pallet-staking", "pallet-timestamp", "pallet-tips", "pallet-traits", @@ -1572,6 +1623,7 @@ dependencies = [ "bstringify", "frame-support", "orml-oracle", + "orml-traits", "parity-scale-codec", "scale-info", "serde", @@ -1587,6 +1639,8 @@ dependencies = [ name = "bifrost-rpc" version = "0.8.0" dependencies = [ + "bb-bnc-rpc", + "bb-bnc-rpc-runtime-api", "bifrost-farming-rpc", "bifrost-farming-rpc-runtime-api", "bifrost-flexible-fee-rpc", @@ -1598,8 +1652,6 @@ dependencies = [ "bifrost-salp-rpc-runtime-api", "bifrost-stable-pool-rpc", "bifrost-stable-pool-rpc-runtime-api", - "bifrost-ve-minting-rpc", - "bifrost-ve-minting-rpc-runtime-api", "bifrost-vtoken-minting-rpc", "bifrost-vtoken-minting-rpc-runtime-api", "cumulus-primitives-core", @@ -1768,6 +1820,7 @@ name = "bifrost-service" version = "0.8.0" dependencies = [ "async-trait", + "bb-bnc-rpc-runtime-api", "bifrost-farming-rpc-runtime-api", "bifrost-flexible-fee-rpc-runtime-api", "bifrost-kusama-runtime", @@ -1777,7 +1830,6 @@ dependencies = [ "bifrost-rpc", "bifrost-runtime-common", "bifrost-salp-rpc-runtime-api", - "bifrost-ve-minting-rpc-runtime-api", "clap", "cumulus-client-cli", "cumulus-client-collator", @@ -1904,6 +1956,36 @@ dependencies = [ "staging-xcm-executor", ] +[[package]] +name = "bifrost-slp-v2" +version = "0.0.0" +dependencies = [ + "bifrost-asset-registry", + "bifrost-currencies", + "bifrost-primitives", + "bifrost-vtoken-minting", + "cumulus-primitives-core", + "frame-benchmarking", + "frame-support", + "frame-system", + "hex-literal 0.4.1", + "orml-tokens", + "orml-traits", + "pallet-balances", + "pallet-utility", + "pallet-xcm", + "parity-scale-codec", + "polkadot-parachain-primitives", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.13.0)", + "staging-xcm", + "staging-xcm-builder", + "staging-xcm-executor", +] + [[package]] name = "bifrost-slpx" version = "0.8.0" @@ -2118,64 +2200,25 @@ dependencies = [ ] [[package]] -name = "bifrost-ve-minting" +name = "bifrost-vbnc-convert" version = "0.8.0" dependencies = [ "bifrost-asset-registry", "bifrost-currencies", "bifrost-primitives", - "bifrost-runtime-common", - "bifrost-slp", - "bifrost-vtoken-minting", - "cumulus-primitives-core", - "env_logger", "frame-benchmarking", "frame-support", "frame-system", - "hex-literal 0.4.1", - "log", "orml-tokens", "orml-traits", - "orml-xtokens", "pallet-balances", - "pallet-collective", - "pallet-xcm", "parity-scale-codec", "scale-info", "sp-core", "sp-io", "sp-runtime", "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.13.0)", - "staging-xcm", "staging-xcm-builder", - "staging-xcm-executor", -] - -[[package]] -name = "bifrost-ve-minting-rpc" -version = "0.8.0" -dependencies = [ - "bifrost-primitives", - "bifrost-ve-minting-rpc-runtime-api", - "jsonrpsee", - "parity-scale-codec", - "serde", - "sp-api", - "sp-blockchain", - "sp-core", - "sp-rpc", - "sp-runtime", -] - -[[package]] -name = "bifrost-ve-minting-rpc-runtime-api" -version = "0.8.0" -dependencies = [ - "bifrost-primitives", - "parity-scale-codec", - "sp-api", - "sp-core", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.13.0)", ] [[package]] @@ -2243,12 +2286,12 @@ dependencies = [ name = "bifrost-vtoken-minting" version = "0.8.0" dependencies = [ + "bb-bnc", "bifrost-asset-registry", "bifrost-currencies", "bifrost-primitives", "bifrost-runtime-common", "bifrost-slp", - "bifrost-ve-minting", "cumulus-primitives-core", "env_logger", "frame-benchmarking", @@ -9049,6 +9092,7 @@ dependencies = [ "scale-info", "sp-core", "sp-io", + "sp-runtime", "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.13.0)", ] @@ -11934,9 +11978,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -14192,9 +14236,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.205" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -14210,9 +14254,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.205" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -14221,12 +14265,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.122" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", - "memchr", "ryu", "serde", ] @@ -14901,7 +14944,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" version = "0.10.0" -source = "git+https://github.com/paritytech/polkadot-sdk#604f56f03db847a90aa4fdb13be6b80482a4dcd6" +source = "git+https://github.com/paritytech/polkadot-sdk#016421ac71574333da92a56ef7bcbef8621ccc14" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -14963,7 +15006,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#604f56f03db847a90aa4fdb13be6b80482a4dcd6" +source = "git+https://github.com/paritytech/polkadot-sdk#016421ac71574333da92a56ef7bcbef8621ccc14" dependencies = [ "proc-macro2", "quote", @@ -14983,7 +15026,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.25.0" -source = "git+https://github.com/paritytech/polkadot-sdk#604f56f03db847a90aa4fdb13be6b80482a4dcd6" +source = "git+https://github.com/paritytech/polkadot-sdk#016421ac71574333da92a56ef7bcbef8621ccc14" dependencies = [ "environmental", "parity-scale-codec", @@ -15199,7 +15242,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "24.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#604f56f03db847a90aa4fdb13be6b80482a4dcd6" +source = "git+https://github.com/paritytech/polkadot-sdk#016421ac71574333da92a56ef7bcbef8621ccc14" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -15231,7 +15274,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#604f56f03db847a90aa4fdb13be6b80482a4dcd6" +source = "git+https://github.com/paritytech/polkadot-sdk#016421ac71574333da92a56ef7bcbef8621ccc14" dependencies = [ "Inflector", "expander", @@ -15320,7 +15363,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#604f56f03db847a90aa4fdb13be6b80482a4dcd6" +source = "git+https://github.com/paritytech/polkadot-sdk#016421ac71574333da92a56ef7bcbef8621ccc14" [[package]] name = "sp-storage" @@ -15337,7 +15380,7 @@ dependencies = [ [[package]] name = "sp-storage" version = "19.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#604f56f03db847a90aa4fdb13be6b80482a4dcd6" +source = "git+https://github.com/paritytech/polkadot-sdk#016421ac71574333da92a56ef7bcbef8621ccc14" dependencies = [ "impl-serde", "parity-scale-codec", @@ -15372,7 +15415,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#604f56f03db847a90aa4fdb13be6b80482a4dcd6" +source = "git+https://github.com/paritytech/polkadot-sdk#016421ac71574333da92a56ef7bcbef8621ccc14" dependencies = [ "parity-scale-codec", "tracing", @@ -15469,8 +15512,9 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "20.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#604f56f03db847a90aa4fdb13be6b80482a4dcd6" +source = "git+https://github.com/paritytech/polkadot-sdk#016421ac71574333da92a56ef7bcbef8621ccc14" dependencies = [ + "anyhow", "impl-trait-for-tuples", "log", "parity-scale-codec", @@ -16579,6 +16623,7 @@ dependencies = [ "sharded-slab", "smallvec", "thread_local", + "time", "tracing", "tracing-core", "tracing-log", diff --git a/Cargo.toml b/Cargo.toml index 9615cbc61..e2b412274 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,11 +15,11 @@ members = [ "pallets/token-issuer", "pallets/vesting", "pallets/vsbond-auction", - "pallets/call-switchgear", "pallets/cross-in-out", "pallets/evm-accounts", "pallets/xcm-interface", "pallets/slp", + "pallets/slp-v2", "pallets/vstoken-conversion", "pallets/vtoken-minting", "pallets/vtoken-voting", @@ -27,13 +27,14 @@ members = [ "pallets/system-maker", "pallets/fee-share", "pallets/parachain-staking", - "pallets/ve-minting", + "pallets/bb-bnc", "pallets/stable-pool", "pallets/lend-market", "pallets/prices", "pallets/leverage-staking", "pallets/channel-commission", "pallets/clouds-convert", + "pallets/vbnc-convert", "runtime/bifrost-kusama", "runtime/bifrost-polkadot/src/evm/evm-utility/macro", @@ -52,7 +53,7 @@ bifrost-flexible-fee-rpc = { path = "pallets/flexible-fee/rpc" } bifrost-rpc = { path = "node/rpc" } bifrost-salp-rpc = { path = "pallets/salp/rpc" } bifrost-stable-pool-rpc = { path = "pallets/stable-pool/rpc" } -bifrost-ve-minting-rpc = { path = "pallets/ve-minting/rpc" } +bb-bnc-rpc = { path = "pallets/bb-bnc/rpc" } lend-market-rpc = { path = "pallets/lend-market/rpc" } bifrost-vtoken-minting-rpc = { path = "pallets/vtoken-minting/rpc" } @@ -79,6 +80,7 @@ bifrost-salp = { path = "pallets/salp", default-featur bifrost-salp-rpc-runtime-api = { path = "pallets/salp/rpc/runtime-api", default-features = false } bifrost-service = { path = "node/service", default-features = false } bifrost-slp = { path = "pallets/slp", default-features = false } +bifrost-slp-v2 = { path = "pallets/slp-v2", default-features = false } bifrost-slpx = { path = "pallets/slpx", default-features = false } bifrost-stable-asset = { path = "pallets/stable-asset", default-features = false } bifrost-stable-pool = { path = "pallets/stable-pool", default-features = false } @@ -86,8 +88,9 @@ bifrost-stable-pool-rpc-runtime-api = { path = "pallets/stable-pool/rpc/runti bifrost-system-maker = { path = "pallets/system-maker", default-features = false } bifrost-system-staking = { path = "pallets/system-staking", default-features = false } bifrost-token-issuer = { path = "pallets/token-issuer", default-features = false } -bifrost-ve-minting = { path = "pallets/ve-minting", default-features = false } -bifrost-ve-minting-rpc-runtime-api = { path = "pallets/ve-minting/rpc/runtime-api", default-features = false } +bifrost-vbnc-convert = { path = "pallets/vbnc-convert", default-features = false } +bb-bnc = { path = "pallets/bb-bnc", default-features = false } +bb-bnc-rpc-runtime-api = { path = "pallets/bb-bnc/rpc/runtime-api", default-features = false } bifrost-vesting = { path = "pallets/vesting", default-features = false } bifrost-vsbond-auction = { path = "pallets/vsbond-auction", default-features = false } bifrost-vstoken-conversion = { path = "pallets/vstoken-conversion", default-features = false } @@ -330,7 +333,7 @@ proc-macro2 = { version = "1.0.40" } quote = { version = "1.0.20" } scale-info = { version = "2.11.3", default-features = false } serde = { version = "1.0.205", default-features = false } -serde_json = { version = "1.0.122", default-features = false } +serde_json = { version = "1.0.120", default-features = false } sha3 = { version = "0.10.6", default-features = false } similar-asserts = { version = "1.1.0" } smallvec = { version = "1.13.1" } diff --git a/Makefile b/Makefile index 85bae2f33..121749f9c 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ format-check: .PHONY: clippy # cargo clippy clippy: format-check - SKIP_WASM_BUILD= cargo clippy --all --all-targets --features=with-all-runtime -- -D warnings + cargo clippy --all --all-targets --features "with-all-runtime,runtime-benchmarks,try-runtime" -- -D warnings .PHONY: benchmarking-staking # benchmarking staking pallet benchmarking-staking: diff --git a/docs/res/readme/bifrost-banner.svg b/docs/res/readme/bifrost-banner.svg new file mode 100644 index 000000000..34325bff2 --- /dev/null +++ b/docs/res/readme/bifrost-banner.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/res/readme/bifrost-black-logo.svg b/docs/res/readme/bifrost-black-logo.svg new file mode 100644 index 000000000..b70dfd53e --- /dev/null +++ b/docs/res/readme/bifrost-black-logo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/res/readme/substrate-builder.svg b/docs/res/readme/substrate-builder.svg new file mode 100644 index 000000000..1eead6316 --- /dev/null +++ b/docs/res/readme/substrate-builder.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/docs/res/readme/web3-bootcamp.svg b/docs/res/readme/web3-bootcamp.svg new file mode 100644 index 000000000..7fb3bb0c8 --- /dev/null +++ b/docs/res/readme/web3-bootcamp.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/docs/res/readme/web3-foundation-grant.svg b/docs/res/readme/web3-foundation-grant.svg new file mode 100644 index 000000000..1b8d7ffc7 --- /dev/null +++ b/docs/res/readme/web3-foundation-grant.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/integration-tests/src/mock/bifrost.rs b/integration-tests/src/mock/bifrost.rs index 5a116eba1..915cb879b 100644 --- a/integration-tests/src/mock/bifrost.rs +++ b/integration-tests/src/mock/bifrost.rs @@ -29,15 +29,14 @@ use sp_std::prelude::*; use crate::mock::{mock_message_queue, Amount}; use bifrost_asset_registry::AssetIdMaps; use bifrost_polkadot_runtime::{ - xcm_config::{ - BaseXcmWeight, BifrostAccountIdToLocation, BifrostAssetTransactor, MaxAssetsForTransfer, - ParachainMinFee, SelfRelativeLocation, UniversalLocation, - }, - BifrostCurrencyIdConvert, BifrostTreasuryAccount, MaxLengthLimit, MaxRefundPerBlock, - MaxTypeEntryPerBlock, NativeCurrencyId, SelfParaChainId, SubAccountIndexMultiLocationConvertor, - VtokenMinting, XcmInterface, + xcm_config::{BaseXcmWeight, BifrostAssetTransactor, MaxAssetsForTransfer, ParachainMinFee}, + BifrostTreasuryAccount, MaxLengthLimit, MaxRefundPerBlock, MaxTypeEntryPerBlock, + NativeCurrencyId, SubAccountIndexMultiLocationConvertor, VtokenMinting, XcmInterface, }; -use bifrost_primitives::CurrencyId; +use bifrost_primitives::{ + AccountIdToLocation, CurrencyId, PolkadotUniversalLocation, SelfLocation, +}; +use bifrost_runtime_common::currency_converter::CurrencyIdConvert; use bifrost_slp::QueryResponseManager; use pallet_xcm::{QueryStatus, XcmPassthrough}; use polkadot_parachain_primitives::primitives::Sibling; @@ -118,15 +117,15 @@ impl orml_xtokens::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type CurrencyId = CurrencyId; - type CurrencyIdConvert = BifrostCurrencyIdConvert; - type AccountIdToLocation = BifrostAccountIdToLocation; - type SelfLocation = SelfRelativeLocation; + type CurrencyIdConvert = CurrencyIdConvert; + type AccountIdToLocation = AccountIdToLocation; + type SelfLocation = SelfLocation; type LocationsFilter = Everything; type MinXcmFee = ParachainMinFee; type XcmExecutor = XcmExecutor; type Weigher = FixedWeightBounds; type BaseXcmWeight = BaseXcmWeight; - type UniversalLocation = UniversalLocation; + type UniversalLocation = PolkadotUniversalLocation; type MaxAssetsForTransfer = MaxAssetsForTransfer; type ReserveProvider = RelativeReserveProvider; type RateLimiter = (); @@ -173,7 +172,7 @@ impl Config for XcmConfig { type OriginConverter = XcmOriginToCallOrigin; type IsReserve = NativeAsset; type IsTeleporter = (); - type UniversalLocation = UniversalLocation; + type UniversalLocation = PolkadotUniversalLocation; type Barrier = Barrier; type Weigher = FixedWeightBounds; type Trader = FixedRateOfFungible; @@ -215,7 +214,7 @@ impl pallet_xcm::Config for Runtime { type XcmTeleportFilter = Nothing; type XcmReserveTransferFilter = Everything; type Weigher = FixedWeightBounds; - type UniversalLocation = UniversalLocation; + type UniversalLocation = PolkadotUniversalLocation; type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; @@ -298,7 +297,7 @@ impl bifrost_slp::Config for Runtime { type WeightInfo = (); type VtokenMinting = VtokenMinting; type AccountConverter = SubAccountIndexMultiLocationConvertor; - type ParachainId = SelfParaChainId; + type ParachainId = ParachainInfo; type SubstrateResponseManager = SubstrateResponseManager; type MaxTypeEntryPerBlock = MaxTypeEntryPerBlock; type MaxRefundPerBlock = MaxRefundPerBlock; diff --git a/integration-tests/src/mock/mod.rs b/integration-tests/src/mock/mod.rs index d7423adf0..52aa34ef9 100644 --- a/integration-tests/src/mock/mod.rs +++ b/integration-tests/src/mock/mod.rs @@ -62,6 +62,7 @@ decl_test_network! { pub type BifrostTokens = orml_tokens::Pallet; pub type BifrostXTokens = orml_xtokens::Pallet; pub type BifrostSlp = bifrost_slp::Pallet; +pub type BifrostAssetRegistry = bifrost_asset_registry::Pallet; pub type RelayBalances = pallet_balances::Pallet; pub type RelaySystem = frame_system::Pallet; @@ -72,6 +73,15 @@ pub fn para_ext(para_id: u32) -> TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + bifrost_asset_registry::GenesisConfig:: { + currency: vec![(CurrencyId::Token2(0), 1_000_000, None)], + vcurrency: vec![], + vsbond: vec![], + phantom: Default::default(), + } + .assimilate_storage(&mut t) + .unwrap(); + orml_tokens::GenesisConfig:: { balances: vec![(ALICE, CurrencyId::Token2(0), 100_000_000_000)], } diff --git a/integration-tests/src/mock/relaychain.rs b/integration-tests/src/mock/relaychain.rs index 7ae78ad3f..57bc0358c 100644 --- a/integration-tests/src/mock/relaychain.rs +++ b/integration-tests/src/mock/relaychain.rs @@ -17,7 +17,7 @@ // along with this program. If not, see . use bifrost_polkadot_runtime::{ - xcm_config, BlockHashCount, Hash, Nonce, ReservedDmpWeight, ReservedXcmpWeight, + BlockHashCount, Hash, Nonce, RelayOrigin, ReservedDmpWeight, ReservedXcmpWeight, RuntimeBlockLength, RuntimeBlockWeights, SS58Prefix, Version, XcmpQueue, }; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; @@ -71,7 +71,7 @@ impl frame_system::Config for Runtime { impl cumulus_pallet_parachain_system::Config for Runtime { type DmpQueue = frame_support::traits::EnqueueWithOrigin< bifrost_polkadot_runtime::MessageQueue, - xcm_config::RelayOrigin, + RelayOrigin, >; type RuntimeEvent = RuntimeEvent; type OnSystemEvent = (); diff --git a/integration-tests/src/tests/send_relay_chain_asset.rs b/integration-tests/src/tests/send_relay_chain_asset.rs index 86e14aaf3..61b621bf5 100644 --- a/integration-tests/src/tests/send_relay_chain_asset.rs +++ b/integration-tests/src/tests/send_relay_chain_asset.rs @@ -17,7 +17,8 @@ // along with this program. If not, see . use crate::mock::{ - Bifrost, BifrostTokens, BifrostXTokens, Relay, RelayBalances, RelaySystem, TestNet, ALICE, BOB, + Bifrost, BifrostAssetRegistry, BifrostTokens, BifrostXTokens, Relay, RelayBalances, + RelaySystem, TestNet, ALICE, BOB, }; use bifrost_primitives::CurrencyId; use cumulus_primitives_core::ParaId; @@ -39,6 +40,10 @@ fn send_relay_chain_asset_to_relay_chain() { }); Bifrost::execute_with(|| { + assert_ok!(BifrostAssetRegistry::do_register_location( + CurrencyId::Token2(0), + &Location::parent() + )); assert_ok!(BifrostXTokens::transfer( Some(ALICE).into(), CurrencyId::Token2(0), diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index c30589326..1adb0e8fb 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bifrost-cli" -version = "0.12.1" +version = "0.13.0" authors = ["Liebi Technologies "] description = "Bifrost Parachain Node" build = "build.rs" diff --git a/node/rpc/Cargo.toml b/node/rpc/Cargo.toml index 1254c4fdd..8ada17b5b 100644 --- a/node/rpc/Cargo.toml +++ b/node/rpc/Cargo.toml @@ -44,8 +44,8 @@ bifrost-salp-rpc = { workspace = true } bifrost-salp-rpc-runtime-api = { workspace = true } bifrost-farming-rpc = { workspace = true } bifrost-farming-rpc-runtime-api = { workspace = true } -bifrost-ve-minting-rpc = { workspace = true } -bifrost-ve-minting-rpc-runtime-api = { workspace = true } +bb-bnc-rpc = { workspace = true } +bb-bnc-rpc-runtime-api = { workspace = true } bifrost-stable-pool-rpc = { workspace = true } bifrost-stable-pool-rpc-runtime-api = { workspace = true } lend-market-rpc = { workspace = true } diff --git a/node/rpc/src/lib.rs b/node/rpc/src/lib.rs index 41dc9059b..1bfb4d3cd 100644 --- a/node/rpc/src/lib.rs +++ b/node/rpc/src/lib.rs @@ -33,6 +33,8 @@ use std::sync::Arc; +use bb_bnc_rpc::{BbBNCRpc, BbBNCRpcApiServer}; +use bb_bnc_rpc_runtime_api::BbBNCRuntimeApi; use bifrost_farming_rpc::{FarmingRpc, FarmingRpcApiServer}; use bifrost_farming_rpc_runtime_api::FarmingRuntimeApi; use bifrost_flexible_fee_rpc::{FeeRpcApiServer, FlexibleFeeRpc}; @@ -43,8 +45,6 @@ use bifrost_salp_rpc::{SalpRpc, SalpRpcApiServer}; use bifrost_salp_rpc_runtime_api::SalpRuntimeApi; use bifrost_stable_pool_rpc::{StablePoolRpc, StablePoolRpcApiServer}; use bifrost_stable_pool_rpc_runtime_api::StablePoolRuntimeApi; -use bifrost_ve_minting_rpc::{VeMintingRpc, VeMintingRpcApiServer}; -use bifrost_ve_minting_rpc_runtime_api::VeMintingRuntimeApi; use bifrost_vtoken_minting_rpc::{VtokenMintingRpc, VtokenMintingRpcApiServer}; use bifrost_vtoken_minting_rpc_runtime_api::VtokenMintingRuntimeApi; use futures::channel::mpsc; @@ -152,7 +152,7 @@ where C::Api: FarmingRuntimeApi, C::Api: FeeRuntimeApi, C::Api: SalpRuntimeApi, - C::Api: VeMintingRuntimeApi, + C::Api: BbBNCRuntimeApi, C::Api: LendMarketApi, C::Api: VtokenMintingRuntimeApi, C::Api: ZenlinkProtocolRuntimeApi, @@ -169,7 +169,7 @@ where module.merge(FarmingRpc::new(client.clone()).into_rpc())?; module.merge(FlexibleFeeRpc::new(client.clone()).into_rpc())?; module.merge(SalpRpc::new(client.clone()).into_rpc())?; - module.merge(VeMintingRpc::new(client.clone()).into_rpc())?; + module.merge(BbBNCRpc::new(client.clone()).into_rpc())?; module.merge(ZenlinkProtocol::new(client.clone()).into_rpc())?; module.merge(StablePoolRpc::new(client.clone()).into_rpc())?; module.merge(LendMarket::new(client.clone()).into_rpc())?; diff --git a/node/service/Cargo.toml b/node/service/Cargo.toml index 74e8f9ac3..64b512682 100644 --- a/node/service/Cargo.toml +++ b/node/service/Cargo.toml @@ -124,7 +124,7 @@ fp-rpc = { workspace = true, features = ["default"] } bifrost-flexible-fee-rpc-runtime-api = { workspace = true } bifrost-salp-rpc-runtime-api = { workspace = true } bifrost-farming-rpc-runtime-api = { workspace = true } -bifrost-ve-minting-rpc-runtime-api = { workspace = true } +bb-bnc-rpc-runtime-api = { workspace = true } [features] default = [ "std" ] diff --git a/node/service/src/chain_spec/bifrost_kusama.rs b/node/service/src/chain_spec/bifrost_kusama.rs index bd7c17202..ba38b8ab7 100644 --- a/node/service/src/chain_spec/bifrost_kusama.rs +++ b/node/service/src/chain_spec/bifrost_kusama.rs @@ -16,11 +16,14 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +use crate::chain_spec::{get_account_id_from_seed, get_from_seed, RelayExtensions}; use bifrost_kusama_runtime::{ constants::currency::DOLLARS, AccountId, Balance, BalancesConfig, BlockNumber, DefaultBlocksPerRound, InflationInfo, Range, SS58Prefix, VestingConfig, }; -use bifrost_primitives::{CurrencyId, CurrencyId::*, TokenInfo, TokenSymbol::*}; +use bifrost_primitives::{ + BifrostKusamaChainId, CurrencyId, CurrencyId::*, TokenInfo, TokenSymbol::*, +}; use bifrost_runtime_common::AuraId; use cumulus_primitives_core::ParaId; use frame_benchmarking::{account, whitelisted_caller}; @@ -37,8 +40,6 @@ use std::{ path::PathBuf, }; -use crate::chain_spec::{get_account_id_from_seed, get_from_seed, RelayExtensions}; - const DEFAULT_PROTOCOL_ID: &str = "bifrost"; /// Specialized `ChainSpec` for the bifrost runtime. @@ -49,8 +50,6 @@ pub fn ENDOWMENT() -> u128 { 1_000_000 * DOLLARS } -pub const PARA_ID: u32 = 2001; - pub fn inflation_config() -> InflationInfo { fn to_round_inflation(annual: Range) -> Range { use bifrost_parachain_staking::inflation::{ @@ -219,7 +218,11 @@ pub fn local_testnet_config() -> ChainSpec { ChainSpec::builder( bifrost_kusama_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), - RelayExtensions { relay_chain: "kusama-local".into(), para_id: PARA_ID, evm_since: 1 }, + RelayExtensions { + relay_chain: "kusama-local".into(), + para_id: BifrostKusamaChainId::get(), + evm_since: 1, + }, ) .with_name("Bifrost Local Testnet") .with_id("bifrost_local_testnet") @@ -240,7 +243,7 @@ pub fn local_testnet_config() -> ChainSpec { vec![], balances, vestings, - PARA_ID.into(), + BifrostKusamaChainId::get().into(), council_membership, technical_committee_membership, salp_multisig, @@ -325,7 +328,11 @@ pub fn chainspec_config() -> ChainSpec { ChainSpec::builder( bifrost_kusama_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), - RelayExtensions { relay_chain: "kusama".into(), para_id: PARA_ID, evm_since: 1 }, + RelayExtensions { + relay_chain: "kusama".into(), + para_id: BifrostKusamaChainId::get(), + evm_since: 1, + }, ) .with_name("Bifrost") .with_id("bifrost") @@ -335,7 +342,7 @@ pub fn chainspec_config() -> ChainSpec { vec![], balances, vesting_configs.into_iter().flat_map(|vc| vc.vesting).collect(), - PARA_ID.into(), + BifrostKusamaChainId::get().into(), vec![], // council membership vec![], // technical committee membership salp_multisig, diff --git a/node/service/src/chain_spec/bifrost_polkadot.rs b/node/service/src/chain_spec/bifrost_polkadot.rs index ee486a4f3..b52070fe5 100644 --- a/node/service/src/chain_spec/bifrost_polkadot.rs +++ b/node/service/src/chain_spec/bifrost_polkadot.rs @@ -22,7 +22,7 @@ use bifrost_polkadot_runtime::{ }; use bifrost_primitives::{ currency::{BNCS, DED, IBTC, INTR, PEN, PINK, USDC, WETH}, - CurrencyId, + BifrostPolkadotChainId, CurrencyId, CurrencyId::*, TokenInfo, TokenSymbol, ASTR, BNC, DOT, DOT_TOKEN_ID, DOT_U, FIL, GLMR, MANTA, }; @@ -47,8 +47,6 @@ pub fn ENDOWMENT() -> u128 { 1_000_000 * DOLLARS } -pub const PARA_ID: u32 = 2030; - fn bifrost_polkadot_properties() -> Properties { let mut properties = sc_chain_spec::Properties::new(); let mut token_symbol: Vec = vec![]; @@ -227,7 +225,11 @@ pub fn local_testnet_config() -> ChainSpec { ChainSpec::builder( bifrost_polkadot_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), - RelayExtensions { relay_chain: "polkadot-local".into(), para_id: PARA_ID, evm_since: 1 }, + RelayExtensions { + relay_chain: "polkadot-local".into(), + para_id: BifrostPolkadotChainId::get(), + evm_since: 1, + }, ) .with_name("Bifrost Polkadot Local Testnet") .with_id("bifrost_polkadot_local_testnet") @@ -242,7 +244,7 @@ pub fn local_testnet_config() -> ChainSpec { ], balances, vec![], - PARA_ID.into(), + BifrostPolkadotChainId::get().into(), tokens, council_membership, technical_committee_membership, @@ -336,7 +338,11 @@ pub fn dev_config() -> ChainSpec { ChainSpec::builder( bifrost_polkadot_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), - RelayExtensions { relay_chain: "polkadot".into(), para_id: PARA_ID, evm_since: 1 }, + RelayExtensions { + relay_chain: "polkadot".into(), + para_id: BifrostPolkadotChainId::get(), + evm_since: 1, + }, ) .with_name("Bifrost Polkadot Dev Testnet") .with_id("dev") @@ -351,7 +357,7 @@ pub fn dev_config() -> ChainSpec { ], balances, vec![], - PARA_ID.into(), + BifrostPolkadotChainId::get().into(), tokens, council_membership, technical_committee_membership, @@ -425,7 +431,11 @@ pub fn paseo_config() -> ChainSpec { ChainSpec::builder( bifrost_polkadot_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), - RelayExtensions { relay_chain: "paseo".into(), para_id: PARA_ID, evm_since: 1 }, + RelayExtensions { + relay_chain: "paseo".into(), + para_id: BifrostPolkadotChainId::get(), + evm_since: 1, + }, ) .with_name("Bifrost Paseo") .with_id("bifrost_paseo") @@ -434,7 +444,7 @@ pub fn paseo_config() -> ChainSpec { invulnerables, balances, vec![], - PARA_ID.into(), + BifrostPolkadotChainId::get().into(), vec![], council_membership, technical_committee_membership, @@ -480,7 +490,11 @@ pub fn chainspec_config() -> ChainSpec { ChainSpec::builder( bifrost_polkadot_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), - RelayExtensions { relay_chain: "polkadot".into(), para_id: PARA_ID, evm_since: 1 }, + RelayExtensions { + relay_chain: "polkadot".into(), + para_id: BifrostPolkadotChainId::get(), + evm_since: 1, + }, ) .with_name("Bifrost Polkadot") .with_id("bifrost_polkadot") @@ -489,7 +503,7 @@ pub fn chainspec_config() -> ChainSpec { invulnerables, vec![], vec![], - PARA_ID.into(), + BifrostPolkadotChainId::get().into(), vec![], vec![], vec![], diff --git a/pallets/asset-registry/src/benchmarking.rs b/pallets/asset-registry/src/benchmarking.rs index 309065886..bb7b63b13 100644 --- a/pallets/asset-registry/src/benchmarking.rs +++ b/pallets/asset-registry/src/benchmarking.rs @@ -232,12 +232,12 @@ benchmarks! { }: {call.dispatch_bypass_filter(origin)?} verify { assert_eq!( - LocationToCurrencyIds::::get(location.clone()), + LocationToCurrencyIds::::get(location), Some(Token2(0)) ); assert_eq!( CurrencyIdToLocations::::get(Token2(0)), - Some(location.clone()) + Some(location) ); assert_eq!(CurrencyIdToWeights::::get(Token2(0)), Some(Weight::from_parts(2000_000_000, u64::MAX))); } diff --git a/pallets/ve-minting/Cargo.toml b/pallets/bb-bnc/Cargo.toml similarity index 98% rename from pallets/ve-minting/Cargo.toml rename to pallets/bb-bnc/Cargo.toml index 122c7a7fa..2b9f27443 100644 --- a/pallets/ve-minting/Cargo.toml +++ b/pallets/bb-bnc/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "bifrost-ve-minting" +name = "bb-bnc" version = "0.8.0" authors = ["Kadokura "] edition = "2021" diff --git a/pallets/ve-minting/rpc/Cargo.toml b/pallets/bb-bnc/rpc/Cargo.toml similarity index 84% rename from pallets/ve-minting/rpc/Cargo.toml rename to pallets/bb-bnc/rpc/Cargo.toml index aa9fcb7ba..578fd700f 100644 --- a/pallets/ve-minting/rpc/Cargo.toml +++ b/pallets/bb-bnc/rpc/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "bifrost-ve-minting-rpc" +name = "bb-bnc-rpc" version = "0.8.0" authors = ["Kadokura "] edition = "2021" @@ -14,4 +14,4 @@ sp-blockchain = { workspace = true } sp-core = { workspace = true } sp-rpc = { workspace = true } bifrost-primitives = { workspace = true } -bifrost-ve-minting-rpc-runtime-api = { workspace = true } +bb-bnc-rpc-runtime-api = { workspace = true } diff --git a/pallets/ve-minting/rpc/runtime-api/Cargo.toml b/pallets/bb-bnc/rpc/runtime-api/Cargo.toml similarity index 90% rename from pallets/ve-minting/rpc/runtime-api/Cargo.toml rename to pallets/bb-bnc/rpc/runtime-api/Cargo.toml index afd1c5015..4ec16fe07 100644 --- a/pallets/ve-minting/rpc/runtime-api/Cargo.toml +++ b/pallets/bb-bnc/rpc/runtime-api/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "bifrost-ve-minting-rpc-runtime-api" +name = "bb-bnc-rpc-runtime-api" version = "0.8.0" authors = ["Kadokura "] edition = "2021" diff --git a/pallets/ve-minting/rpc/runtime-api/src/lib.rs b/pallets/bb-bnc/rpc/runtime-api/src/lib.rs similarity index 96% rename from pallets/ve-minting/rpc/runtime-api/src/lib.rs rename to pallets/bb-bnc/rpc/runtime-api/src/lib.rs index 153b3543b..b1309f318 100644 --- a/pallets/ve-minting/rpc/runtime-api/src/lib.rs +++ b/pallets/bb-bnc/rpc/runtime-api/src/lib.rs @@ -24,7 +24,7 @@ use sp_api::decl_runtime_apis; use sp_core::U256; decl_runtime_apis! { - pub trait VeMintingRuntimeApi where + pub trait BbBNCRuntimeApi where AccountId: Codec, BlockNumber: Codec, { diff --git a/pallets/ve-minting/rpc/src/lib.rs b/pallets/bb-bnc/rpc/src/lib.rs similarity index 90% rename from pallets/ve-minting/rpc/src/lib.rs rename to pallets/bb-bnc/rpc/src/lib.rs index 944d53838..f1483120d 100644 --- a/pallets/ve-minting/rpc/src/lib.rs +++ b/pallets/bb-bnc/rpc/src/lib.rs @@ -18,8 +18,8 @@ use std::{marker::PhantomData, sync::Arc}; +pub use bb_bnc_rpc_runtime_api::{self as runtime_api, BbBNCRuntimeApi}; use bifrost_primitives::Balance; -pub use bifrost_ve_minting_rpc_runtime_api::{self as runtime_api, VeMintingRuntimeApi}; use jsonrpsee::{ core::{async_trait, RpcResult}, proc_macros::rpc, @@ -37,27 +37,27 @@ use sp_runtime::{ }; #[rpc(client, server)] -pub trait VeMintingRpcApi { +pub trait BbBNCRpcApi { /// rpc method for getting user balance - #[method(name = "ve_minting_balanceOf")] + #[method(name = "bb_bnc_balanceOf")] fn balance_of(&self, who: AccountId, at: Option) -> RpcResult; /// RPC method to get total supply - #[method(name = "ve_minting_totalSupply")] + #[method(name = "bb_bnc_totalSupply")] fn total_supply(&self, at: Option) -> RpcResult; /// RPC method to find block epoch - #[method(name = "ve_minting_findBlockEpoch")] + #[method(name = "bb_bnc_findBlockEpoch")] fn find_block_epoch(&self, max_epoch: U256, at: Option) -> RpcResult; } #[derive(Clone, Debug)] -pub struct VeMintingRpc { +pub struct BbBNCRpc { client: Arc, _marker: PhantomData, } -impl VeMintingRpc +impl BbBNCRpc where Block: BlockT, C: BlockIdTo, @@ -68,12 +68,12 @@ where } #[async_trait] -impl VeMintingRpcApiServer<::Hash, AccountId> - for VeMintingRpc +impl BbBNCRpcApiServer<::Hash, AccountId> + for BbBNCRpc where Block: BlockT, C: Send + Sync + 'static + ProvideRuntimeApi + HeaderBackend + BlockIdTo, - C::Api: VeMintingRuntimeApi, + C::Api: BbBNCRuntimeApi, AccountId: Codec, // CallError: From<>::Error>, { diff --git a/pallets/ve-minting/src/benchmarking.rs b/pallets/bb-bnc/src/benchmarking.rs similarity index 84% rename from pallets/ve-minting/src/benchmarking.rs rename to pallets/bb-bnc/src/benchmarking.rs index 93822ced8..26dcebcfe 100644 --- a/pallets/ve-minting/src/benchmarking.rs +++ b/pallets/bb-bnc/src/benchmarking.rs @@ -27,7 +27,7 @@ use frame_system::RawOrigin; use sp_runtime::traits::UniqueSaturatedFrom; use sp_std::vec; -use crate::{BalanceOf, Call, Config, Pallet as VeMinting, Pallet}; +use crate::{BalanceOf, Call, Config, Pallet as BbBNC, Pallet}; use orml_traits::MultiCurrency; benchmarks! { @@ -38,7 +38,7 @@ benchmarks! { create_lock { let test_account: T::AccountId = account("seed",1,1); - assert_ok!(VeMinting::::set_config( + assert_ok!(BbBNC::::set_config( RawOrigin::Root.into(), Some((4 * 365 * 86400 / 12u32).into()), Some((7 * 86400 / 12u32).into()) @@ -46,7 +46,7 @@ benchmarks! { T::MultiCurrency::deposit(CurrencyId::Native(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; T::MultiCurrency::deposit(CurrencyId::VToken(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; let rewards = vec![(CurrencyId::Native(TokenSymbol::BNC), BalanceOf::::unique_saturated_from(10_000_000_000_000u128))]; - assert_ok!(VeMinting::::notify_rewards( + assert_ok!(BbBNC::::notify_rewards( T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?, account("seed",1,1), Some((7 * 86400 / 12u32).into()),rewards @@ -56,7 +56,7 @@ benchmarks! { increase_amount { let test_account: T::AccountId = account("seed",1,1); - assert_ok!(VeMinting::::set_config( + assert_ok!(BbBNC::::set_config( RawOrigin::Root.into(), Some((4 * 365 * 86400 / 12u32).into()), Some((7 * 86400 / 12u32).into()) @@ -64,13 +64,13 @@ benchmarks! { T::MultiCurrency::deposit(CurrencyId::Native(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; T::MultiCurrency::deposit(CurrencyId::VToken(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; let rewards = vec![(CurrencyId::Native(TokenSymbol::BNC), BalanceOf::::unique_saturated_from(10_000_000_000_000u128))]; - assert_ok!(VeMinting::::notify_rewards( + assert_ok!(BbBNC::::notify_rewards( T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?, account("seed",1,1), Some((7 * 86400 / 12u32).into()),rewards )); - assert_ok!(VeMinting::::create_lock( + assert_ok!(BbBNC::::create_lock( RawOrigin::Signed(test_account.clone()).into(), BalanceOf::::unique_saturated_from(10_000_000_000_000u128), (365 * 86400 / 12u32).into() @@ -80,7 +80,7 @@ benchmarks! { increase_unlock_time { let test_account: T::AccountId = account("seed",1,1); - assert_ok!(VeMinting::::set_config( + assert_ok!(BbBNC::::set_config( RawOrigin::Root.into(), Some((4 * 365 * 86400 / 12u32).into()), Some((7 * 86400 / 12u32).into()) @@ -88,13 +88,13 @@ benchmarks! { T::MultiCurrency::deposit(CurrencyId::Native(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; T::MultiCurrency::deposit(CurrencyId::VToken(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; let rewards = vec![(CurrencyId::Native(TokenSymbol::BNC), BalanceOf::::unique_saturated_from(10_000_000_000_000u128))]; - assert_ok!(VeMinting::::notify_rewards( + assert_ok!(BbBNC::::notify_rewards( T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?, account("seed",1,1), Some((7 * 86400 / 12u32).into()),rewards )); - assert_ok!(VeMinting::::create_lock( + assert_ok!(BbBNC::::create_lock( RawOrigin::Signed(test_account.clone()).into(), BalanceOf::::unique_saturated_from(10_000_000_000_000u128), (365 * 86400 / 12u32).into() @@ -104,7 +104,7 @@ benchmarks! { withdraw { let test_account: T::AccountId = account("seed",1,1); - assert_ok!(VeMinting::::set_config( + assert_ok!(BbBNC::::set_config( T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?, Some((4 * 365 * 86400 / 12u32).into()), Some((7 * 86400 / 12u32).into()) @@ -112,13 +112,13 @@ benchmarks! { T::MultiCurrency::deposit(CurrencyId::Native(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; T::MultiCurrency::deposit(CurrencyId::VToken(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; let rewards = vec![(CurrencyId::Native(TokenSymbol::BNC), BalanceOf::::unique_saturated_from(10_000_000_000_000u128))]; - assert_ok!(VeMinting::::notify_rewards( + assert_ok!(BbBNC::::notify_rewards( T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?, account("seed",1,1), Some((7 * 86400 / 12u32).into()),rewards )); - assert_ok!(VeMinting::::create_lock( + assert_ok!(BbBNC::::create_lock( RawOrigin::Signed(test_account.clone()).into(), BalanceOf::::unique_saturated_from(10_000_000_000_000u128), (365 * 86400 / 12u32).into() @@ -130,7 +130,7 @@ benchmarks! { get_rewards { let test_account: T::AccountId = account("seed",1,1); - assert_ok!(VeMinting::::set_config( + assert_ok!(BbBNC::::set_config( RawOrigin::Root.into(), Some((4 * 365 * 86400 / 12u32).into()), Some((7 * 86400 / 12u32).into()) @@ -138,13 +138,13 @@ benchmarks! { T::MultiCurrency::deposit(CurrencyId::Native(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; T::MultiCurrency::deposit(CurrencyId::VToken(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; let rewards = vec![(CurrencyId::Native(TokenSymbol::BNC), BalanceOf::::unique_saturated_from(10_000_000_000_000u128))]; - assert_ok!(VeMinting::::notify_rewards( + assert_ok!(BbBNC::::notify_rewards( T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?, account("seed",1,1), Some((7 * 86400 / 12u32).into()),rewards )); - assert_ok!(VeMinting::::create_lock( + assert_ok!(BbBNC::::create_lock( RawOrigin::Signed(test_account.clone()).into(), BalanceOf::::unique_saturated_from(10_000_000_000_000u128), (365 * 86400 / 12u32).into() @@ -155,7 +155,7 @@ benchmarks! { }: _(RawOrigin::Signed(test_account)) notify_rewards { - assert_ok!(VeMinting::::set_config( + assert_ok!(BbBNC::::set_config( RawOrigin::Root.into(), Some((4 * 365 * 86400 / 12u32).into()), Some((7 * 86400 / 12u32).into()) @@ -165,7 +165,7 @@ benchmarks! { }: _(RawOrigin::Root,account("seed",1,1),Some((7 * 86400 / 12u32).into()),rewards) set_markup_coefficient { - assert_ok!(VeMinting::::set_config( + assert_ok!(BbBNC::::set_config( RawOrigin::Root.into(), Some((4 * 365 * 86400 / 12u32).into()), Some((7 * 86400 / 12u32).into()) @@ -175,7 +175,7 @@ benchmarks! { deposit_markup { let test_account: T::AccountId = account("seed",1,1); - assert_ok!(VeMinting::::set_config( + assert_ok!(BbBNC::::set_config( RawOrigin::Root.into(), Some((4 * 365 * 86400 / 12u32).into()), Some((7 * 86400 / 12u32).into()) @@ -183,18 +183,18 @@ benchmarks! { T::MultiCurrency::deposit(CurrencyId::Native(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; T::MultiCurrency::deposit(CurrencyId::VToken(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; let rewards = vec![(CurrencyId::Native(TokenSymbol::BNC), BalanceOf::::unique_saturated_from(10_000_000_000_000u128))]; - assert_ok!(VeMinting::::notify_rewards( + assert_ok!(BbBNC::::notify_rewards( T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?, account("seed",1,1), Some((7 * 86400 / 12u32).into()),rewards )); - assert_ok!(VeMinting::::create_lock( + assert_ok!(BbBNC::::create_lock( RawOrigin::Signed(test_account.clone()).into(), BalanceOf::::unique_saturated_from(10_000_000_000_000u128), (365 * 86400 / 12u32).into() )); - assert_ok!(VeMinting::::set_markup_coefficient( + assert_ok!(BbBNC::::set_markup_coefficient( RawOrigin::Root.into(), CurrencyId::VToken(TokenSymbol::BNC), 1_000.into(), @@ -206,7 +206,7 @@ benchmarks! { withdraw_markup { let test_account: T::AccountId = account("seed",1,1); - assert_ok!(VeMinting::::set_config( + assert_ok!(BbBNC::::set_config( RawOrigin::Root.into(), Some((4 * 365 * 86400 / 12u32).into()), Some((7 * 86400 / 12u32).into()) @@ -214,31 +214,31 @@ benchmarks! { T::MultiCurrency::deposit(CurrencyId::Native(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; T::MultiCurrency::deposit(CurrencyId::VToken(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; let rewards = vec![(CurrencyId::Native(TokenSymbol::BNC), BalanceOf::::unique_saturated_from(10_000_000_000_000u128))]; - assert_ok!(VeMinting::::notify_rewards( + assert_ok!(BbBNC::::notify_rewards( T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?, account("seed",1,1), Some((7 * 86400 / 12u32).into()),rewards )); - assert_ok!(VeMinting::::create_lock( + assert_ok!(BbBNC::::create_lock( RawOrigin::Signed(test_account.clone()).into(), BalanceOf::::unique_saturated_from(10_000_000_000_000u128), (365 * 86400 / 12u32).into() )); - assert_ok!(VeMinting::::set_markup_coefficient( + assert_ok!(BbBNC::::set_markup_coefficient( RawOrigin::Root.into(), CurrencyId::VToken(TokenSymbol::BNC), 1_000.into(), 10_000_000_000_000.into() )); - assert_ok!(VeMinting::::deposit_markup(RawOrigin::Signed(test_account.clone()).into(), CurrencyId::VToken(TokenSymbol::BNC), BalanceOf::::unique_saturated_from(10_000_000_000_000u128))); + assert_ok!(BbBNC::::deposit_markup(RawOrigin::Signed(test_account.clone()).into(), CurrencyId::VToken(TokenSymbol::BNC), BalanceOf::::unique_saturated_from(10_000_000_000_000u128))); >::set_block_number((2 * 365 * 86400 / 12u32).into()); }: _(RawOrigin::Signed(test_account), CurrencyId::VToken(TokenSymbol::BNC)) redeem_unlock { let test_account: T::AccountId = account("seed",1,1); - assert_ok!(VeMinting::::set_config( + assert_ok!(BbBNC::::set_config( RawOrigin::Root.into(), Some((4 * 365 * 86400 / 12u32).into()), Some((7 * 86400 / 12u32).into()) @@ -246,31 +246,31 @@ benchmarks! { T::MultiCurrency::deposit(CurrencyId::Native(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; T::MultiCurrency::deposit(CurrencyId::VToken(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; let rewards = vec![(CurrencyId::Native(TokenSymbol::BNC), BalanceOf::::unique_saturated_from(10_000_000_000_000u128))]; - assert_ok!(VeMinting::::notify_rewards( + assert_ok!(BbBNC::::notify_rewards( T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?, account("seed",1,1), Some((7 * 86400 / 12u32).into()),rewards )); - assert_ok!(VeMinting::::create_lock( + assert_ok!(BbBNC::::create_lock( RawOrigin::Signed(test_account.clone()).into(), BalanceOf::::unique_saturated_from(10_000_000_000_000u128), (365 * 86400 / 12u32).into() )); - assert_ok!(VeMinting::::set_markup_coefficient( + assert_ok!(BbBNC::::set_markup_coefficient( RawOrigin::Root.into(), CurrencyId::VToken(TokenSymbol::BNC), 1_000.into(), 10_000_000_000_000.into() )); - assert_ok!(VeMinting::::deposit_markup(RawOrigin::Signed(test_account.clone()).into(), CurrencyId::VToken(TokenSymbol::BNC), BalanceOf::::unique_saturated_from(10_000_000_000_000u128))); + assert_ok!(BbBNC::::deposit_markup(RawOrigin::Signed(test_account.clone()).into(), CurrencyId::VToken(TokenSymbol::BNC), BalanceOf::::unique_saturated_from(10_000_000_000_000u128))); >::set_block_number((2 * 86400 / 12u32).into()); }: _(RawOrigin::Signed(test_account), 0) refresh { let test_account: T::AccountId = account("seed",1,1); - assert_ok!(VeMinting::::set_config( + assert_ok!(BbBNC::::set_config( RawOrigin::Root.into(), Some((4 * 365 * 86400 / 12u32).into()), Some((7 * 86400 / 12u32).into()) @@ -278,27 +278,27 @@ benchmarks! { T::MultiCurrency::deposit(CurrencyId::Native(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; T::MultiCurrency::deposit(CurrencyId::VToken(TokenSymbol::BNC), &test_account, BalanceOf::::unique_saturated_from(100_000_000_000_000u128))?; let rewards = vec![(CurrencyId::Native(TokenSymbol::BNC), BalanceOf::::unique_saturated_from(10_000_000_000_000u128))]; - assert_ok!(VeMinting::::notify_rewards( + assert_ok!(BbBNC::::notify_rewards( T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?, account("seed",1,1), Some((7 * 86400 / 12u32).into()),rewards )); - assert_ok!(VeMinting::::create_lock( + assert_ok!(BbBNC::::create_lock( RawOrigin::Signed(test_account.clone()).into(), BalanceOf::::unique_saturated_from(10_000_000_000_000u128), (365 * 86400 / 12u32).into() )); - assert_ok!(VeMinting::::set_markup_coefficient( + assert_ok!(BbBNC::::set_markup_coefficient( RawOrigin::Root.into(), CurrencyId::VToken(TokenSymbol::BNC), 1_000.into(), 10_000_000_000_000.into() )); - assert_ok!(VeMinting::::deposit_markup(RawOrigin::Signed(test_account.clone()).into(), CurrencyId::VToken(TokenSymbol::BNC), BalanceOf::::unique_saturated_from(10_000_000_000_000u128))); + assert_ok!(BbBNC::::deposit_markup(RawOrigin::Signed(test_account.clone()).into(), CurrencyId::VToken(TokenSymbol::BNC), BalanceOf::::unique_saturated_from(10_000_000_000_000u128))); >::set_block_number((2 * 86400 / 12u32).into()); }: _(RawOrigin::Signed(test_account), CurrencyId::VToken(TokenSymbol::BNC)) - impl_benchmark_test_suite!(VeMinting,crate::mock::ExtBuilder::default().build(),crate::mock::Runtime); + impl_benchmark_test_suite!(BbBNC,crate::mock::ExtBuilder::default().build(),crate::mock::Runtime); } diff --git a/pallets/ve-minting/src/incentive.rs b/pallets/bb-bnc/src/incentive.rs similarity index 89% rename from pallets/ve-minting/src/incentive.rs rename to pallets/bb-bnc/src/incentive.rs index cbbbb7a77..4edfcb1eb 100644 --- a/pallets/ve-minting/src/incentive.rs +++ b/pallets/bb-bnc/src/incentive.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use crate::{traits::VeMintingInterface, *}; +use crate::{traits::BbBNCInterface, *}; use bifrost_primitives::PoolId; pub use pallet::*; use sp_std::collections::btree_map::BTreeMap; @@ -56,10 +56,10 @@ impl Pallet { /// Check if the current block number is within the end time of the reward pool pub fn last_time_reward_applicable(pool_id: PoolId) -> BlockNumberFor { let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); - if current_block_number < Self::incentive_configs(pool_id).period_finish { + if current_block_number < IncentiveConfigs::::get(pool_id).period_finish { current_block_number } else { - Self::incentive_configs(pool_id).period_finish + IncentiveConfigs::::get(pool_id).period_finish } } @@ -67,7 +67,7 @@ impl Pallet { pub fn reward_per_token( pool_id: PoolId, ) -> Result, BalanceOf>, DispatchError> { - let mut conf = Self::incentive_configs(pool_id); + let mut conf = IncentiveConfigs::::get(pool_id); let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); let total_supply = Self::total_supply(current_block_number)?; if total_supply == BalanceOf::::zero() { @@ -108,7 +108,7 @@ impl Pallet { ) -> Result, BalanceOf>, DispatchError> { let reward_per_token = Self::reward_per_token(pool_id)?; let vetoken_balance = Self::balance_of_current_block(addr)?; - let mut rewards = if let Some(rewards) = Self::rewards(addr) { + let mut rewards = if let Some(rewards) = Rewards::::get(addr) { rewards } else { BTreeMap::, BalanceOf>::default() @@ -118,7 +118,7 @@ impl Pallet { .checked_mul(U256::from( reward .saturating_sub( - *Self::user_reward_per_token_paid(addr) + *UserRewardPerTokenPaid::::get(addr) .get(currency) .unwrap_or(&BalanceOf::::zero()), ) @@ -136,6 +136,15 @@ impl Pallet { // and total share. match share_info { Some((share, total_share)) => { + let mut pools = UserFarmingPool::::get(addr); + if share.is_zero() { + if let Some(pos) = pools.iter().position(|&x| x == pool_id) { + pools.remove(pos); + } + } else { + pools.try_push(pool_id).map_err(|_| Error::::UserFarmingPoolOverflow)?; + } + UserFarmingPool::::insert(addr, pools); let reward = increment .checked_mul(U256::from(share.saturated_into::())) .ok_or(ArithmeticError::Overflow)? @@ -195,9 +204,13 @@ impl Pallet { } /// Update reward for all pools - pub fn update_reward_all(addr: Option<&AccountIdOf>) -> DispatchResult { - // TODO: pool_id - Self::update_reward(0, addr, None)?; + pub fn update_reward_all(addr: &AccountIdOf) -> DispatchResult { + UserFarmingPool::::get(addr) + .iter() + .try_for_each(|&pool_id| -> DispatchResult { + Self::update_reward(pool_id, Some(addr), None) + })?; + Self::update_reward(VE_MINTING_SYSTEM_POOL_ID, Some(addr), None)?; Ok(()) } @@ -211,7 +224,7 @@ impl Pallet { if Self::balance_of_current_block(addr)? == BalanceOf::::zero() { return Ok(()); } // Excit earlier if balance of token is zero - if let Some(rewards) = Self::rewards(addr) { + if let Some(rewards) = Rewards::::get(addr) { rewards.iter().try_for_each(|(currency, &reward)| -> DispatchResult { T::MultiCurrency::transfer( *currency, @@ -225,8 +238,6 @@ impl Pallet { addr: addr.to_owned(), rewards: rewards.into_iter().collect(), }); - } else { - return Err(Error::::NoRewards.into()); } Ok(()) } @@ -242,7 +253,7 @@ impl Pallet { None => return Err(Error::::NoController.into()), }; Self::update_reward(pool_id, None, None)?; - let mut conf = Self::incentive_configs(pool_id); + let mut conf = IncentiveConfigs::::get(pool_id); let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); if current_block_number >= conf.period_finish { diff --git a/pallets/ve-minting/src/lib.rs b/pallets/bb-bnc/src/lib.rs similarity index 91% rename from pallets/ve-minting/src/lib.rs rename to pallets/bb-bnc/src/lib.rs index 03ce9a825..3e0728af3 100644 --- a/pallets/ve-minting/src/lib.rs +++ b/pallets/bb-bnc/src/lib.rs @@ -49,9 +49,7 @@ pub use incentive::*; use orml_traits::{LockIdentifier, MultiCurrency, MultiLockableCurrency}; use sp_core::{U256, U512}; use sp_std::{borrow::ToOwned, cmp::Ordering, collections::btree_map::BTreeMap, vec, vec::Vec}; -pub use traits::{ - LockedToken, MarkupCoefficientInfo, MarkupInfo, UserMarkupInfo, VeMintingInterface, -}; +pub use traits::{BbBNCInterface, LockedToken, MarkupCoefficientInfo, MarkupInfo, UserMarkupInfo}; pub use weights::WeightInfo; type BalanceOf = <::MultiCurrency as MultiCurrency>>::Balance; @@ -64,7 +62,7 @@ pub type CurrencyIdOf = <::MultiCurrency as MultiCurrency< const VE_LOCK_ID: LockIdentifier = *b"vebnclck"; const MARKUP_LOCK_ID: LockIdentifier = *b"vebncmkp"; - +const VE_MINTING_SYSTEM_POOL_ID: PoolId = u32::MAX; #[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo, Default)] pub struct VeConfig { amount: Balance, @@ -109,10 +107,10 @@ pub mod pallet { type TokenType: Get; #[pallet::constant] - type VeMintingPalletId: Get; + type IncentivePalletId: Get; #[pallet::constant] - type IncentivePalletId: Get; + type BuyBackAccount: Get; /// Convert the block number into a balance. type BlockNumberToBalance: Convert, BalanceOf>; @@ -188,6 +186,9 @@ pub mod pallet { PartiallyRefreshed { asset_id: CurrencyIdOf, }, + NotifyRewardFailed { + rewards: Vec<(CurrencyIdOf, BalanceOf)>, + }, } #[pallet::error] @@ -197,27 +198,23 @@ pub mod pallet { BelowMinimumMint, LockNotExist, LockExist, - NoRewards, ArgumentsError, ExceedsMaxPositions, NoController, + UserFarmingPoolOverflow, } #[pallet::storage] - #[pallet::getter(fn supply)] pub type Supply = StorageValue<_, BalanceOf, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn ve_configs)] pub type VeConfigs = StorageValue<_, VeConfig, BlockNumberFor>, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn epoch)] pub type Epoch = StorageValue<_, U256, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn locked)] pub type Locked = StorageMap< _, Blake2_128Concat, @@ -227,18 +224,15 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn user_locked)] pub type UserLocked = StorageMap<_, Blake2_128Concat, AccountIdOf, BalanceOf, ValueQuery>; // Each week has a Point struct stored in PointHistory. #[pallet::storage] - #[pallet::getter(fn point_history)] pub type PointHistory = StorageMap<_, Twox64Concat, U256, Point, BlockNumberFor>, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn user_point_history)] pub type UserPointHistory = StorageDoubleMap< _, Blake2_128Concat, @@ -250,17 +244,14 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn user_point_epoch)] pub type UserPointEpoch = StorageMap<_, Blake2_128Concat, u128, U256, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn slope_changes)] pub type SlopeChanges = StorageMap<_, Twox64Concat, BlockNumberFor, i128, ValueQuery>; // Incentive #[pallet::storage] - #[pallet::getter(fn incentive_configs)] pub type IncentiveConfigs = StorageMap< _, Blake2_128Concat, @@ -270,7 +261,6 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn user_reward_per_token_paid)] pub type UserRewardPerTokenPaid = StorageMap< _, Blake2_128Concat, @@ -280,17 +270,14 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn rewards)] pub type Rewards = StorageMap<_, Blake2_128Concat, AccountIdOf, BTreeMap, BalanceOf>>; #[pallet::storage] - #[pallet::getter(fn user_markup_infos)] pub type UserMarkupInfos = StorageMap<_, Blake2_128Concat, AccountIdOf, UserMarkupInfo>; #[pallet::storage] - #[pallet::getter(fn locked_tokens)] pub type LockedTokens = StorageDoubleMap< _, Blake2_128Concat, @@ -301,17 +288,14 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn total_lock)] pub type TotalLock = StorageMap<_, Twox64Concat, CurrencyIdOf, BalanceOf, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn markup_coefficient)] pub type MarkupCoefficient = StorageMap<_, Twox64Concat, CurrencyIdOf, MarkupCoefficientInfo>>; #[pallet::storage] - #[pallet::getter(fn position)] pub type Position = StorageValue<_, u128, ValueQuery>; #[pallet::storage] @@ -323,17 +307,40 @@ pub mod pallet { ValueQuery, >; - // #[pallet::hooks] - // impl Hooks> for Pallet { - // fn on_initialize(n: BlockNumberFor) -> Weight { - // let conf = Self::incentive_configs(); - // if n == conf.last_update_time + conf.rewards_duration { - // Self::notify_reward_amount(&conf.incentive_controller, conf.last_reward.clone()) - // .unwrap_or_default(); - // } - // T::DbWeight::get().writes(1_u64) - // } - // } + /// The pool ID of the user participating in the farming pool. + #[pallet::storage] + pub type UserFarmingPool = StorageMap< + _, + Blake2_128Concat, + AccountIdOf, + BoundedVec>, + ValueQuery, + >; + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(n: BlockNumberFor) -> Weight { + let conf = IncentiveConfigs::::get(VE_MINTING_SYSTEM_POOL_ID); + if n == conf.period_finish { + if let Some(e) = Self::notify_reward_amount( + VE_MINTING_SYSTEM_POOL_ID, + &conf.incentive_controller, + conf.last_reward.clone(), + ) + .err() + { + log::error!( + target: "bb-bnc::notify_reward_amount", + "Received invalid justification for {:?}", + e, + ); + Self::deposit_event(Event::NotifyRewardFailed { rewards: conf.last_reward }); + } + } + + T::DbWeight::get().writes(1_u64) + } + } #[pallet::call] impl Pallet { @@ -346,7 +353,7 @@ pub mod pallet { ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - let mut ve_config = Self::ve_configs(); + let mut ve_config = VeConfigs::::get(); if let Some(min_mint) = min_mint { ve_config.min_mint = min_mint; }; @@ -415,15 +422,19 @@ pub mod pallet { rewards: Vec<(CurrencyIdOf, BalanceOf)>, ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - Self::set_incentive(0, rewards_duration, Some(incentive_from.clone())); // for pool0 - Self::notify_reward_amount(0, &Some(incentive_from), rewards) // for pool0 + Self::set_incentive( + VE_MINTING_SYSTEM_POOL_ID, + rewards_duration, + Some(incentive_from.clone()), + ); + Self::notify_reward_amount(VE_MINTING_SYSTEM_POOL_ID, &Some(incentive_from), rewards) } #[pallet::call_index(6)] #[pallet::weight(T::WeightInfo::get_rewards())] pub fn get_rewards(origin: OriginFor) -> DispatchResult { let exchanger = ensure_signed(origin)?; - Self::get_rewards_inner(0, &exchanger, None) // for pool0 + Self::get_rewards_inner(VE_MINTING_SYSTEM_POOL_ID, &exchanger, None) } #[pallet::call_index(7)] @@ -488,12 +499,12 @@ pub mod pallet { old_locked: LockedBalance, BlockNumberFor>, new_locked: LockedBalance, BlockNumberFor>, ) -> DispatchResult { - Self::update_reward_all(Some(who))?; + Self::update_reward_all(who)?; let mut u_old = Point::, BlockNumberFor>::default(); let mut u_new = Point::, BlockNumberFor>::default(); let mut new_dslope = 0_i128; - let mut g_epoch: U256 = Self::epoch(); + let mut g_epoch: U256 = Epoch::::get(); let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); if old_locked.end > current_block_number && old_locked.amount > BalanceOf::::zero() { @@ -526,12 +537,12 @@ pub mod pallet { ) .ok_or(ArithmeticError::Overflow)?; } - let mut old_dslope = Self::slope_changes(old_locked.end); + let mut old_dslope = SlopeChanges::::get(old_locked.end); if new_locked.end != Zero::zero() { if new_locked.end == old_locked.end { new_dslope = old_dslope } else { - new_dslope = Self::slope_changes(new_locked.end) + new_dslope = SlopeChanges::::get(new_locked.end) } } @@ -542,13 +553,9 @@ pub mod pallet { amount: Zero::zero(), }; if g_epoch > U256::zero() { - last_point = Self::point_history(g_epoch); + last_point = PointHistory::::get(g_epoch); } else { - // last_point.amount = T::MultiCurrency::free_balance( - // T::TokenType::get(), - // &T::VeMintingPalletId::get().into_account_truncating(), - // ); - last_point.amount = Self::supply(); + last_point.amount = Supply::::get(); } let mut last_checkpoint = last_point.block; let mut t_i: BlockNumberFor = last_checkpoint @@ -562,7 +569,7 @@ pub mod pallet { if t_i > current_block_number { t_i = current_block_number } else { - d_slope = Self::slope_changes(t_i) + d_slope = SlopeChanges::::get(t_i) } last_point.bias = last_point .bias @@ -596,11 +603,7 @@ pub mod pallet { // Fill for the current block, if applicable if t_i == current_block_number { - last_point.amount = Self::supply(); - // last_point.amount = T::MultiCurrency::free_balance( - // T::TokenType::get(), - // &T::VeMintingPalletId::get().into_account_truncating(), - // ); + last_point.amount = Supply::::get(); break; } else { PointHistory::::insert(g_epoch, last_point); @@ -649,12 +652,12 @@ pub mod pallet { } // Now handle user history - let user_epoch = Self::user_point_epoch(addr) + let user_epoch = UserPointEpoch::::get(addr) .checked_add(U256::one()) .ok_or(ArithmeticError::Overflow)?; UserPointEpoch::::insert(addr, user_epoch); u_new.block = current_block_number; - // u_new.amount = Self::locked(addr).amount; + // u_new.amount = Locked::::get(addr).amount; u_new.amount = new_locked.amount; UserPointHistory::::insert(addr, user_epoch, u_new); @@ -670,7 +673,7 @@ pub mod pallet { ) -> DispatchResult { let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); let mut _locked = locked_balance; - let supply_before = Self::supply(); + let supply_before = Supply::::get(); Supply::::set(supply_before.checked_add(value).ok_or(ArithmeticError::Overflow)?); let old_locked = _locked.clone(); @@ -715,12 +718,12 @@ pub mod pallet { addr: u128, ) -> Result, DispatchError> { let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); - let u_epoch = Self::user_point_epoch(addr); + let u_epoch = UserPointEpoch::::get(addr); if u_epoch == U256::zero() { return Ok(Zero::zero()); } else { let mut last_point: Point, BlockNumberFor> = - Self::user_point_history(addr, u_epoch); + UserPointHistory::::get(addr, u_epoch); last_point.bias = last_point .bias @@ -756,7 +759,7 @@ pub mod pallet { // Binary search let mut _min = U256::zero(); - let mut _max = Self::user_point_epoch(addr); + let mut _max = UserPointEpoch::::get(addr); for _i in 0..128 { if _min >= _max { break; @@ -769,7 +772,7 @@ pub mod pallet { .checked_div(U256::from(2_u128)) .ok_or(ArithmeticError::Overflow)?; - if Self::user_point_history(addr, _mid).block <= block { + if UserPointHistory::::get(addr, _mid).block <= block { _min = _mid } else { _max = _mid.checked_sub(U256::one()).ok_or(ArithmeticError::Overflow)? @@ -777,7 +780,7 @@ pub mod pallet { } let mut upoint: Point, BlockNumberFor> = - Self::user_point_history(addr, _min); + UserPointHistory::::get(addr, _min); upoint.bias = upoint .bias .checked_sub( @@ -883,7 +886,7 @@ pub mod pallet { let left: FixedU128 = FixedU128::checked_from_integer(locked_token.amount) .and_then(|x| x.checked_mul(&markup_coefficient.markup_coefficient)) .and_then(|x| { - x.checked_div(&FixedU128::checked_from_integer(Self::total_lock(asset_id))?) + x.checked_div(&FixedU128::checked_from_integer(TotalLock::::get(asset_id))?) }) .ok_or(ArithmeticError::Overflow)?; @@ -916,7 +919,7 @@ pub mod pallet { UserPositions::::get(&addr).into_iter().try_for_each( |position| -> DispatchResult { let _locked: LockedBalance, BlockNumberFor> = - Self::locked(position); + Locked::::get(position); ensure!(!_locked.amount.is_zero(), Error::::ArgumentsError); Self::markup_calc( &addr, @@ -961,7 +964,7 @@ pub mod pallet { UserPositions::::get(&addr).into_iter().try_for_each( |position| -> DispatchResult { let _locked: LockedBalance, BlockNumberFor> = - Self::locked(position); + Locked::::get(position); ensure!(!_locked.amount.is_zero(), Error::::ArgumentsError); // TODO Self::markup_calc( &addr, @@ -998,7 +1001,7 @@ pub mod pallet { let left: FixedU128 = FixedU128::checked_from_integer(locked_token.amount) .and_then(|x| x.checked_mul(&markup_coefficient.markup_coefficient)) .and_then(|x| { - x.checked_div(&FixedU128::checked_from_integer(Self::total_lock( + x.checked_div(&FixedU128::checked_from_integer(TotalLock::::get( asset_id, ))?) }) @@ -1035,7 +1038,7 @@ pub mod pallet { UserPositions::::get(&addr).into_iter().try_for_each( |position| -> DispatchResult { let _locked: LockedBalance, BlockNumberFor> = - Self::locked(position); + Locked::::get(position); ensure!(!_locked.amount.is_zero(), Error::::ArgumentsError); // TODO Self::markup_calc( &addr, @@ -1080,7 +1083,7 @@ pub mod pallet { _locked.amount = Zero::zero(); Locked::::insert(position, _locked.clone()); - let supply_before = Self::supply(); + let supply_before = Supply::::get(); Supply::::set(supply_before.saturating_sub(value)); // BNC should be transferred before checkpoint @@ -1096,7 +1099,7 @@ pub mod pallet { T::MultiCurrency::transfer( T::TokenType::get(), who, - &T::VeMintingPalletId::get().into_account_truncating(), + &T::BuyBackAccount::get().into_account_truncating(), fast.checked_mul_int(value).ok_or(ArithmeticError::Overflow)?, )?; } @@ -1132,7 +1135,7 @@ pub mod pallet { /// This function will check the lock and redeem it regardless of whether it has expired. pub fn redeem_unlock_inner(who: &AccountIdOf, position: u128) -> DispatchResult { - let mut _locked = Self::locked(position); + let mut _locked = Locked::::get(position); let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); ensure!(_locked.end > current_block_number, Error::::Expired); let fast = Self::redeem_commission(_locked.end - current_block_number)?; diff --git a/pallets/ve-minting/src/mock.rs b/pallets/bb-bnc/src/mock.rs similarity index 95% rename from pallets/ve-minting/src/mock.rs rename to pallets/bb-bnc/src/mock.rs index f6f459eb6..0f5aff4bd 100644 --- a/pallets/ve-minting/src/mock.rs +++ b/pallets/bb-bnc/src/mock.rs @@ -21,8 +21,9 @@ #![cfg(test)] #![allow(non_upper_case_globals)] -use crate as bifrost_ve_minting; +use crate as bb_bnc; use bifrost_asset_registry::AssetIdMaps; +use bifrost_primitives::MoonbeamChainId; pub use bifrost_primitives::{ currency::*, CurrencyId, CurrencyIdMapping, SlpxOperator, TokenSymbol, }; @@ -67,7 +68,7 @@ frame_support::construct_runtime!( VtokenMinting: bifrost_vtoken_minting, Slp: bifrost_slp, AssetRegistry: bifrost_asset_registry, - VeMinting: bifrost_ve_minting, + BbBNC: bb_bnc, PolkadotXcm: pallet_xcm, } ); @@ -220,15 +221,11 @@ impl bifrost_vtoken_minting::Config for Runtime { type WeightInfo = (); type OnRedeemSuccess = (); type XcmTransfer = XTokens; - type AstarParachainId = ConstU32<2007>; - type MoonbeamParachainId = ConstU32<2023>; - type HydradxParachainId = ConstU32<2034>; - type MantaParachainId = ConstU32<2104>; - type InterlayParachainId = ConstU32<2032>; + type MoonbeamChainId = MoonbeamChainId; type ChannelCommission = (); type MaxLockRecords = ConstU32<100>; type IncentivePoolAccount = IncentivePoolAccount; - type VeMinting = (); + type BbBNC = (); type AssetIdMaps = AssetIdMaps; } @@ -243,9 +240,9 @@ impl bifrost_asset_registry::Config for Runtime { } parameter_types! { - pub const VeMintingTokenType: CurrencyId = CurrencyId::VToken(TokenSymbol::BNC); - pub VeMintingPalletId: PalletId = PalletId(*b"bf/vemnt"); - pub IncentivePalletId: PalletId = PalletId(*b"bf/veict"); + pub const BbBNCTokenType: CurrencyId = CurrencyId::VToken(TokenSymbol::BNC); + pub IncentivePalletId: PalletId = PalletId(*b"bf/bbict"); + pub const BuyBackAccount: PalletId = PalletId(*b"bf/bybck"); pub const Week: BlockNumber = 50400; // a week pub const MaxBlock: BlockNumber = 10512000; // four years pub const Multiplier: Balance = 10_u128.pow(12); @@ -254,13 +251,13 @@ parameter_types! { pub const MarkupRefreshLimit: u32 = 100; } -impl bifrost_ve_minting::Config for Runtime { +impl bb_bnc::Config for Runtime { type RuntimeEvent = RuntimeEvent; type MultiCurrency = Currencies; type ControlOrigin = EnsureRoot; - type TokenType = VeMintingTokenType; - type VeMintingPalletId = VeMintingPalletId; + type TokenType = BbBNCTokenType; type IncentivePalletId = IncentivePalletId; + type BuyBackAccount = BuyBackAccount; type WeightInfo = (); type BlockNumberToBalance = ConvertInto; type Week = Week; diff --git a/pallets/ve-minting/src/tests.rs b/pallets/bb-bnc/src/tests.rs similarity index 65% rename from pallets/ve-minting/src/tests.rs rename to pallets/bb-bnc/src/tests.rs index 78247e72e..45a80b53f 100644 --- a/pallets/ve-minting/src/tests.rs +++ b/pallets/bb-bnc/src/tests.rs @@ -20,7 +20,7 @@ #![cfg(test)] -use crate::{mock::*, traits::VeMintingInterface, *}; +use crate::{mock::*, traits::BbBNCInterface, *}; use bifrost_asset_registry::AssetMetadata; use bifrost_primitives::TokenInfo; use bifrost_runtime_common::milli; @@ -28,7 +28,6 @@ use frame_support::{assert_noop, assert_ok}; const POSITIONID0: u128 = 0; const POSITIONID1: u128 = 1; -const POOLID0: PoolId = 0; #[test] fn create_lock_should_work() { @@ -36,8 +35,8 @@ fn create_lock_should_work() { asset_registry(); System::set_block_number(System::block_number() + 20); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::create_lock_inner( &BOB, 10_000_000_000_000, System::block_number() + (4 * 365 * 86400 - 5 * 86400) / 12, @@ -46,8 +45,8 @@ fn create_lock_should_work() { UserPointHistory::::get(POSITIONID0, U256::from(1)), Point { bias: 9972575751740, slope: 951293, block: 20, amount: 10000000000000 } ); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(9972575751740)); - assert_eq!(VeMinting::total_supply(System::block_number()), Ok(9972575751740)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(9972575751740)); + assert_eq!(BbBNC::total_supply(System::block_number()), Ok(9972575751740)); }); } @@ -57,8 +56,8 @@ fn create_multi_locks_should_work() { asset_registry(); System::set_block_number(System::block_number() + 20); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::create_lock_inner( &BOB, 10_000_000_000_000, System::block_number() + (4 * 365 * 86400 - 5 * 86400) / 12, @@ -67,9 +66,9 @@ fn create_multi_locks_should_work() { UserPointHistory::::get(POSITIONID0, U256::from(1)), Point { bias: 9972575751740, slope: 951293, block: 20, amount: 10000000000000 } ); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(9972575751740)); - assert_eq!(VeMinting::total_supply(System::block_number()), Ok(9972575751740)); - assert_ok!(VeMinting::create_lock_inner( + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(9972575751740)); + assert_eq!(BbBNC::total_supply(System::block_number()), Ok(9972575751740)); + assert_ok!(BbBNC::create_lock_inner( &BOB, 5_000_000_000_000, System::block_number() + (2 * 365 * 86400 - 5 * 86400) / 12, @@ -78,8 +77,8 @@ fn create_multi_locks_should_work() { UserPointHistory::::get(POSITIONID1, U256::from(1)), Point { bias: 2493136560680, slope: 475646, block: 20, amount: 5000000000000 } ); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(12465712312420)); - assert_eq!(VeMinting::total_supply(System::block_number()), Ok(12465712312420)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(12465712312420)); + assert_eq!(BbBNC::total_supply(System::block_number()), Ok(12465712312420)); }); } @@ -89,22 +88,22 @@ fn increase_unlock_time_should_work() { asset_registry(); System::set_block_number(System::block_number() + 7 * 86400 / 12); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::create_lock_inner( &BOB, 10_000_000_000_000, System::block_number() + (3 * 365 * 86400 - 5 * 86400) / 12, )); assert_eq!(Locked::::get(POSITIONID0).end, 7963200); assert_noop!( - VeMinting::increase_unlock_time( + BbBNC::increase_unlock_time( RuntimeOrigin::signed(BOB), POSITIONID0, System::block_number() + 365 * 86400 / 12 ), Error::::ArgumentsError ); - assert_ok!(VeMinting::increase_unlock_time( + assert_ok!(BbBNC::increase_unlock_time( RuntimeOrigin::signed(BOB), POSITIONID0, (365 * 86400 - 5 * 86400) / 12 @@ -114,8 +113,8 @@ fn increase_unlock_time_should_work() { Point { bias: 7527391250400, slope: 951293, block: 50400, amount: 10000000000000 } ); assert_eq!(Locked::::get(POSITIONID0).end, 10584000); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(10020539944800)); - assert_eq!(VeMinting::total_supply(System::block_number()), Ok(10020539944800)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(10020539944800)); + assert_eq!(BbBNC::total_supply(System::block_number()), Ok(10020539944800)); }); } @@ -125,22 +124,22 @@ fn increase_unlock_time_should_work2() { asset_registry(); System::set_block_number(System::block_number() + 7 * 86400 / 12); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::create_lock_inner( &BOB, 10_000_000_000_000, System::block_number() + (3 * 365 * 86400 - 5 * 86400) / 12, )); assert_eq!(Locked::::get(POSITIONID0).end, 7963200); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(7527391250400)); - assert_ok!(VeMinting::create_lock_inner( + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(7527391250400)); + assert_ok!(BbBNC::create_lock_inner( &BOB, 5_000_000_000_000, System::block_number() + (3 * 365 * 86400 - 5 * 86400) / 12, )); assert_eq!(Locked::::get(POSITIONID1).end, 7963200); assert_noop!( - VeMinting::increase_unlock_time( + BbBNC::increase_unlock_time( RuntimeOrigin::signed(BOB), POSITIONID0, System::block_number() + 365 * 86400 / 12 @@ -148,20 +147,20 @@ fn increase_unlock_time_should_work2() { Error::::ArgumentsError ); assert_noop!( - VeMinting::increase_unlock_time( + BbBNC::increase_unlock_time( RuntimeOrigin::signed(BOB), POSITIONID1, System::block_number() + 365 * 86400 / 12 ), Error::::ArgumentsError ); - assert_ok!(VeMinting::increase_unlock_time( + assert_ok!(BbBNC::increase_unlock_time( RuntimeOrigin::signed(BOB), POSITIONID0, (365 * 86400 - 5 * 86400) / 12 )); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(13784231613600)); - assert_ok!(VeMinting::increase_unlock_time( + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(13784231613600)); + assert_ok!(BbBNC::increase_unlock_time( RuntimeOrigin::signed(BOB), POSITIONID1, (365 * 86400 - 5 * 86400) / 12 @@ -176,8 +175,8 @@ fn increase_unlock_time_should_work2() { Point { bias: 3763691668800, slope: 475646, block: 50400, amount: 5000000000000 } ); assert_eq!(Locked::::get(POSITIONID1).end, 10584000); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(15030804650400)); - assert_eq!(VeMinting::total_supply(System::block_number()), Ok(15030804650400)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(15030804650400)); + assert_eq!(BbBNC::total_supply(System::block_number()), Ok(15030804650400)); }); } @@ -186,21 +185,21 @@ fn update_reward() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { asset_registry(); System::set_block_number(System::block_number() + 20); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); System::set_block_number(System::block_number() + 40); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::create_lock_inner( &BOB, 100_000_000_000, System::block_number() + 365 * 86400 / 12, )); - assert_eq!(VeMinting::balance_of(&BOB, None), Ok(25407883680)); - assert_eq!(VeMinting::balance_of_position_current_block(0), Ok(25407883680)); - assert_ok!(VeMinting::deposit_for(&BOB, 0, 100_000_000_000)); - assert_ok!(VeMinting::update_reward(POOLID0, Some(&BOB), None)); // TODO + assert_eq!(BbBNC::balance_of(&BOB, None), Ok(25407883680)); + assert_eq!(BbBNC::balance_of_position_current_block(0), Ok(25407883680)); + assert_ok!(BbBNC::deposit_for(&BOB, 0, 100_000_000_000)); + assert_ok!(BbBNC::update_reward(VE_MINTING_SYSTEM_POOL_ID, Some(&BOB), None)); // TODO - assert_eq!(VeMinting::balance_of(&BOB, None), Ok(50818438500)); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(50818438500)); + assert_eq!(BbBNC::balance_of(&BOB, None), Ok(50818438500)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(50818438500)); }); } @@ -226,26 +225,23 @@ fn notify_reward_amount() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { asset_registry(); System::set_block_number(System::block_number() + 20); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); System::set_block_number(System::block_number() + 40); - assert_ok!(VeMinting::get_rewards(RuntimeOrigin::signed(BOB))); // balance of veBNC is 0 - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::get_rewards(RuntimeOrigin::signed(BOB))); // balance of veBNC is 0 + assert_ok!(BbBNC::create_lock_inner( &BOB, 20_000_000_000, System::block_number() + (4 * 365 * 86400 - 7 * 86400) / 12, )); assert_eq!(Tokens::free_balance(KSM, &BOB), 0); // balance of veBNC is not 0 - assert_noop!( - VeMinting::get_rewards(RuntimeOrigin::signed(BOB)), - Error::::NoRewards - ); - assert_ok!(VeMinting::increase_amount(RuntimeOrigin::signed(BOB), 0, 80_000_000_000)); - assert_eq!(VeMinting::balance_of(&BOB, None), Ok(99715627680)); + assert_ok!(BbBNC::get_rewards(RuntimeOrigin::signed(BOB))); + assert_ok!(BbBNC::increase_amount(RuntimeOrigin::signed(BOB), 0, 80_000_000_000)); + assert_eq!(BbBNC::balance_of(&BOB, None), Ok(99715627680)); let rewards = vec![(KSM, 1_000_000_000)]; - assert_ok!(VeMinting::notify_rewards( + assert_ok!(BbBNC::notify_rewards( RuntimeOrigin::root(), ALICE, Some(7 * 86400 / 12), @@ -254,31 +250,31 @@ fn notify_reward_amount() { assert_eq!(Tokens::free_balance(KSM, &BOB), 0); System::set_block_number(System::block_number() + 20); assert_eq!(Tokens::free_balance(KSM, &BOB), 0); - assert_ok!(VeMinting::get_rewards(RuntimeOrigin::signed(BOB))); + assert_ok!(BbBNC::get_rewards(RuntimeOrigin::signed(BOB))); assert_eq!(Tokens::free_balance(KSM, &BOB), 396819); System::set_block_number(System::block_number() + 7 * 86400 / 12); - assert_ok!(VeMinting::get_rewards_inner(POOLID0, &BOB, None)); + assert_ok!(BbBNC::get_rewards_inner(VE_MINTING_SYSTEM_POOL_ID, &BOB, None)); assert_eq!(Tokens::free_balance(KSM, &BOB), 999986398); - assert_ok!(VeMinting::notify_rewards( + assert_ok!(BbBNC::notify_rewards( RuntimeOrigin::root(), ALICE, Some(7 * 86400 / 12), rewards )); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::create_lock_inner( &CHARLIE, 100_000_000_000, (4 * 365 * 86400 - 7 * 86400) / 12 )); System::set_block_number(System::block_number() + 1 * 86400 / 12); - assert_ok!(VeMinting::get_rewards_inner(POOLID0, &BOB, None)); + assert_ok!(BbBNC::get_rewards_inner(VE_MINTING_SYSTEM_POOL_ID, &BOB, None)); assert_eq!(Tokens::free_balance(KSM, &BOB), 1071241763); - assert_ok!(VeMinting::get_rewards_inner(POOLID0, &CHARLIE, None)); + assert_ok!(BbBNC::get_rewards_inner(VE_MINTING_SYSTEM_POOL_ID, &CHARLIE, None)); assert_eq!(Tokens::free_balance(KSM, &CHARLIE), 71599834); System::set_block_number(System::block_number() + 7 * 86400 / 12); - assert_ok!(VeMinting::get_rewards_inner(POOLID0, &CHARLIE, None)); + assert_ok!(BbBNC::get_rewards_inner(VE_MINTING_SYSTEM_POOL_ID, &CHARLIE, None)); assert_eq!(Tokens::free_balance(KSM, &CHARLIE), 501203849); - assert_ok!(VeMinting::get_rewards_inner(POOLID0, &BOB, None)); + assert_ok!(BbBNC::get_rewards_inner(VE_MINTING_SYSTEM_POOL_ID, &BOB, None)); assert_eq!(Tokens::free_balance(KSM, &BOB), 1498768947); }); } @@ -288,24 +284,24 @@ fn create_lock_to_withdraw() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { asset_registry(); System::set_block_number(System::block_number() + 7 * 86400 / 12); // a week - assert_ok!(VeMinting::set_config( + assert_ok!(BbBNC::set_config( RuntimeOrigin::root(), Some(4 * 365 * 86400 / 12), Some(14 * 86400 / 12) )); let rewards = vec![(KSM, 1000)]; - assert_ok!(VeMinting::notify_rewards( + assert_ok!(BbBNC::notify_rewards( RuntimeOrigin::root(), ALICE, Some(7 * 86400 / 12), rewards )); assert_noop!( - VeMinting::increase_amount(RuntimeOrigin::signed(BOB), POSITIONID0, 50_000_000_000_000), + BbBNC::increase_amount(RuntimeOrigin::signed(BOB), POSITIONID0, 50_000_000_000_000), Error::::LockNotExist ); assert_noop!( - VeMinting::increase_unlock_time( + BbBNC::increase_unlock_time( RuntimeOrigin::signed(BOB), POSITIONID0, System::block_number() + 365 * 86400 / 12 @@ -313,7 +309,7 @@ fn create_lock_to_withdraw() { Error::::LockNotExist ); assert_noop!( - VeMinting::create_lock( + BbBNC::create_lock( RuntimeOrigin::signed(BOB), 50_000_000_000_000, System::block_number() + 5 * 365 * 86400 / 12 @@ -321,53 +317,53 @@ fn create_lock_to_withdraw() { Error::::ArgumentsError ); assert_noop!( - VeMinting::create_lock(RuntimeOrigin::signed(BOB), 50_000_000_000_000, 1), + BbBNC::create_lock(RuntimeOrigin::signed(BOB), 50_000_000_000_000, 1), Error::::ArgumentsError ); assert_noop!( - VeMinting::create_lock(RuntimeOrigin::signed(BOB), 50_000, 7 * 86400 / 12), + BbBNC::create_lock(RuntimeOrigin::signed(BOB), 50_000, 7 * 86400 / 12), Error::::BelowMinimumMint ); assert_eq!(Tokens::free_balance(VBNC, &BOB), 1000000000000000); - assert_ok!(VeMinting::create_lock_inner(&BOB, 50_000_000_000_000, 365 * 86400 / 12)); + assert_ok!(BbBNC::create_lock_inner(&BOB, 50_000_000_000_000, 365 * 86400 / 12)); assert_noop!( - VeMinting::increase_unlock_time( + BbBNC::increase_unlock_time( RuntimeOrigin::signed(BOB), POSITIONID0, System::block_number() + 5 * 365 * 86400 / 12 ), Error::::ArgumentsError ); - assert_eq!(VeMinting::balance_of_at(&BOB, System::block_number()), Ok(12705477321600)); - assert_eq!(VeMinting::balance_of_at(&BOB, System::block_number() - 10), Ok(0)); - assert_eq!(VeMinting::balance_of_at(&BOB, 0), Ok(0)); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number() - 10)), Ok(0)); - assert_eq!(VeMinting::total_supply(System::block_number()), Ok(12705477321600)); + assert_eq!(BbBNC::balance_of_at(&BOB, System::block_number()), Ok(12705477321600)); + assert_eq!(BbBNC::balance_of_at(&BOB, System::block_number() - 10), Ok(0)); + assert_eq!(BbBNC::balance_of_at(&BOB, 0), Ok(0)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number() - 10)), Ok(0)); + assert_eq!(BbBNC::total_supply(System::block_number()), Ok(12705477321600)); assert_noop!( - VeMinting::increase_amount(RuntimeOrigin::signed(BOB), 0, 50_000), + BbBNC::increase_amount(RuntimeOrigin::signed(BOB), 0, 50_000), Error::::BelowMinimumMint ); - assert_ok!(VeMinting::increase_amount(RuntimeOrigin::signed(BOB), 0, 50_000_000_000_000)); - assert_eq!(VeMinting::balance_of(&BOB, None), Ok(25410957314400)); - assert_eq!(VeMinting::total_supply(System::block_number()), Ok(25410957314400)); + assert_ok!(BbBNC::increase_amount(RuntimeOrigin::signed(BOB), 0, 50_000_000_000_000)); + assert_eq!(BbBNC::balance_of(&BOB, None), Ok(25410957314400)); + assert_eq!(BbBNC::total_supply(System::block_number()), Ok(25410957314400)); assert_noop!( - VeMinting::withdraw(RuntimeOrigin::signed(ALICE), POSITIONID0), + BbBNC::withdraw(RuntimeOrigin::signed(ALICE), POSITIONID0), Error::::LockNotExist ); assert_noop!( - VeMinting::withdraw(RuntimeOrigin::signed(BOB), POSITIONID0), + BbBNC::withdraw(RuntimeOrigin::signed(BOB), POSITIONID0), Error::::Expired ); - assert_eq!(VeMinting::total_supply(System::block_number()), Ok(25410957314400)); + assert_eq!(BbBNC::total_supply(System::block_number()), Ok(25410957314400)); System::set_block_number(System::block_number() + 2 * 365 * 86400 / 12); - assert_eq!(VeMinting::balance_of(&BOB, None), Ok(0)); - assert_eq!(VeMinting::total_supply(System::block_number()), Ok(0)); - assert_ok!(VeMinting::withdraw(RuntimeOrigin::signed(BOB), POSITIONID0)); - assert_ok!(VeMinting::withdraw_inner(&BOB, 0)); - assert_ok!(VeMinting::withdraw_inner(&BOB, 1)); - assert_eq!(VeMinting::balance_of(&BOB, None), Ok(0)); - assert_eq!(VeMinting::total_supply(System::block_number()), Ok(0)); + assert_eq!(BbBNC::balance_of(&BOB, None), Ok(0)); + assert_eq!(BbBNC::total_supply(System::block_number()), Ok(0)); + assert_ok!(BbBNC::withdraw(RuntimeOrigin::signed(BOB), POSITIONID0)); + assert_ok!(BbBNC::withdraw_inner(&BOB, 0)); + assert_ok!(BbBNC::withdraw_inner(&BOB, 1)); + assert_eq!(BbBNC::balance_of(&BOB, None), Ok(0)); + assert_eq!(BbBNC::total_supply(System::block_number()), Ok(0)); }); } @@ -375,10 +371,10 @@ fn create_lock_to_withdraw() { fn overflow() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { asset_registry(); - assert_ok!(VeMinting::create_lock_inner(&BOB, 100_000_000_000_000, 77000)); + assert_ok!(BbBNC::create_lock_inner(&BOB, 100_000_000_000_000, 77000)); System::set_block_number(77001); - assert_eq!(VeMinting::balance_of(&BOB, Some(77001)), Ok(226398387663)); - assert_eq!(VeMinting::total_supply(System::block_number()), Ok(226398387663)); + assert_eq!(BbBNC::balance_of(&BOB, Some(77001)), Ok(226398387663)); + assert_eq!(BbBNC::total_supply(System::block_number()), Ok(226398387663)); }); } @@ -388,15 +384,15 @@ fn deposit_markup_before_lock_should_work() { asset_registry(); System::set_block_number(System::block_number() + 20); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); - assert_ok!(VeMinting::set_markup_coefficient( + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::set_markup_coefficient( RuntimeOrigin::root(), VBNC, FixedU128::from_inner(100_000_000_000_000_000), // 0.1 FixedU128::saturating_from_integer(1), )); - assert_ok!(VeMinting::deposit_markup(RuntimeOrigin::signed(BOB), VBNC, 10_000_000_000_000)); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::deposit_markup(RuntimeOrigin::signed(BOB), VBNC, 10_000_000_000_000)); + assert_ok!(BbBNC::create_lock_inner( &BOB, 10_000_000_000_000, System::block_number() + 365 * 86400 / 12, @@ -406,7 +402,7 @@ fn deposit_markup_before_lock_should_work() { Point { bias: 2796030953200, slope: 1046740, block: 20, amount: 11003333333333 } ); assert_eq!(Locked::::get(POSITIONID0).amount, 10_000_000_000_000); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(2796030953200)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(2796030953200)); }); } @@ -416,20 +412,20 @@ fn deposit_markup_before_lock_should_work2() { asset_registry(); System::set_block_number(System::block_number() + 20); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); - assert_ok!(VeMinting::set_markup_coefficient( + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::set_markup_coefficient( RuntimeOrigin::root(), VBNC, FixedU128::from_inner(100_000_000_000_000_000), // 0.1 FixedU128::saturating_from_integer(1), )); - assert_ok!(VeMinting::deposit_markup(RuntimeOrigin::signed(BOB), VBNC, 10_000_000_000_000)); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::deposit_markup(RuntimeOrigin::signed(BOB), VBNC, 10_000_000_000_000)); + assert_ok!(BbBNC::create_lock_inner( &BOB, 10_000_000_000_000, System::block_number() + 365 * 86400 / 12, )); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::create_lock_inner( &BOB, 15_000_000_000_000, System::block_number() + 365 * 86400 / 12, @@ -445,11 +441,11 @@ fn deposit_markup_before_lock_should_work2() { assert_eq!(Locked::::get(POSITIONID0).amount, 10_000_000_000_000); assert_eq!(Locked::::get(POSITIONID1).amount, 15_000_000_000_000); assert_eq!( - VeMinting::balance_of(&BOB, Some(System::block_number())), + BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(2796030953200 + 4194046429800) ); assert_eq!( - VeMinting::balance_of(&BOB, Some(System::block_number())), + BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(2796030953200 + 4194046429800) ); }); @@ -461,13 +457,13 @@ fn deposit_markup_after_lock_should_work2() { asset_registry(); System::set_block_number(System::block_number() + 20); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::create_lock_inner( &BOB, 10_000_000_000_000, System::block_number() + 365 * 86400 / 12, )); - assert_ok!(VeMinting::set_markup_coefficient( + assert_ok!(BbBNC::set_markup_coefficient( RuntimeOrigin::root(), MOVR, FixedU128::from_inner(500_000_000_000_000_000), // 0.5 @@ -484,7 +480,7 @@ fn deposit_markup_after_lock_should_work2() { ); assert_eq!(Tokens::ensure_can_withdraw(MOVR, &BOB, 10_000_000_000_000).is_ok(), true); assert_eq!(UserMarkupInfos::::get(BOB), None); - assert_ok!(VeMinting::deposit_markup(RuntimeOrigin::signed(BOB), MOVR, 9_000_000_000_000)); + assert_ok!(BbBNC::deposit_markup(RuntimeOrigin::signed(BOB), MOVR, 9_000_000_000_000)); assert_eq!( UserMarkupInfos::::get(BOB), Some(UserMarkupInfo { @@ -492,7 +488,7 @@ fn deposit_markup_after_lock_should_work2() { markup_coefficient: FixedU128::from_inner(950_000_000_000_000_000), }) ); - assert_ok!(VeMinting::deposit_markup(RuntimeOrigin::signed(BOB), MOVR, 1_000_000_000_000)); + assert_ok!(BbBNC::deposit_markup(RuntimeOrigin::signed(BOB), MOVR, 1_000_000_000_000)); assert_eq!( UserMarkupInfos::::get(BOB), Some(UserMarkupInfo { @@ -509,7 +505,7 @@ fn deposit_markup_after_lock_should_work2() { Point { bias: 5082152342660, slope: 1902587, block: 20, amount: 20000000000000 } ); assert_eq!(Locked::::get(POSITIONID0).amount, 10_000_000_000_000); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(5082152342660)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(5082152342660)); }); } @@ -519,13 +515,13 @@ fn deposit_markup_after_lock_should_work() { asset_registry(); System::set_block_number(System::block_number() + 20); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::create_lock_inner( &BOB, 10_000_000_000_000, System::block_number() + 365 * 86400 / 12, )); - assert_ok!(VeMinting::set_markup_coefficient( + assert_ok!(BbBNC::set_markup_coefficient( RuntimeOrigin::root(), VBNC, FixedU128::from_inner(100_000_000_000_000_000), // 0.1 @@ -536,13 +532,13 @@ fn deposit_markup_after_lock_should_work() { UserPointHistory::::get(POSITIONID0, U256::from(1)), Point { bias: 2541074835740, slope: 951293, block: 20, amount: 10000000000000 } ); - assert_ok!(VeMinting::deposit_markup(RuntimeOrigin::signed(BOB), VBNC, 10_000_000_000_000)); + assert_ok!(BbBNC::deposit_markup(RuntimeOrigin::signed(BOB), VBNC, 10_000_000_000_000)); assert_eq!( UserPointHistory::::get(POSITIONID0, U256::from(2)), Point { bias: 2796030953200, slope: 1046740, block: 20, amount: 11003333333333 } ); assert_eq!(Locked::::get(POSITIONID0).amount, 10_000_000_000_000); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(2796030953200)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(2796030953200)); }); } @@ -552,20 +548,20 @@ fn withdraw_markup_after_lock_should_work() { asset_registry(); System::set_block_number(System::block_number() + 20); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::create_lock_inner( &BOB, 10_000_000_000_000, System::block_number() + 365 * 86400 / 12, )); - assert_ok!(VeMinting::set_markup_coefficient( + assert_ok!(BbBNC::set_markup_coefficient( RuntimeOrigin::root(), VBNC, FixedU128::from_inner(100_000_000_000_000_000), // 0.1 FixedU128::saturating_from_integer(1), )); - assert_ok!(VeMinting::deposit_markup(RuntimeOrigin::signed(BOB), VBNC, 10_000_000_000_000)); - assert_ok!(VeMinting::withdraw_markup(RuntimeOrigin::signed(BOB), VBNC)); + assert_ok!(BbBNC::deposit_markup(RuntimeOrigin::signed(BOB), VBNC, 10_000_000_000_000)); + assert_ok!(BbBNC::withdraw_markup(RuntimeOrigin::signed(BOB), VBNC)); assert_eq!( UserPointHistory::::get(POSITIONID0, U256::from(2)), Point { bias: 2796030953200, slope: 1046740, block: 20, amount: 11003333333333 } @@ -575,7 +571,7 @@ fn withdraw_markup_after_lock_should_work() { Point { bias: 2541074835740, slope: 951293, block: 20, amount: 10000000000000 } ); assert_eq!(Locked::::get(POSITIONID0).amount, 10_000_000_000_000); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(2541074835740)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(2541074835740)); }); } @@ -585,18 +581,18 @@ fn redeem_unlock_should_work() { asset_registry(); System::set_block_number(System::block_number() + 20); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); - assert_ok!(VeMinting::set_markup_coefficient( + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::set_markup_coefficient( RuntimeOrigin::root(), VKSM, FixedU128::from_inner(FixedU128::DIV / 10), // 0.1 FixedU128::saturating_from_integer(1), )); - assert_ok!(VeMinting::deposit_markup(RuntimeOrigin::signed(BOB), VKSM, 10_000_000_000_000)); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(0)); + assert_ok!(BbBNC::deposit_markup(RuntimeOrigin::signed(BOB), VKSM, 10_000_000_000_000)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(0)); assert_eq!(Tokens::free_balance(VBNC, &BOB), 1000000000000000); assert_eq!(Tokens::ensure_can_withdraw(VBNC, &BOB, 1000000000000000).is_ok(), true); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::create_lock_inner( &BOB, 10_000_000_000_000, System::block_number() + 365 * 86400 / 12, @@ -606,11 +602,11 @@ fn redeem_unlock_should_work() { Point { bias: 5082152342660, slope: 1902587, block: 20, amount: 20000000000000 } ); assert_eq!(Locked::::get(POSITIONID0).amount, 10_000_000_000_000); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(5082152342660)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(5082152342660)); assert_eq!(Tokens::free_balance(VBNC, &BOB), 1_000_000_000_000_000); assert_eq!(Tokens::ensure_can_withdraw(VBNC, &BOB, 1_000_000_000_000_000).is_ok(), false); - assert_ok!(VeMinting::redeem_unlock(RuntimeOrigin::signed(BOB), 0)); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(0)); + assert_ok!(BbBNC::redeem_unlock(RuntimeOrigin::signed(BOB), 0)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(0)); assert_eq!(Tokens::free_balance(VBNC, &BOB), 997451711199422); assert_eq!(Tokens::ensure_can_withdraw(VBNC, &BOB, 997451711199422).is_ok(), true); }); @@ -622,25 +618,25 @@ fn withdraw_markup_after_lock_should_work3() { asset_registry(); System::set_block_number(System::block_number() + 20); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::create_lock_inner( &BOB, 10_000_000_000_000, System::block_number() + 365 * 86400 / 12, )); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::create_lock_inner( &BOB, 15_000_000_000_000, System::block_number() + 365 * 86400 / 12, )); - assert_ok!(VeMinting::set_markup_coefficient( + assert_ok!(BbBNC::set_markup_coefficient( RuntimeOrigin::root(), VBNC, FixedU128::from_inner(100_000_000_000_000_000), // 0.1 FixedU128::saturating_from_integer(1), )); - assert_ok!(VeMinting::deposit_markup(RuntimeOrigin::signed(BOB), VBNC, 10_000_000_000_000)); - assert_ok!(VeMinting::withdraw_markup(RuntimeOrigin::signed(BOB), VBNC)); + assert_ok!(BbBNC::deposit_markup(RuntimeOrigin::signed(BOB), VBNC, 10_000_000_000_000)); + assert_ok!(BbBNC::withdraw_markup(RuntimeOrigin::signed(BOB), VBNC)); assert_eq!( UserPointHistory::::get(POSITIONID0, U256::from(2)), Point { bias: 2796030953200, slope: 1046740, block: 20, amount: 11003333333333 } @@ -659,7 +655,7 @@ fn withdraw_markup_after_lock_should_work3() { ); assert_eq!(Locked::::get(POSITIONID0).amount, 10_000_000_000_000); assert_eq!(Locked::::get(POSITIONID1).amount, 15_000_000_000_000); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(6352688424940)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(6352688424940)); }); } @@ -669,18 +665,18 @@ fn redeem_unlock_after_360_days_should_work() { asset_registry(); System::set_block_number(System::block_number() + 20); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); - assert_ok!(VeMinting::set_markup_coefficient( + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::set_markup_coefficient( RuntimeOrigin::root(), VKSM, FixedU128::from_inner(FixedU128::DIV / 10), // 0.1 FixedU128::saturating_from_integer(1), )); - assert_ok!(VeMinting::deposit_markup(RuntimeOrigin::signed(BOB), VKSM, 10_000_000_000_000)); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(0)); + assert_ok!(BbBNC::deposit_markup(RuntimeOrigin::signed(BOB), VKSM, 10_000_000_000_000)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(0)); assert_eq!(Tokens::free_balance(VBNC, &BOB), 1000000000000000); assert_eq!(Tokens::ensure_can_withdraw(VBNC, &BOB, 1000000000000000).is_ok(), true); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::create_lock_inner( &BOB, 10_000_000_000_000, System::block_number() + 365 * 86400 / 12, @@ -690,12 +686,12 @@ fn redeem_unlock_after_360_days_should_work() { Point { bias: 5082152342660, slope: 1902587, block: 20, amount: 20000000000000 } ); assert_eq!(Locked::::get(POSITIONID0).amount, 10_000_000_000_000); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(5082152342660)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(5082152342660)); assert_eq!(Tokens::free_balance(VBNC, &BOB), 1_000_000_000_000_000); assert_eq!(Tokens::ensure_can_withdraw(VBNC, &BOB, 1_000_000_000_000_000).is_ok(), false); System::set_block_number(System::block_number() + 360 * 86400 / 12); - assert_ok!(VeMinting::redeem_unlock(RuntimeOrigin::signed(BOB), 0)); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(0)); + assert_ok!(BbBNC::redeem_unlock(RuntimeOrigin::signed(BOB), 0)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(0)); assert_eq!(Tokens::free_balance(VBNC, &BOB), 999336664330082); assert_eq!(Tokens::ensure_can_withdraw(VBNC, &BOB, 999336664330082).is_ok(), true); }); @@ -707,23 +703,23 @@ fn redeem_unlock_after_360_days_should_work2() { asset_registry(); System::set_block_number(System::block_number() + 20); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); - assert_ok!(VeMinting::set_markup_coefficient( + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::set_markup_coefficient( RuntimeOrigin::root(), VKSM, FixedU128::from_inner(FixedU128::DIV / 10), // 0.1 FixedU128::saturating_from_integer(1), )); - assert_ok!(VeMinting::deposit_markup(RuntimeOrigin::signed(BOB), VKSM, 10_000_000_000_000)); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(0)); + assert_ok!(BbBNC::deposit_markup(RuntimeOrigin::signed(BOB), VKSM, 10_000_000_000_000)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(0)); assert_eq!(Tokens::free_balance(VBNC, &BOB), 1000000000000000); assert_eq!(Tokens::ensure_can_withdraw(VBNC, &BOB, 1000000000000000).is_ok(), true); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::create_lock_inner( &BOB, 10_000_000_000_000, System::block_number() + 365 * 86400 / 12, )); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::create_lock_inner( &BOB, 15_000_000_000_000, System::block_number() + 365 * 86400 / 12, @@ -738,13 +734,13 @@ fn redeem_unlock_after_360_days_should_work2() { ); assert_eq!(Locked::::get(POSITIONID0).amount, 10_000_000_000_000); assert_eq!(Locked::::get(POSITIONID1).amount, 15_000_000_000_000); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(12705382192240)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(12705382192240)); assert_eq!(Tokens::free_balance(VBNC, &BOB), 1_000_000_000_000_000); assert_eq!(Tokens::ensure_can_withdraw(VBNC, &BOB, 1_000_000_000_000_000).is_ok(), false); System::set_block_number(System::block_number() + 360 * 86400 / 12); - assert_ok!(VeMinting::redeem_unlock(RuntimeOrigin::signed(BOB), POSITIONID0)); - assert_ok!(VeMinting::redeem_unlock(RuntimeOrigin::signed(BOB), POSITIONID1)); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(0)); + assert_ok!(BbBNC::redeem_unlock(RuntimeOrigin::signed(BOB), POSITIONID0)); + assert_ok!(BbBNC::redeem_unlock(RuntimeOrigin::signed(BOB), POSITIONID1)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(0)); assert_eq!(Tokens::free_balance(VBNC, &BOB), 998341660825205); assert_eq!(Tokens::ensure_can_withdraw(VBNC, &BOB, 998341660825205).is_ok(), true); }); @@ -756,21 +752,21 @@ fn refresh_should_work() { asset_registry(); System::set_block_number(System::block_number() + 20); - assert_ok!(VeMinting::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); - assert_ok!(VeMinting::set_markup_coefficient( + assert_ok!(BbBNC::set_config(RuntimeOrigin::root(), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::set_markup_coefficient( RuntimeOrigin::root(), VBNC, FixedU128::from_inner(100_000_000_000_000_000), // 0.1 FixedU128::saturating_from_integer(1), )); - assert_ok!(VeMinting::deposit_markup(RuntimeOrigin::signed(BOB), VBNC, 10_000_000_000_000)); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(0)); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::deposit_markup(RuntimeOrigin::signed(BOB), VBNC, 10_000_000_000_000)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(0)); + assert_ok!(BbBNC::create_lock_inner( &BOB, 10_000_000_000_000, System::block_number() + 365 * 86400 / 12, )); - assert_ok!(VeMinting::set_markup_coefficient( + assert_ok!(BbBNC::set_markup_coefficient( RuntimeOrigin::root(), VBNC, FixedU128::from_inner(200_000_000_000_000_000), // 0.2 @@ -784,7 +780,7 @@ fn refresh_should_work() { UserPointHistory::::get(POSITIONID0, U256::from(2)), Point { bias: 0, slope: 0, block: 0, amount: 0 } ); - assert_ok!(VeMinting::refresh_inner(RuntimeOrigin::signed(BOB), VBNC)); + assert_ok!(BbBNC::refresh_inner(RuntimeOrigin::signed(BOB), VBNC)); assert_eq!( UserPointHistory::::get(POSITIONID0, U256::one()), Point { bias: 2796030953200, slope: 1046740, block: 20, amount: 11003333333333 } @@ -794,8 +790,8 @@ fn refresh_should_work() { Point { bias: 3050984399480, slope: 1142186, block: 20, amount: 12006666666666 } ); assert_eq!(Locked::::get(POSITIONID0).amount, 10_000_000_000_000); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(3050984399480)); - assert_ok!(VeMinting::redeem_unlock(RuntimeOrigin::signed(BOB), 0)); - assert_eq!(VeMinting::balance_of(&BOB, Some(System::block_number())), Ok(0)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(3050984399480)); + assert_ok!(BbBNC::redeem_unlock(RuntimeOrigin::signed(BOB), 0)); + assert_eq!(BbBNC::balance_of(&BOB, Some(System::block_number())), Ok(0)); }); } diff --git a/pallets/ve-minting/src/traits.rs b/pallets/bb-bnc/src/traits.rs similarity index 94% rename from pallets/ve-minting/src/traits.rs rename to pallets/bb-bnc/src/traits.rs index 32e7deb27..3c705aa0e 100644 --- a/pallets/ve-minting/src/traits.rs +++ b/pallets/bb-bnc/src/traits.rs @@ -21,7 +21,7 @@ use bifrost_primitives::PoolId; // Ensure we're `no_std` when compiling for Wasm. use crate::*; -pub trait VeMintingInterface { +pub trait BbBNCInterface { fn deposit_for(_who: &AccountId, position: u128, value: Balance) -> DispatchResult; fn withdraw_inner(who: &AccountId, position: u128) -> DispatchResult; fn balance_of(addr: &AccountId, time: Option) -> Result; @@ -75,7 +75,7 @@ pub trait VeMintingInterface { ) -> DispatchResult; } -impl VeMintingInterface, CurrencyIdOf, BalanceOf, BlockNumberFor> +impl BbBNCInterface, CurrencyIdOf, BalanceOf, BlockNumberFor> for Pallet { fn create_lock_inner( @@ -91,11 +91,12 @@ impl VeMintingInterface, CurrencyIdOf, BalanceOf UserPositions::::insert(who, user_positions); Position::::set(new_position + 1); - let ve_config = Self::ve_configs(); + let ve_config = VeConfigs::::get(); ensure!(_value >= ve_config.min_mint, Error::::BelowMinimumMint); let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); - let _locked: LockedBalance, BlockNumberFor> = Self::locked(new_position); + let _locked: LockedBalance, BlockNumberFor> = + Locked::::get(new_position); let unlock_time: BlockNumberFor = _unlock_time .saturating_add(current_block_number) .checked_div(&T::Week::get()) @@ -132,8 +133,8 @@ impl VeMintingInterface, CurrencyIdOf, BalanceOf position: u128, _unlock_time: BlockNumberFor, ) -> DispatchResult { - let ve_config = Self::ve_configs(); - let _locked: LockedBalance, BlockNumberFor> = Self::locked(position); + let ve_config = VeConfigs::::get(); + let _locked: LockedBalance, BlockNumberFor> = Locked::::get(position); let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); let unlock_time: BlockNumberFor = _unlock_time @@ -172,9 +173,9 @@ impl VeMintingInterface, CurrencyIdOf, BalanceOf position: u128, value: BalanceOf, ) -> DispatchResult { - let ve_config = Self::ve_configs(); + let ve_config = VeConfigs::::get(); ensure!(value >= ve_config.min_mint, Error::::BelowMinimumMint); - let _locked: LockedBalance, BlockNumberFor> = Self::locked(position); + let _locked: LockedBalance, BlockNumberFor> = Locked::::get(position); ensure!(_locked.amount > BalanceOf::::zero(), Error::::LockNotExist); // Need to be executed after create_lock let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); ensure!(_locked.end > current_block_number, Error::::Expired); // Cannot add to expired/non-existent lock @@ -184,12 +185,12 @@ impl VeMintingInterface, CurrencyIdOf, BalanceOf } fn deposit_for(who: &AccountIdOf, position: u128, value: BalanceOf) -> DispatchResult { - let _locked: LockedBalance, BlockNumberFor> = Self::locked(position); + let _locked: LockedBalance, BlockNumberFor> = Locked::::get(position); Self::_deposit_for(who, position, value, Zero::zero(), _locked) } fn withdraw_inner(who: &AccountIdOf, position: u128) -> DispatchResult { - let mut _locked = Self::locked(position); + let mut _locked = Locked::::get(position); let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); ensure!(current_block_number >= _locked.end, Error::::Expired); Self::withdraw_no_ensure(who, position, _locked, None) @@ -214,7 +215,7 @@ impl VeMintingInterface, CurrencyIdOf, BalanceOf } let _mid = (_min + _max + 1) / 2; - if Self::point_history(_mid).block <= _block { + if PointHistory::::get(_mid).block <= _block { _min = _mid } else { _max = _mid - 1 @@ -224,8 +225,8 @@ impl VeMintingInterface, CurrencyIdOf, BalanceOf } fn total_supply(t: BlockNumberFor) -> Result, DispatchError> { - let g_epoch: U256 = Self::epoch(); - let last_point = Self::point_history(g_epoch); + let g_epoch: U256 = Epoch::::get(); + let last_point = PointHistory::::get(g_epoch); Self::supply_at(last_point, t) } @@ -246,7 +247,7 @@ impl VeMintingInterface, CurrencyIdOf, BalanceOf if t_i > t { t_i = t } else { - d_slope = Self::slope_changes(t_i) + d_slope = SlopeChanges::::get(t_i) } last_point.bias = last_point @@ -284,8 +285,8 @@ impl VeMintingInterface, CurrencyIdOf, BalanceOf n: BlockNumberFor, rewards: Vec<(CurrencyIdOf, BalanceOf)>, ) -> DispatchResult { - let conf = Self::incentive_configs(pool_id); - if n == conf.last_update_time + conf.rewards_duration { + let conf = IncentiveConfigs::::get(pool_id); + if n == conf.period_finish { Self::notify_reward_amount(pool_id, &conf.incentive_controller, rewards)?; } Ok(()) @@ -312,7 +313,7 @@ impl VeMintingInterface, CurrencyIdOf, BalanceOf rewards_duration: Option>, controller: Option>, ) { - let mut incentive_config = Self::incentive_configs(pool_id); + let mut incentive_config = IncentiveConfigs::::get(pool_id); if let Some(rewards_duration) = rewards_duration { incentive_config.rewards_duration = rewards_duration; @@ -384,7 +385,7 @@ impl VeMintingInterface, CurrencyIdOf, BalanceOf } impl - VeMintingInterface for () + BbBNCInterface for () where Balance: orml_traits::arithmetic::Zero, { diff --git a/pallets/ve-minting/src/weights.rs b/pallets/bb-bnc/src/weights.rs similarity index 52% rename from pallets/ve-minting/src/weights.rs rename to pallets/bb-bnc/src/weights.rs index 9181daf02..aca971f2c 100644 --- a/pallets/ve-minting/src/weights.rs +++ b/pallets/bb-bnc/src/weights.rs @@ -22,7 +22,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for bifrost_ve_minting +//! Autogenerated weights for bb_bnc //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev //! DATE: 2023-09-14, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` @@ -36,12 +36,12 @@ // --chain=bifrost-polkadot-local // --steps=50 // --repeat=20 -// --pallet=bifrost_ve_minting +// --pallet=bb_bnc // --extrinsic=* // --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./pallets/ve-minting/src/weights.rs +// --output=./pallets/bb-bnc/src/weights.rs // --template=./weight-template/pallet-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -51,7 +51,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; -/// Weight functions needed for bifrost_ve_minting. +/// Weight functions needed for bb_bnc. pub trait WeightInfo { fn set_config() -> Weight; fn create_lock() -> Weight; @@ -69,8 +69,8 @@ pub trait WeightInfo { // For backwards compatibility and tests impl WeightInfo for () { - /// Storage: VeMinting VeConfigs (r:1 w:1) - /// Proof Skipped: VeMinting VeConfigs (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC VeConfigs (r:1 w:1) + /// Proof Skipped: BbBNC VeConfigs (max_values: Some(1), max_size: None, mode: Measured) /// Storage: System Number (r:1 w:0) /// Proof: System Number (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) /// Storage: System ExecutionPhase (r:1 w:0) @@ -88,14 +88,14 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: VeMinting VeConfigs (r:1 w:0) - /// Proof Skipped: VeMinting VeConfigs (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting Locked (r:1 w:1) - /// Proof Skipped: VeMinting Locked (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC VeConfigs (r:1 w:0) + /// Proof Skipped: BbBNC VeConfigs (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC Locked (r:1 w:1) + /// Proof Skipped: BbBNC Locked (max_values: None, max_size: None, mode: Measured) /// Storage: System Number (r:1 w:0) /// Proof: System Number (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: VeMinting Supply (r:1 w:1) - /// Proof Skipped: VeMinting Supply (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC Supply (r:1 w:1) + /// Proof Skipped: BbBNC Supply (max_values: Some(1), max_size: None, mode: Measured) /// Storage: Tokens Accounts (r:2 w:2) /// Proof: Tokens Accounts (max_values: None, max_size: Some(118), added: 2593, mode: MaxEncodedLen) /// Storage: AssetRegistry CurrencyMetadatas (r:1 w:0) @@ -108,22 +108,22 @@ impl WeightInfo for () { /// Proof: System EventCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) /// Storage: System Events (r:1 w:1) /// Proof Skipped: System Events (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting IncentiveConfigs (r:1 w:1) - /// Proof Skipped: VeMinting IncentiveConfigs (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting Epoch (r:1 w:1) - /// Proof Skipped: VeMinting Epoch (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting PointHistory (r:1 w:1) - /// Proof Skipped: VeMinting PointHistory (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting UserPointEpoch (r:1 w:1) - /// Proof Skipped: VeMinting UserPointEpoch (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting Rewards (r:1 w:0) - /// Proof Skipped: VeMinting Rewards (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting SlopeChanges (r:2 w:1) - /// Proof Skipped: VeMinting SlopeChanges (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting UserPointHistory (r:0 w:1) - /// Proof Skipped: VeMinting UserPointHistory (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting UserRewardPerTokenPaid (r:0 w:1) - /// Proof Skipped: VeMinting UserRewardPerTokenPaid (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC IncentiveConfigs (r:1 w:1) + /// Proof Skipped: BbBNC IncentiveConfigs (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC Epoch (r:1 w:1) + /// Proof Skipped: BbBNC Epoch (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC PointHistory (r:1 w:1) + /// Proof Skipped: BbBNC PointHistory (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC UserPointEpoch (r:1 w:1) + /// Proof Skipped: BbBNC UserPointEpoch (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC Rewards (r:1 w:0) + /// Proof Skipped: BbBNC Rewards (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC SlopeChanges (r:2 w:1) + /// Proof Skipped: BbBNC SlopeChanges (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC UserPointHistory (r:0 w:1) + /// Proof Skipped: BbBNC UserPointHistory (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC UserRewardPerTokenPaid (r:0 w:1) + /// Proof Skipped: BbBNC UserRewardPerTokenPaid (max_values: None, max_size: None, mode: Measured) fn create_lock() -> Weight { // Proof Size summary in bytes: // Measured: `1439` @@ -133,14 +133,14 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(19_u64)) .saturating_add(RocksDbWeight::get().writes(14_u64)) } - /// Storage: VeMinting VeConfigs (r:1 w:0) - /// Proof Skipped: VeMinting VeConfigs (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting Locked (r:1 w:1) - /// Proof Skipped: VeMinting Locked (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC VeConfigs (r:1 w:0) + /// Proof Skipped: BbBNC VeConfigs (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC Locked (r:1 w:1) + /// Proof Skipped: BbBNC Locked (max_values: None, max_size: None, mode: Measured) /// Storage: System Number (r:1 w:0) /// Proof: System Number (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: VeMinting Supply (r:1 w:1) - /// Proof Skipped: VeMinting Supply (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC Supply (r:1 w:1) + /// Proof Skipped: BbBNC Supply (max_values: Some(1), max_size: None, mode: Measured) /// Storage: Tokens Accounts (r:2 w:2) /// Proof: Tokens Accounts (max_values: None, max_size: Some(118), added: 2593, mode: MaxEncodedLen) /// Storage: AssetRegistry CurrencyMetadatas (r:1 w:0) @@ -153,22 +153,22 @@ impl WeightInfo for () { /// Proof: System EventCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) /// Storage: System Events (r:1 w:1) /// Proof Skipped: System Events (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting IncentiveConfigs (r:1 w:1) - /// Proof Skipped: VeMinting IncentiveConfigs (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting Epoch (r:1 w:1) - /// Proof Skipped: VeMinting Epoch (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting PointHistory (r:1 w:1) - /// Proof Skipped: VeMinting PointHistory (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting UserPointEpoch (r:1 w:1) - /// Proof Skipped: VeMinting UserPointEpoch (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting UserPointHistory (r:1 w:1) - /// Proof Skipped: VeMinting UserPointHistory (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting Rewards (r:1 w:1) - /// Proof Skipped: VeMinting Rewards (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting UserRewardPerTokenPaid (r:1 w:1) - /// Proof Skipped: VeMinting UserRewardPerTokenPaid (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting SlopeChanges (r:1 w:1) - /// Proof Skipped: VeMinting SlopeChanges (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC IncentiveConfigs (r:1 w:1) + /// Proof Skipped: BbBNC IncentiveConfigs (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC Epoch (r:1 w:1) + /// Proof Skipped: BbBNC Epoch (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC PointHistory (r:1 w:1) + /// Proof Skipped: BbBNC PointHistory (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC UserPointEpoch (r:1 w:1) + /// Proof Skipped: BbBNC UserPointEpoch (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC UserPointHistory (r:1 w:1) + /// Proof Skipped: BbBNC UserPointHistory (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC Rewards (r:1 w:1) + /// Proof Skipped: BbBNC Rewards (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC UserRewardPerTokenPaid (r:1 w:1) + /// Proof Skipped: BbBNC UserRewardPerTokenPaid (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC SlopeChanges (r:1 w:1) + /// Proof Skipped: BbBNC SlopeChanges (max_values: None, max_size: None, mode: Measured) fn increase_amount() -> Weight { // Proof Size summary in bytes: // Measured: `2083` @@ -178,30 +178,30 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(19_u64)) .saturating_add(RocksDbWeight::get().writes(14_u64)) } - /// Storage: VeMinting VeConfigs (r:1 w:0) - /// Proof Skipped: VeMinting VeConfigs (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting Locked (r:1 w:1) - /// Proof Skipped: VeMinting Locked (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC VeConfigs (r:1 w:0) + /// Proof Skipped: BbBNC VeConfigs (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC Locked (r:1 w:1) + /// Proof Skipped: BbBNC Locked (max_values: None, max_size: None, mode: Measured) /// Storage: System Number (r:1 w:0) /// Proof: System Number (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: VeMinting Supply (r:1 w:1) - /// Proof Skipped: VeMinting Supply (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting IncentiveConfigs (r:1 w:1) - /// Proof Skipped: VeMinting IncentiveConfigs (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting Epoch (r:1 w:1) - /// Proof Skipped: VeMinting Epoch (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting PointHistory (r:1 w:1) - /// Proof Skipped: VeMinting PointHistory (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting UserPointEpoch (r:1 w:1) - /// Proof Skipped: VeMinting UserPointEpoch (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting UserPointHistory (r:1 w:1) - /// Proof Skipped: VeMinting UserPointHistory (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting Rewards (r:1 w:1) - /// Proof Skipped: VeMinting Rewards (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting UserRewardPerTokenPaid (r:1 w:1) - /// Proof Skipped: VeMinting UserRewardPerTokenPaid (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting SlopeChanges (r:2 w:2) - /// Proof Skipped: VeMinting SlopeChanges (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC Supply (r:1 w:1) + /// Proof Skipped: BbBNC Supply (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC IncentiveConfigs (r:1 w:1) + /// Proof Skipped: BbBNC IncentiveConfigs (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC Epoch (r:1 w:1) + /// Proof Skipped: BbBNC Epoch (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC PointHistory (r:1 w:1) + /// Proof Skipped: BbBNC PointHistory (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC UserPointEpoch (r:1 w:1) + /// Proof Skipped: BbBNC UserPointEpoch (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC UserPointHistory (r:1 w:1) + /// Proof Skipped: BbBNC UserPointHistory (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC Rewards (r:1 w:1) + /// Proof Skipped: BbBNC Rewards (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC UserRewardPerTokenPaid (r:1 w:1) + /// Proof Skipped: BbBNC UserRewardPerTokenPaid (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC SlopeChanges (r:2 w:2) + /// Proof Skipped: BbBNC SlopeChanges (max_values: None, max_size: None, mode: Measured) /// Storage: Tokens Accounts (r:1 w:0) /// Proof: Tokens Accounts (max_values: None, max_size: Some(118), added: 2593, mode: MaxEncodedLen) /// Storage: System ExecutionPhase (r:1 w:0) @@ -219,12 +219,12 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(17_u64)) .saturating_add(RocksDbWeight::get().writes(13_u64)) } - /// Storage: VeMinting Locked (r:1 w:1) - /// Proof Skipped: VeMinting Locked (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC Locked (r:1 w:1) + /// Proof Skipped: BbBNC Locked (max_values: None, max_size: None, mode: Measured) /// Storage: System Number (r:1 w:0) /// Proof: System Number (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: VeMinting Supply (r:1 w:1) - /// Proof Skipped: VeMinting Supply (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC Supply (r:1 w:1) + /// Proof Skipped: BbBNC Supply (max_values: Some(1), max_size: None, mode: Measured) /// Storage: Tokens Accounts (r:2 w:2) /// Proof: Tokens Accounts (max_values: None, max_size: Some(118), added: 2593, mode: MaxEncodedLen) /// Storage: AssetRegistry CurrencyMetadatas (r:1 w:0) @@ -237,22 +237,22 @@ impl WeightInfo for () { /// Proof: System EventCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) /// Storage: System Events (r:1 w:1) /// Proof Skipped: System Events (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting IncentiveConfigs (r:1 w:1) - /// Proof Skipped: VeMinting IncentiveConfigs (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting Epoch (r:1 w:1) - /// Proof Skipped: VeMinting Epoch (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting PointHistory (r:1 w:105) - /// Proof Skipped: VeMinting PointHistory (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting SlopeChanges (r:104 w:0) - /// Proof Skipped: VeMinting SlopeChanges (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting UserPointEpoch (r:1 w:1) - /// Proof Skipped: VeMinting UserPointEpoch (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting UserPointHistory (r:1 w:1) - /// Proof Skipped: VeMinting UserPointHistory (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting Rewards (r:1 w:1) - /// Proof Skipped: VeMinting Rewards (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting UserRewardPerTokenPaid (r:1 w:1) - /// Proof Skipped: VeMinting UserRewardPerTokenPaid (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC IncentiveConfigs (r:1 w:1) + /// Proof Skipped: BbBNC IncentiveConfigs (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC Epoch (r:1 w:1) + /// Proof Skipped: BbBNC Epoch (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC PointHistory (r:1 w:105) + /// Proof Skipped: BbBNC PointHistory (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC SlopeChanges (r:104 w:0) + /// Proof Skipped: BbBNC SlopeChanges (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC UserPointEpoch (r:1 w:1) + /// Proof Skipped: BbBNC UserPointEpoch (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC UserPointHistory (r:1 w:1) + /// Proof Skipped: BbBNC UserPointHistory (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC Rewards (r:1 w:1) + /// Proof Skipped: BbBNC Rewards (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC UserRewardPerTokenPaid (r:1 w:1) + /// Proof Skipped: BbBNC UserRewardPerTokenPaid (max_values: None, max_size: None, mode: Measured) fn withdraw() -> Weight { // Proof Size summary in bytes: // Measured: `2059` @@ -262,24 +262,24 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(121_u64)) .saturating_add(RocksDbWeight::get().writes(118_u64)) } - /// Storage: VeMinting IncentiveConfigs (r:1 w:1) - /// Proof Skipped: VeMinting IncentiveConfigs (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC IncentiveConfigs (r:1 w:1) + /// Proof Skipped: BbBNC IncentiveConfigs (max_values: Some(1), max_size: None, mode: Measured) /// Storage: System Number (r:1 w:0) /// Proof: System Number (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: VeMinting Epoch (r:1 w:0) - /// Proof Skipped: VeMinting Epoch (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting PointHistory (r:1 w:0) - /// Proof Skipped: VeMinting PointHistory (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting SlopeChanges (r:104 w:0) - /// Proof Skipped: VeMinting SlopeChanges (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting UserPointEpoch (r:1 w:0) - /// Proof Skipped: VeMinting UserPointEpoch (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting UserPointHistory (r:1 w:0) - /// Proof Skipped: VeMinting UserPointHistory (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting Rewards (r:1 w:1) - /// Proof Skipped: VeMinting Rewards (max_values: None, max_size: None, mode: Measured) - /// Storage: VeMinting UserRewardPerTokenPaid (r:1 w:1) - /// Proof Skipped: VeMinting UserRewardPerTokenPaid (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC Epoch (r:1 w:0) + /// Proof Skipped: BbBNC Epoch (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC PointHistory (r:1 w:0) + /// Proof Skipped: BbBNC PointHistory (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC SlopeChanges (r:104 w:0) + /// Proof Skipped: BbBNC SlopeChanges (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC UserPointEpoch (r:1 w:0) + /// Proof Skipped: BbBNC UserPointEpoch (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC UserPointHistory (r:1 w:0) + /// Proof Skipped: BbBNC UserPointHistory (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC Rewards (r:1 w:1) + /// Proof Skipped: BbBNC Rewards (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC UserRewardPerTokenPaid (r:1 w:1) + /// Proof Skipped: BbBNC UserRewardPerTokenPaid (max_values: None, max_size: None, mode: Measured) /// Storage: Balances TotalIssuance (r:1 w:1) /// Proof: Balances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) /// Storage: System Account (r:3 w:3) @@ -299,8 +299,8 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(119_u64)) .saturating_add(RocksDbWeight::get().writes(9_u64)) } - /// Storage: VeMinting IncentiveConfigs (r:1 w:1) - /// Proof Skipped: VeMinting IncentiveConfigs (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC IncentiveConfigs (r:1 w:1) + /// Proof Skipped: BbBNC IncentiveConfigs (max_values: Some(1), max_size: None, mode: Measured) /// Storage: System Number (r:1 w:0) /// Proof: System Number (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) /// Storage: System ExecutionPhase (r:1 w:0) @@ -309,10 +309,10 @@ impl WeightInfo for () { /// Proof: System EventCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) /// Storage: System Events (r:1 w:1) /// Proof Skipped: System Events (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting Epoch (r:1 w:0) - /// Proof Skipped: VeMinting Epoch (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: VeMinting PointHistory (r:1 w:0) - /// Proof Skipped: VeMinting PointHistory (max_values: None, max_size: None, mode: Measured) + /// Storage: BbBNC Epoch (r:1 w:0) + /// Proof Skipped: BbBNC Epoch (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: BbBNC PointHistory (r:1 w:0) + /// Proof Skipped: BbBNC PointHistory (max_values: None, max_size: None, mode: Measured) /// Storage: System Account (r:2 w:2) /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// Storage: Balances TotalIssuance (r:1 w:0) @@ -326,12 +326,12 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(10_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `VeMinting::TotalLock` (r:1 w:1) - /// Proof: `VeMinting::TotalLock` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::TotalLock` (r:1 w:1) + /// Proof: `BbBNC::TotalLock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `System::Number` (r:1 w:0) /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VeMinting::MarkupCoefficient` (r:0 w:1) - /// Proof: `VeMinting::MarkupCoefficient` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::MarkupCoefficient` (r:0 w:1) + /// Proof: `BbBNC::MarkupCoefficient` (`max_values`: None, `max_size`: None, mode: `Measured`) fn set_markup_coefficient() -> Weight { // Proof Size summary in bytes: // Measured: `213` @@ -342,16 +342,16 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(2)) .saturating_add(RocksDbWeight::get().writes(2)) } - /// Storage: `VeMinting::MarkupCoefficient` (r:1 w:0) - /// Proof: `VeMinting::MarkupCoefficient` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::TotalLock` (r:1 w:1) - /// Proof: `VeMinting::TotalLock` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::MarkupCoefficient` (r:1 w:0) + /// Proof: `BbBNC::MarkupCoefficient` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::TotalLock` (r:1 w:1) + /// Proof: `BbBNC::TotalLock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `System::Number` (r:1 w:0) /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VeMinting::UserMarkupInfos` (r:1 w:1) - /// Proof: `VeMinting::UserMarkupInfos` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::LockedTokens` (r:1 w:1) - /// Proof: `VeMinting::LockedTokens` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserMarkupInfos` (r:1 w:1) + /// Proof: `BbBNC::UserMarkupInfos` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::LockedTokens` (r:1 w:1) + /// Proof: `BbBNC::LockedTokens` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Tokens::Locks` (r:1 w:1) /// Proof: `Tokens::Locks` (`max_values`: None, `max_size`: Some(1271), added: 3746, mode: `MaxEncodedLen`) /// Storage: `Tokens::Accounts` (r:1 w:1) @@ -364,28 +364,28 @@ impl WeightInfo for () { /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `System::Events` (r:1 w:1) /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserPositions` (r:1 w:0) - /// Proof: `VeMinting::UserPositions` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::Locked` (r:1 w:0) - /// Proof: `VeMinting::Locked` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::IncentiveConfigs` (r:1 w:1) - /// Proof: `VeMinting::IncentiveConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::Epoch` (r:1 w:1) - /// Proof: `VeMinting::Epoch` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::PointHistory` (r:1 w:105) - /// Proof: `VeMinting::PointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::SlopeChanges` (r:104 w:0) - /// Proof: `VeMinting::SlopeChanges` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserPointEpoch` (r:1 w:1) - /// Proof: `VeMinting::UserPointEpoch` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserPointHistory` (r:1 w:1) - /// Proof: `VeMinting::UserPointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::Rewards` (r:1 w:1) - /// Proof: `VeMinting::Rewards` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserRewardPerTokenPaid` (r:1 w:1) - /// Proof: `VeMinting::UserRewardPerTokenPaid` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::Supply` (r:1 w:0) - /// Proof: `VeMinting::Supply` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserPositions` (r:1 w:0) + /// Proof: `BbBNC::UserPositions` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Locked` (r:1 w:0) + /// Proof: `BbBNC::Locked` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::IncentiveConfigs` (r:1 w:1) + /// Proof: `BbBNC::IncentiveConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Epoch` (r:1 w:1) + /// Proof: `BbBNC::Epoch` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::PointHistory` (r:1 w:105) + /// Proof: `BbBNC::PointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::SlopeChanges` (r:104 w:0) + /// Proof: `BbBNC::SlopeChanges` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserPointEpoch` (r:1 w:1) + /// Proof: `BbBNC::UserPointEpoch` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserPointHistory` (r:1 w:1) + /// Proof: `BbBNC::UserPointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Rewards` (r:1 w:1) + /// Proof: `BbBNC::Rewards` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserRewardPerTokenPaid` (r:1 w:1) + /// Proof: `BbBNC::UserRewardPerTokenPaid` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Supply` (r:1 w:0) + /// Proof: `BbBNC::Supply` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn deposit_markup() -> Weight { // Proof Size summary in bytes: // Measured: `2260` @@ -396,14 +396,14 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(125)) .saturating_add(RocksDbWeight::get().writes(118)) } - /// Storage: `VeMinting::MarkupCoefficient` (r:1 w:0) - /// Proof: `VeMinting::MarkupCoefficient` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserMarkupInfos` (r:1 w:1) - /// Proof: `VeMinting::UserMarkupInfos` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::LockedTokens` (r:1 w:1) - /// Proof: `VeMinting::LockedTokens` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::TotalLock` (r:1 w:1) - /// Proof: `VeMinting::TotalLock` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::MarkupCoefficient` (r:1 w:0) + /// Proof: `BbBNC::MarkupCoefficient` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserMarkupInfos` (r:1 w:1) + /// Proof: `BbBNC::UserMarkupInfos` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::LockedTokens` (r:1 w:1) + /// Proof: `BbBNC::LockedTokens` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::TotalLock` (r:1 w:1) + /// Proof: `BbBNC::TotalLock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Tokens::Locks` (r:1 w:1) /// Proof: `Tokens::Locks` (`max_values`: None, `max_size`: Some(1271), added: 3746, mode: `MaxEncodedLen`) /// Storage: `Tokens::Accounts` (r:1 w:1) @@ -418,28 +418,28 @@ impl WeightInfo for () { /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `System::Events` (r:1 w:1) /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserPositions` (r:1 w:0) - /// Proof: `VeMinting::UserPositions` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::Locked` (r:1 w:0) - /// Proof: `VeMinting::Locked` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::IncentiveConfigs` (r:1 w:1) - /// Proof: `VeMinting::IncentiveConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::Epoch` (r:1 w:1) - /// Proof: `VeMinting::Epoch` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::PointHistory` (r:1 w:105) - /// Proof: `VeMinting::PointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::SlopeChanges` (r:104 w:0) - /// Proof: `VeMinting::SlopeChanges` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserPointEpoch` (r:1 w:1) - /// Proof: `VeMinting::UserPointEpoch` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserPointHistory` (r:1 w:1) - /// Proof: `VeMinting::UserPointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::Rewards` (r:1 w:1) - /// Proof: `VeMinting::Rewards` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserRewardPerTokenPaid` (r:1 w:1) - /// Proof: `VeMinting::UserRewardPerTokenPaid` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::Supply` (r:1 w:0) - /// Proof: `VeMinting::Supply` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserPositions` (r:1 w:0) + /// Proof: `BbBNC::UserPositions` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Locked` (r:1 w:0) + /// Proof: `BbBNC::Locked` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::IncentiveConfigs` (r:1 w:1) + /// Proof: `BbBNC::IncentiveConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Epoch` (r:1 w:1) + /// Proof: `BbBNC::Epoch` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::PointHistory` (r:1 w:105) + /// Proof: `BbBNC::PointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::SlopeChanges` (r:104 w:0) + /// Proof: `BbBNC::SlopeChanges` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserPointEpoch` (r:1 w:1) + /// Proof: `BbBNC::UserPointEpoch` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserPointHistory` (r:1 w:1) + /// Proof: `BbBNC::UserPointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Rewards` (r:1 w:1) + /// Proof: `BbBNC::Rewards` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserRewardPerTokenPaid` (r:1 w:1) + /// Proof: `BbBNC::UserRewardPerTokenPaid` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Supply` (r:1 w:0) + /// Proof: `BbBNC::Supply` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn withdraw_markup() -> Weight { // Proof Size summary in bytes: // Measured: `2725` @@ -450,16 +450,16 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(125)) .saturating_add(RocksDbWeight::get().writes(118)) } - /// Storage: `VeMinting::Locked` (r:1 w:1) - /// Proof: `VeMinting::Locked` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Locked` (r:1 w:1) + /// Proof: `BbBNC::Locked` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `System::Number` (r:1 w:0) /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VeMinting::Supply` (r:1 w:1) - /// Proof: `VeMinting::Supply` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserPositions` (r:1 w:1) - /// Proof: `VeMinting::UserPositions` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserLocked` (r:1 w:1) - /// Proof: `VeMinting::UserLocked` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Supply` (r:1 w:1) + /// Proof: `BbBNC::Supply` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserPositions` (r:1 w:1) + /// Proof: `BbBNC::UserPositions` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserLocked` (r:1 w:1) + /// Proof: `BbBNC::UserLocked` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Tokens::Accounts` (r:2 w:2) /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(118), added: 2593, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::CurrencyMetadatas` (r:1 w:0) @@ -472,22 +472,22 @@ impl WeightInfo for () { /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `System::Events` (r:1 w:1) /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::IncentiveConfigs` (r:1 w:1) - /// Proof: `VeMinting::IncentiveConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::Epoch` (r:1 w:1) - /// Proof: `VeMinting::Epoch` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::PointHistory` (r:1 w:105) - /// Proof: `VeMinting::PointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::SlopeChanges` (r:104 w:0) - /// Proof: `VeMinting::SlopeChanges` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::Rewards` (r:1 w:1) - /// Proof: `VeMinting::Rewards` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserRewardPerTokenPaid` (r:1 w:1) - /// Proof: `VeMinting::UserRewardPerTokenPaid` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserPointHistory` (r:0 w:1) - /// Proof: `VeMinting::UserPointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserPointEpoch` (r:0 w:1) - /// Proof: `VeMinting::UserPointEpoch` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::IncentiveConfigs` (r:1 w:1) + /// Proof: `BbBNC::IncentiveConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Epoch` (r:1 w:1) + /// Proof: `BbBNC::Epoch` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::PointHistory` (r:1 w:105) + /// Proof: `BbBNC::PointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::SlopeChanges` (r:104 w:0) + /// Proof: `BbBNC::SlopeChanges` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Rewards` (r:1 w:1) + /// Proof: `BbBNC::Rewards` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserRewardPerTokenPaid` (r:1 w:1) + /// Proof: `BbBNC::UserRewardPerTokenPaid` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserPointHistory` (r:0 w:1) + /// Proof: `BbBNC::UserPointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserPointEpoch` (r:0 w:1) + /// Proof: `BbBNC::UserPointEpoch` (`max_values`: None, `max_size`: None, mode: `Measured`) fn redeem_unlock() -> Weight { // Proof Size summary in bytes: // Measured: `2525` @@ -498,36 +498,36 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(122)) .saturating_add(RocksDbWeight::get().writes(120)) } - /// Storage: `VeMinting::MarkupCoefficient` (r:1 w:0) - /// Proof: `VeMinting::MarkupCoefficient` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::MarkupCoefficient` (r:1 w:0) + /// Proof: `BbBNC::MarkupCoefficient` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `System::Number` (r:1 w:0) /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VeMinting::LockedTokens` (r:2 w:1) - /// Proof: `VeMinting::LockedTokens` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserMarkupInfos` (r:1 w:1) - /// Proof: `VeMinting::UserMarkupInfos` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserPositions` (r:1 w:0) - /// Proof: `VeMinting::UserPositions` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::Locked` (r:1 w:0) - /// Proof: `VeMinting::Locked` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::IncentiveConfigs` (r:1 w:1) - /// Proof: `VeMinting::IncentiveConfigs` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::Epoch` (r:1 w:1) - /// Proof: `VeMinting::Epoch` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::PointHistory` (r:1 w:1) - /// Proof: `VeMinting::PointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserPointEpoch` (r:1 w:1) - /// Proof: `VeMinting::UserPointEpoch` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserPointHistory` (r:1 w:1) - /// Proof: `VeMinting::UserPointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::Rewards` (r:1 w:1) - /// Proof: `VeMinting::Rewards` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::UserRewardPerTokenPaid` (r:1 w:1) - /// Proof: `VeMinting::UserRewardPerTokenPaid` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::SlopeChanges` (r:1 w:1) - /// Proof: `VeMinting::SlopeChanges` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `VeMinting::Supply` (r:1 w:0) - /// Proof: `VeMinting::Supply` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::LockedTokens` (r:2 w:1) + /// Proof: `BbBNC::LockedTokens` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserMarkupInfos` (r:1 w:1) + /// Proof: `BbBNC::UserMarkupInfos` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserPositions` (r:1 w:0) + /// Proof: `BbBNC::UserPositions` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Locked` (r:1 w:0) + /// Proof: `BbBNC::Locked` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::IncentiveConfigs` (r:1 w:1) + /// Proof: `BbBNC::IncentiveConfigs` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Epoch` (r:1 w:1) + /// Proof: `BbBNC::Epoch` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::PointHistory` (r:1 w:1) + /// Proof: `BbBNC::PointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserPointEpoch` (r:1 w:1) + /// Proof: `BbBNC::UserPointEpoch` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserPointHistory` (r:1 w:1) + /// Proof: `BbBNC::UserPointHistory` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Rewards` (r:1 w:1) + /// Proof: `BbBNC::Rewards` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::UserRewardPerTokenPaid` (r:1 w:1) + /// Proof: `BbBNC::UserRewardPerTokenPaid` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::SlopeChanges` (r:1 w:1) + /// Proof: `BbBNC::SlopeChanges` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `BbBNC::Supply` (r:1 w:0) + /// Proof: `BbBNC::Supply` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn refresh() -> Weight { // Proof Size summary in bytes: // Measured: `1687` diff --git a/pallets/buy-back/Cargo.toml b/pallets/buy-back/Cargo.toml index 38a9f9ba5..1279d6a9f 100644 --- a/pallets/buy-back/Cargo.toml +++ b/pallets/buy-back/Cargo.toml @@ -10,6 +10,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] bifrost-primitives = { workspace = true } bifrost-slp = { workspace = true } +bb-bnc = { workspace = true } bifrost-vtoken-minting = { workspace = true } cumulus-primitives-core = { workspace = true } frame-benchmarking = { workspace = true, optional = true } @@ -27,11 +28,11 @@ sp-runtime = { workspace = true } sp-std = { workspace = true } xcm = { workspace = true } zenlink-protocol = { workspace = true } -bifrost-ve-minting = { workspace = true } [dev-dependencies] bifrost-asset-registry = { workspace = true } bifrost-currencies = { workspace = true } +bifrost-runtime-common = { workspace = true } orml-tokens = { workspace = true } orml-traits = { workspace = true } orml-xtokens = { workspace = true } @@ -45,25 +46,27 @@ env_logger = { workspace = true } [features] default = ["std"] std = [ - "parity-scale-codec/std", - "scale-info/std", - "sp-runtime/std", + "bifrost-asset-registry/std", + "bifrost-primitives/std", + "bifrost-runtime-common/std", + "bifrost-slp/std", + "bifrost-vtoken-minting/std", + "frame-benchmarking/std", "frame-support/std", "frame-system/std", - "frame-benchmarking/std", - "bifrost-primitives/std", "orml-traits/std", - "bifrost-vtoken-minting/std", - "zenlink-protocol/std", - "bifrost-slp/std", - "bifrost-asset-registry/std", "orml-xtokens/std", + "parity-scale-codec/std", + "scale-info/std", + "sp-runtime/std", + "zenlink-protocol/std", ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", - "xcm-builder/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", + ] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/buy-back/src/benchmarking.rs b/pallets/buy-back/src/benchmarking.rs index 1b2ee3f10..c015d581d 100644 --- a/pallets/buy-back/src/benchmarking.rs +++ b/pallets/buy-back/src/benchmarking.rs @@ -21,7 +21,7 @@ #![cfg(feature = "runtime-benchmarks")] use crate::{BalanceOf, Call, Config, Pallet, Pallet as BuyBack, *}; -use bifrost_primitives::{CurrencyId, TokenSymbol, DOT}; +use bifrost_primitives::VDOT; use frame_benchmarking::v1::{account, benchmarks, BenchmarkError}; use frame_support::{ assert_ok, @@ -34,41 +34,45 @@ use sp_runtime::traits::UniqueSaturatedFrom; benchmarks! { set_vtoken { let origin = T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - }: _(origin,CurrencyId::VToken(TokenSymbol::KSM),1_000_000u32.into(),Permill::from_percent(2),1000u32.into(),1000u32.into(),true) + }: _(origin,VDOT,1_000_000u32.into(),Permill::from_percent(2),1000u32.into(),1000u32.into(),true,Some(Permill::from_percent(2)),Permill::from_percent(2)) charge { let test_account: T::AccountId = account("seed",1,1); - T::MultiCurrency::deposit(DOT, &test_account, BalanceOf::::unique_saturated_from(1_000_000_000_000_000u128))?; - }: _(RawOrigin::Signed(test_account),DOT,BalanceOf::::unique_saturated_from(9_000_000_000_000u128)) + T::MultiCurrency::deposit(VDOT, &test_account, BalanceOf::::unique_saturated_from(1_000_000_000_000_000u128))?; + }: _(RawOrigin::Signed(test_account),VDOT,BalanceOf::::unique_saturated_from(9_000_000_000_000u128)) remove_vtoken { let origin = T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; assert_ok!(BuyBack::::set_vtoken( T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?, - CurrencyId::VToken(TokenSymbol::KSM), + VDOT, 1_000_000u32.into(), Permill::from_percent(2), 1000u32.into(), 1000u32.into(), - true + true, + Some(Permill::from_percent(2)), + Permill::from_percent(2) )); - }: _(origin,CurrencyId::Token(TokenSymbol::KSM)) + }: _(origin,VDOT) - on_idle { + on_initialize { let origin = T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; assert_ok!(BuyBack::::set_vtoken( T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?, - CurrencyId::VToken(TokenSymbol::KSM), + VDOT, 1_000_000u32.into(), Permill::from_percent(2), 1000u32.into(), 1000u32.into(), - true + true, + Some(Permill::from_percent(2)), + Permill::from_percent(2) )); }: { - BuyBack::::on_idle(BlockNumberFor::::from(0u32),Weight::from_parts(0, u64::MAX)); + BuyBack::::on_initialize(BlockNumberFor::::from(0u32)); } impl_benchmark_test_suite!(BuyBack,crate::mock::ExtBuilder::default().build(),crate::mock::Runtime); diff --git a/pallets/buy-back/src/lib.rs b/pallets/buy-back/src/lib.rs index 7504adf3e..b3ea80623 100644 --- a/pallets/buy-back/src/lib.rs +++ b/pallets/buy-back/src/lib.rs @@ -30,23 +30,21 @@ mod benchmarking; pub mod weights; -use bifrost_primitives::{ - currency::BNC, CurrencyId, CurrencyIdConversion, CurrencyIdRegister, TryConvertFrom, -}; -use bifrost_ve_minting::VeMintingInterface; +use bb_bnc::BbBNCInterface; +use bifrost_primitives::{currency::BNC, CurrencyId, CurrencyIdRegister, TryConvertFrom}; use cumulus_primitives_core::ParaId; use frame_support::{ pallet_prelude::*, sp_runtime::{ - traits::{AccountIdConversion, Zero}, - Permill, SaturatedConversion, + traits::{AccountIdConversion, One, Zero}, + Permill, SaturatedConversion, Saturating, }, transactional, PalletId, }; use frame_system::pallet_prelude::*; use orml_traits::MultiCurrency; pub use pallet::*; -use sp_std::vec; +use sp_std::{vec, vec::Vec}; pub use weights::WeightInfo; use zenlink_protocol::{AssetId, ExportZenlink}; @@ -78,14 +76,9 @@ pub mod pallet { type DexOperator: ExportZenlink; - type CurrencyIdConversion: CurrencyIdConversion; - #[pallet::constant] type TreasuryAccount: Get; - #[pallet::constant] - type RelayChainToken: Get; - #[pallet::constant] type BuyBackAccount: Get; @@ -96,7 +89,7 @@ pub mod pallet { type CurrencyIdRegister: CurrencyIdRegister; - type VeMinting: VeMintingInterface< + type BbBNC: BbBNCInterface< AccountIdOf, CurrencyIdOf, BalanceOf, @@ -107,85 +100,203 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - Charged { who: AccountIdOf, asset_id: CurrencyIdOf, value: BalanceOf }, - ConfigSet { asset_id: CurrencyIdOf, info: Info, BlockNumberFor> }, - Removed { asset_id: CurrencyIdOf }, - BuyBackFailed { asset_id: CurrencyIdOf, block_number: BlockNumberFor }, - BuyBackSuccess { asset_id: CurrencyIdOf, block_number: BlockNumberFor }, - AddLiquidityFailed { asset_id: CurrencyIdOf, block_number: BlockNumberFor }, - AddLiquiditySuccess { asset_id: CurrencyIdOf, block_number: BlockNumberFor }, + /// A successful call of the `Charge` extrinsic will create this event. + Charged { who: AccountIdOf, currency_id: CurrencyIdOf, value: BalanceOf }, + /// A successful call of the `SetVtoken` extrinsic will create this event. + ConfigSet { currency_id: CurrencyIdOf, info: Info, BlockNumberFor> }, + /// A successful call of the `RemoveVtoken` extrinsic will create this event. + Removed { currency_id: CurrencyIdOf }, + /// A failed call of the `BuyBack` extrinsic will create this event. + BuyBackFailed { currency_id: CurrencyIdOf, block_number: BlockNumberFor }, + /// A successful call of the `BuyBack` extrinsic will create this event. + BuyBackSuccess { currency_id: CurrencyIdOf, block_number: BlockNumberFor }, + /// A failed call of the `AddLiquidity` extrinsic will create this event. + AddLiquidityFailed { currency_id: CurrencyIdOf, block_number: BlockNumberFor }, + /// A successful call of the `AddLiquidity` extrinsic will create this event. + AddLiquiditySuccess { currency_id: CurrencyIdOf, block_number: BlockNumberFor }, + /// A failed call of the `SetSwapOutMin` extrinsic will create this event. + SetSwapOutMinFailed { currency_id: CurrencyIdOf, block_number: BlockNumberFor }, + /// A successful call of the `SetSwapOutMin` extrinsic will create this event. + SetSwapOutMinSuccess { currency_id: CurrencyIdOf, block_number: BlockNumberFor }, } #[pallet::error] pub enum Error { - ArgumentsError, + /// Insufficient balance. NotEnoughBalance, + /// Currency does not exist. + CurrencyIdNotExists, + /// Currency is not supported. + CurrencyIdError, + /// Duration can't be zero. + ZeroDuration, + /// Field min_swap_value can't be zero. + ZeroMinSwapValue, } #[pallet::storage] - #[pallet::getter(fn configs)] pub type Infos = StorageMap<_, Twox64Concat, CurrencyIdOf, Info, BlockNumberFor>>; + #[pallet::storage] + pub type SwapOutMin = StorageMap<_, Twox64Concat, CurrencyIdOf, u128>; + + #[pallet::storage] + pub type AddLiquiditySwapOutMin = StorageMap<_, Twox64Concat, CurrencyIdOf, u128>; + + /// Information on buybacks and add liquidity #[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo)] pub struct Info { - value: BalanceOf, + /// The minimum value of the token to be swapped. + min_swap_value: BalanceOf, + /// Whether to automatically add liquidity and buy back. if_auto: bool, + /// The proportion of the token to be added to the liquidity pool. proportion: Permill, + /// The duration of the buyback. buyback_duration: BlockNumberFor, + /// The last time the buyback was executed. last_buyback: BlockNumberFor, + /// The end block of the last buyback cycle. + last_buyback_cycle: BlockNumberFor, + /// The duration of adding liquidity. add_liquidity_duration: BlockNumberFor, + /// The last time liquidity was added. last_add_liquidity: BlockNumberFor, + /// The destruction ratio of BNC. + destruction_ratio: Option, + /// The bias of the token value to be swapped. + bias: Permill, } #[pallet::hooks] impl Hooks> for Pallet { - fn on_idle(n: BlockNumberFor, _remaining_weight: Weight) -> Weight { + fn on_initialize(n: BlockNumberFor) -> Weight { let buyback_address = T::BuyBackAccount::get().into_account_truncating(); let liquidity_address = T::LiquidityAccount::get().into_account_truncating(); - for (asset_id, mut info) in Infos::::iter() { + for (currency_id, mut info) in Infos::::iter() { if !info.if_auto { continue; } - if info.last_add_liquidity == BlockNumberFor::::from(0u32) || - info.last_add_liquidity + info.add_liquidity_duration == n - { - if let Some(e) = Self::add_liquidity(&liquidity_address, asset_id, &info).err() - { - log::error!( - target: "runtime::add_liquidity", - "Received invalid justification for {:?}", - e, - ); - Self::deposit_event(Event::AddLiquidityFailed { - asset_id, - block_number: n, - }); - } else { - Self::deposit_event(Event::AddLiquiditySuccess { - asset_id, - block_number: n, - }); - } - info.last_add_liquidity = n; - Infos::::insert(asset_id, info.clone()); + match info.last_add_liquidity + info.add_liquidity_duration { + target_block if target_block.saturating_sub(One::one()) == n => { + if let Some(e) = Self::set_add_liquidity_swap_out_min( + &liquidity_address, + currency_id, + &info, + ) + .err() + { + log::error!( + target: "buy-back::set_add_liquidity_swap_out_min", + "Received invalid justification for {:?}", + e, + ); + Self::deposit_event(Event::SetSwapOutMinFailed { + currency_id, + block_number: n, + }); + } else { + Self::deposit_event(Event::SetSwapOutMinSuccess { + currency_id, + block_number: n, + }); + } + }, + target_block if target_block == n => { + if let Some(swap_out_min) = AddLiquiditySwapOutMin::::get(currency_id) { + if let Some(e) = Self::add_liquidity( + &liquidity_address, + currency_id, + &info, + swap_out_min, + ) + .err() + { + log::error!( + target: "buy-back::add_liquidity", + "Received invalid justification for {:?}", + e, + ); + Self::deposit_event(Event::AddLiquidityFailed { + currency_id, + block_number: n, + }); + } else { + Self::deposit_event(Event::AddLiquiditySuccess { + currency_id, + block_number: n, + }); + } + info.last_add_liquidity = + info.last_add_liquidity + info.add_liquidity_duration; + Infos::::insert(currency_id, info.clone()); + AddLiquiditySwapOutMin::::remove(currency_id); + } + }, + _ => (), } - if info.last_buyback == BlockNumberFor::::from(0u32) || - info.last_buyback + info.buyback_duration == n - { - if let Some(e) = Self::buy_back(&buyback_address, asset_id, &info).err() { - log::error!( - target: "runtime::buy_back", - "Received invalid justification for {:?}", - e, - ); - Self::deposit_event(Event::BuyBackFailed { asset_id, block_number: n }); - } else { - Self::deposit_event(Event::BuyBackSuccess { asset_id, block_number: n }); - } - info.last_buyback = n; - Infos::::insert(asset_id, info); + + // If the previous period has not ended, continue with the next currency. + if info.last_buyback_cycle >= n { + continue; + } + match Self::get_target_block(info.last_buyback, info.buyback_duration) { + target_block + if target_block == + n.saturating_sub(info.last_buyback_cycle) + .saturated_into::() => + { + if let Some(e) = Self::set_swap_out_min(currency_id, &info).err() { + log::error!( + target: "buy-back::set_swap_out_min", + "Received invalid justification for {:?}", + e, + ); + Self::deposit_event(Event::SetSwapOutMinFailed { + currency_id, + block_number: n, + }); + } else { + Self::deposit_event(Event::SetSwapOutMinSuccess { + currency_id, + block_number: n, + }); + } + }, + target_block + if target_block == + n.saturating_sub(info.last_buyback_cycle) + .saturated_into::() + .saturating_sub(One::one()) => + if let Some(swap_out_min) = SwapOutMin::::get(currency_id) { + if let Some(e) = + Self::buy_back(&buyback_address, currency_id, &info, swap_out_min) + .err() + { + log::error!( + target: "buy-back::buy_back", + "Received invalid justification for {:?}", + e, + ); + Self::deposit_event(Event::BuyBackFailed { + currency_id, + block_number: n, + }); + } else { + Self::deposit_event(Event::BuyBackSuccess { + currency_id, + block_number: n, + }); + } + info.last_buyback_cycle = + info.last_buyback_cycle.saturating_add(info.buyback_duration); + info.last_buyback = n; + Infos::::insert(currency_id, info); + SwapOutMin::::remove(currency_id); + }, + _ => (), } } T::WeightInfo::on_idle() @@ -194,77 +305,81 @@ pub mod pallet { #[pallet::call] impl Pallet { + /// Configuration for setting up buybacks and adding liquidity. #[pallet::call_index(0)] #[pallet::weight(T::WeightInfo::set_vtoken())] pub fn set_vtoken( origin: OriginFor, - asset_id: CurrencyIdOf, - value: BalanceOf, + currency_id: CurrencyIdOf, + min_swap_value: BalanceOf, proportion: Permill, buyback_duration: BlockNumberFor, add_liquidity_duration: BlockNumberFor, if_auto: bool, + destruction_ratio: Option, + bias: Permill, ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - match asset_id { - CurrencyId::Token(token_symbol) => - if !T::CurrencyIdRegister::check_vtoken_registered(token_symbol) { - return Err(Error::::ArgumentsError.into()); - }, - CurrencyId::Token2(token_id) => { - if !T::CurrencyIdRegister::check_vtoken2_registered(token_id) { - return Err(Error::::ArgumentsError.into()); - } - }, - _ => (), - }; + Self::check_currency_id(currency_id)?; + ensure!(min_swap_value > Zero::zero(), Error::::ZeroMinSwapValue); + ensure!(buyback_duration > Zero::zero(), Error::::ZeroDuration); + ensure!(add_liquidity_duration > Zero::zero(), Error::::ZeroDuration); + + let now = frame_system::Pallet::::block_number(); let info = Info { - value, + min_swap_value, if_auto, proportion, buyback_duration, - last_buyback: BlockNumberFor::::from(0u32), + last_buyback: now, + last_buyback_cycle: now, add_liquidity_duration, - last_add_liquidity: BlockNumberFor::::from(0u32), + last_add_liquidity: now, + destruction_ratio, + bias, }; - Infos::::insert(asset_id, info.clone()); + Infos::::insert(currency_id, info.clone()); - Self::deposit_event(Event::ConfigSet { asset_id, info }); + Self::deposit_event(Event::ConfigSet { currency_id, info }); Ok(()) } + /// Charge the buyback account. #[pallet::call_index(1)] #[pallet::weight(T::WeightInfo::charge())] pub fn charge( origin: OriginFor, - asset_id: CurrencyIdOf, + currency_id: CurrencyIdOf, value: BalanceOf, ) -> DispatchResult { let exchanger = ensure_signed(origin)?; + Self::check_currency_id(currency_id)?; T::MultiCurrency::transfer( - asset_id, + currency_id, &exchanger, &T::BuyBackAccount::get().into_account_truncating(), value, )?; - Self::deposit_event(Event::Charged { who: exchanger, asset_id, value }); + Self::deposit_event(Event::Charged { who: exchanger, currency_id, value }); Ok(()) } + /// Remove the configuration of the buyback. #[pallet::call_index(2)] #[pallet::weight(T::WeightInfo::remove_vtoken())] - pub fn remove_vtoken(origin: OriginFor, asset_id: CurrencyIdOf) -> DispatchResult { + pub fn remove_vtoken(origin: OriginFor, currency_id: CurrencyIdOf) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - Infos::::remove(asset_id); + ensure!(Infos::::contains_key(currency_id), Error::::CurrencyIdNotExists); + Infos::::remove(currency_id); - Self::deposit_event(Event::Removed { asset_id }); + Self::deposit_event(Event::Removed { currency_id }); Ok(()) } @@ -276,65 +391,134 @@ pub mod pallet { buyback_address: &AccountIdOf, currency_id: CurrencyId, info: &Info, BlockNumberFor>, + swap_out_min: u128, ) -> DispatchResult { - let asset_id: AssetId = - AssetId::try_convert_from(currency_id, T::ParachainId::get().into()) - .map_err(|_| DispatchError::Other("Conversion Error."))?; - let bnc_asset_id: AssetId = - AssetId::try_convert_from(BNC, T::ParachainId::get().into()) - .map_err(|_| DispatchError::Other("Conversion Error."))?; - let path = vec![asset_id, bnc_asset_id]; let balance = T::MultiCurrency::free_balance(currency_id, &buyback_address); - ensure!(balance > Zero::zero(), Error::::NotEnoughBalance); + ensure!(balance >= info.min_swap_value, Error::::NotEnoughBalance); + let path = Self::get_path(currency_id)?; + let amount_out_min = swap_out_min.saturating_sub(info.bias * swap_out_min); T::DexOperator::inner_swap_exact_assets_for_assets( buyback_address, - balance.min(info.value).saturated_into(), - 0, + info.min_swap_value.saturated_into(), + amount_out_min, &path, &buyback_address, )?; + if let Some(ratio) = info.destruction_ratio { + let bnc_balance_before_burn = T::MultiCurrency::free_balance(BNC, &buyback_address); + let destruction_amount = ratio * bnc_balance_before_burn; + T::MultiCurrency::withdraw(BNC, &buyback_address, destruction_amount)?; + } let bnc_balance = T::MultiCurrency::free_balance(BNC, &buyback_address); - T::VeMinting::notify_reward(0, &Some(buyback_address.clone()), vec![(BNC, bnc_balance)]) + let pool_id = 0; + T::BbBNC::notify_reward( + pool_id, + &Some(buyback_address.clone()), + vec![(BNC, bnc_balance)], + ) } #[transactional] fn add_liquidity( - buyback_address: &AccountIdOf, + liquidity_address: &AccountIdOf, currency_id: CurrencyId, info: &Info, BlockNumberFor>, + swap_out_min: u128, ) -> DispatchResult { - let asset_id: AssetId = - AssetId::try_convert_from(currency_id, T::ParachainId::get().into()) - .map_err(|_| DispatchError::Other("Conversion Error."))?; - let bnc_asset_id: AssetId = - AssetId::try_convert_from(BNC, T::ParachainId::get().into()) - .map_err(|_| DispatchError::Other("Conversion Error."))?; - let path = vec![asset_id, bnc_asset_id]; - let balance = T::MultiCurrency::free_balance(currency_id, &buyback_address); + let path = Self::get_path(currency_id)?; + let balance = T::MultiCurrency::free_balance(currency_id, &liquidity_address); let token_balance = info.proportion * balance; ensure!(token_balance > Zero::zero(), Error::::NotEnoughBalance); + let amount_out_min = swap_out_min.saturating_sub(info.bias * swap_out_min); T::DexOperator::inner_swap_exact_assets_for_assets( - buyback_address, + liquidity_address, token_balance.saturated_into(), - 0, + amount_out_min, &path, - &buyback_address, + &liquidity_address, )?; - let remaining_balance = T::MultiCurrency::free_balance(currency_id, &buyback_address); - let bnc_balance = T::MultiCurrency::free_balance(BNC, &buyback_address); + let remaining_balance = T::MultiCurrency::free_balance(currency_id, &liquidity_address); + let bnc_balance = T::MultiCurrency::free_balance(BNC, &liquidity_address); + let amount_0_min = 0; + let amount_1_min = 0; T::DexOperator::inner_add_liquidity( - buyback_address, - asset_id, - bnc_asset_id, + liquidity_address, + path[0], + path[path.len() - 1], remaining_balance.saturated_into(), bnc_balance.saturated_into(), - 0, - 0, + amount_0_min, + amount_1_min, ) } + + pub fn check_currency_id(currency_id: CurrencyId) -> Result<(), DispatchError> { + match currency_id { + CurrencyId::VToken(token_symbol) => + if !T::CurrencyIdRegister::check_vtoken_registered(token_symbol) { + return Err(Error::::CurrencyIdNotExists.into()); + }, + CurrencyId::VToken2(token_id) => { + if !T::CurrencyIdRegister::check_vtoken2_registered(token_id) { + return Err(Error::::CurrencyIdNotExists.into()); + } + }, + _ => return Err(Error::::CurrencyIdError.into()), + }; + Ok(()) + } + + pub fn get_target_block(n: BlockNumberFor, duration: BlockNumberFor) -> u32 { + let block_hash = frame_system::Pallet::::block_hash(n); + let hash_bytes = block_hash.as_ref(); + let hash_value = + u32::from_le_bytes([hash_bytes[0], hash_bytes[1], hash_bytes[2], hash_bytes[3]]); + let target_block = + hash_value % (duration.saturating_sub(One::one()).saturated_into::()); + + target_block + 1 + } + + pub fn get_path(currency_id: CurrencyId) -> Result, DispatchError> { + let asset_id: AssetId = + AssetId::try_convert_from(currency_id, T::ParachainId::get().into()) + .map_err(|_| DispatchError::Other("Conversion Error."))?; + let bnc_asset_id: AssetId = + AssetId::try_convert_from(BNC, T::ParachainId::get().into()) + .map_err(|_| DispatchError::Other("Conversion Error."))?; + Ok(vec![asset_id, bnc_asset_id]) + } + + pub fn set_swap_out_min( + currency_id: CurrencyId, + info: &Info, BlockNumberFor>, + ) -> DispatchResult { + let path = Self::get_path(currency_id)?; + let amounts = T::DexOperator::get_amount_out_by_path( + info.min_swap_value.saturated_into(), + &path, + )?; + SwapOutMin::::insert(currency_id, amounts[amounts.len() - 1]); + Ok(()) + } + + pub fn set_add_liquidity_swap_out_min( + liquidity_address: &AccountIdOf, + currency_id: CurrencyId, + info: &Info, BlockNumberFor>, + ) -> DispatchResult { + let path = Self::get_path(currency_id)?; + let balance = T::MultiCurrency::free_balance(currency_id, &liquidity_address); + let token_balance = info.proportion * balance; + ensure!(token_balance > Zero::zero(), Error::::NotEnoughBalance); + let amounts = + T::DexOperator::get_amount_out_by_path(token_balance.saturated_into(), &path)?; + AddLiquiditySwapOutMin::::insert(currency_id, amounts[amounts.len() - 1]); + Ok(()) + } } } diff --git a/pallets/buy-back/src/mock.rs b/pallets/buy-back/src/mock.rs index 77b9ee1dd..ae4b9787a 100644 --- a/pallets/buy-back/src/mock.rs +++ b/pallets/buy-back/src/mock.rs @@ -22,6 +22,7 @@ #![allow(non_upper_case_globals)] use bifrost_asset_registry::AssetIdMaps; +use bifrost_primitives::MoonbeamChainId; pub use bifrost_primitives::{currency::*, CurrencyId, SlpxOperator, TokenSymbol}; use bifrost_slp::{QueryId, QueryResponseManager}; pub use cumulus_primitives_core::ParaId; @@ -74,7 +75,7 @@ frame_support::construct_runtime!( ZenlinkProtocol: zenlink_protocol, AssetRegistry: bifrost_asset_registry, PolkadotXcm: pallet_xcm, - VeMinting: bifrost_ve_minting, + BbBNC: bb_bnc, } ); @@ -164,7 +165,6 @@ parameter_types! { ord_parameter_types! { pub const One: AccountId = ALICE; - // pub const RelayChainTokenSymbolKSM: TokenSymbol = TokenSymbol::KSM; pub const RelayCurrencyId: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); } @@ -174,14 +174,12 @@ impl bifrost_buy_back::Config for Runtime { type ControlOrigin = EnsureSignedBy; type WeightInfo = (); type DexOperator = ZenlinkProtocol; - type CurrencyIdConversion = AssetIdMaps; type TreasuryAccount = TreasuryAccount; - type RelayChainToken = RelayCurrencyId; type BuyBackAccount = BuyBackAccount; type LiquidityAccount = LiquidityAccount; type ParachainId = ParaInfo; type CurrencyIdRegister = AssetIdMaps; - type VeMinting = VeMinting; + type BbBNC = BbBNC; } pub struct ParaInfo; @@ -309,15 +307,11 @@ impl bifrost_vtoken_minting::Config for Runtime { type WeightInfo = (); type OnRedeemSuccess = (); type XcmTransfer = XTokens; - type AstarParachainId = ConstU32<2007>; - type MoonbeamParachainId = ConstU32<2023>; - type HydradxParachainId = ConstU32<2034>; - type MantaParachainId = ConstU32<2104>; - type InterlayParachainId = ConstU32<2032>; + type MoonbeamChainId = MoonbeamChainId; type ChannelCommission = (); type MaxLockRecords = ConstU32<100>; type IncentivePoolAccount = IncentivePoolAccount; - type VeMinting = (); + type BbBNC = (); type AssetIdMaps = AssetIdMaps; } @@ -471,9 +465,8 @@ impl pallet_xcm::Config for Runtime { } parameter_types! { - pub const VeMintingTokenType: CurrencyId = CurrencyId::VToken(TokenSymbol::BNC); - pub VeMintingPalletId: PalletId = PalletId(*b"bf/vemnt"); - pub IncentivePalletId: PalletId = PalletId(*b"bf/veict"); + pub const BbBNCTokenType: CurrencyId = CurrencyId::VToken(TokenSymbol::BNC); + pub IncentivePalletId: PalletId = PalletId(*b"bf/bbict"); pub const Week: BlockNumber = 50400; // a week pub const MaxBlock: BlockNumber = 10512000; // four years pub const Multiplier: Balance = 10_u128.pow(12); @@ -482,13 +475,13 @@ parameter_types! { pub const MarkupRefreshLimit: u32 = 100; } -impl bifrost_ve_minting::Config for Runtime { +impl bb_bnc::Config for Runtime { type RuntimeEvent = RuntimeEvent; type MultiCurrency = Currencies; type ControlOrigin = EnsureSignedBy; - type TokenType = VeMintingTokenType; - type VeMintingPalletId = VeMintingPalletId; + type TokenType = BbBNCTokenType; type IncentivePalletId = IncentivePalletId; + type BuyBackAccount = BuyBackAccount; type WeightInfo = (); type BlockNumberToBalance = ConvertInto; type Week = Week; @@ -554,6 +547,15 @@ impl ExtBuilder { .assimilate_storage(&mut t) .unwrap(); + bifrost_asset_registry::GenesisConfig:: { + currency: vec![(VKSM, 10_000_000, None), (VDOT, 10_000_000, None)], + vcurrency: vec![], + vsbond: vec![], + phantom: Default::default(), + } + .assimilate_storage(&mut t) + .unwrap(); + t.into() } } diff --git a/pallets/buy-back/src/tests.rs b/pallets/buy-back/src/tests.rs index 8a0e9a99e..485d80d52 100644 --- a/pallets/buy-back/src/tests.rs +++ b/pallets/buy-back/src/tests.rs @@ -21,23 +21,84 @@ #![cfg(test)] use crate::{mock::*, *}; -use frame_support::assert_ok; +use frame_support::{assert_noop, assert_ok}; use sp_arithmetic::per_things::Permill; +const PARAID: u32 = 2001; +const VALUE: u128 = 1000; +const BUYBACK_DURATION: u64 = 2; +const LIQUID_DURATION: u64 = 1000; +const LIQUID_PROPORTION: Permill = Permill::from_percent(2); + +#[test] +fn set_vtoken_should_not_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let destruction_ratio = Some(Permill::from_percent(2)); + let bias: Permill = Permill::from_percent(10); + assert_noop!( + BuyBack::set_vtoken( + RuntimeOrigin::signed(ALICE), + KSM, + VALUE, + LIQUID_PROPORTION, + BUYBACK_DURATION, + LIQUID_DURATION, + true, + destruction_ratio, + bias + ), + Error::::CurrencyIdError + ); + + assert_noop!( + BuyBack::set_vtoken( + RuntimeOrigin::signed(ALICE), + VKSM, + VALUE, + LIQUID_PROPORTION, + 0, + LIQUID_DURATION, + true, + destruction_ratio, + bias + ), + Error::::ZeroDuration + ); + + assert_noop!( + BuyBack::set_vtoken( + RuntimeOrigin::signed(ALICE), + VKSM, + 0, + LIQUID_PROPORTION, + BUYBACK_DURATION, + LIQUID_DURATION, + true, + destruction_ratio, + bias + ), + Error::::ZeroMinSwapValue + ); + }); +} + #[test] -fn buy_back_should_work() { +fn buy_back_with_burn_should_work() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { - let para_id = 2001u32; - let zenlink_pair_account_id = init_zenlink(para_id); + let zenlink_pair_account_id = init_zenlink(PARAID); + let destruction_ratio = Some(Permill::from_percent(2)); + let bias: Permill = Permill::from_percent(10); assert_ok!(BuyBack::set_vtoken( RuntimeOrigin::signed(ALICE), VKSM, - 1000u128, - Permill::from_percent(2), - 1000, - 1000, - true + VALUE, + LIQUID_PROPORTION, + BUYBACK_DURATION, + LIQUID_DURATION, + true, + destruction_ratio, + bias )); let buyback_account = ::BuyBackAccount::get().into_account_truncating(); let incentive_account = IncentivePalletId::get().into_account_truncating(); @@ -46,10 +107,48 @@ fn buy_back_should_work() { assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 2000); assert_eq!(Currencies::free_balance(BNC, &buyback_account), 0); assert_eq!(Currencies::free_balance(BNC, &incentive_account), 0); - VeMinting::set_incentive(0, Some(7 * 86400 / 12), Some(buyback_account.clone())); + BbBNC::set_incentive(0, Some(7 * 86400 / 12), Some(buyback_account.clone())); assert_ok!(BuyBack::charge(RuntimeOrigin::signed(ALICE), VKSM, 1000)); let infos = Infos::::get(VKSM).unwrap(); - assert_ok!(BuyBack::buy_back(&buyback_account, VKSM, &infos)); + assert_ok!(BuyBack::buy_back(&buyback_account, VKSM, &infos, 0)); + System::set_block_number(System::block_number() + 1); + assert_eq!(Currencies::free_balance(VKSM, &buyback_account), 9000); + assert_eq!(Currencies::free_balance(VKSM, &zenlink_pair_account_id), 3200); + assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 1377); + assert_eq!(Currencies::free_balance(BNC, &buyback_account), 0); + assert_eq!(Currencies::free_balance(BNC, &incentive_account), 611); + }); +} + +#[test] +fn buy_back_no_burn_should_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let zenlink_pair_account_id = init_zenlink(PARAID); + let destruction_ratio = Some(Permill::from_percent(0)); + let bias: Permill = Permill::from_percent(10); + + assert_ok!(BuyBack::set_vtoken( + RuntimeOrigin::signed(ALICE), + VKSM, + VALUE, + LIQUID_PROPORTION, + BUYBACK_DURATION, + LIQUID_DURATION, + true, + destruction_ratio, + bias + )); + let buyback_account = ::BuyBackAccount::get().into_account_truncating(); + let incentive_account = IncentivePalletId::get().into_account_truncating(); + assert_eq!(Currencies::free_balance(VKSM, &buyback_account), 9000); + assert_eq!(Currencies::free_balance(VKSM, &zenlink_pair_account_id), 2200); + assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 2000); + assert_eq!(Currencies::free_balance(BNC, &buyback_account), 0); + assert_eq!(Currencies::free_balance(BNC, &incentive_account), 0); + BbBNC::set_incentive(0, Some(7 * 86400 / 12), Some(buyback_account.clone())); + assert_ok!(BuyBack::charge(RuntimeOrigin::signed(ALICE), VKSM, 1000)); + let infos = Infos::::get(VKSM).unwrap(); + assert_ok!(BuyBack::buy_back(&buyback_account, VKSM, &infos, 0)); System::set_block_number(System::block_number() + 1); assert_eq!(Currencies::free_balance(VKSM, &buyback_account), 9000); assert_eq!(Currencies::free_balance(VKSM, &zenlink_pair_account_id), 3200); @@ -60,19 +159,22 @@ fn buy_back_should_work() { } #[test] -fn on_idle_should_work() { +fn on_initialize_no_burn_should_work() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { - let para_id = 2001u32; - let zenlink_pair_account_id = init_zenlink(para_id); + let zenlink_pair_account_id = init_zenlink(PARAID); + let destruction_ratio = None; + let bias: Permill = Permill::from_percent(10); assert_ok!(BuyBack::set_vtoken( RuntimeOrigin::signed(ALICE), VKSM, - 1_000_000u128, - Permill::from_percent(2), - 1000, - 1000, - true + VALUE, + LIQUID_PROPORTION, + BUYBACK_DURATION, + LIQUID_DURATION, + true, + destruction_ratio, + bias )); let buyback_account = ::BuyBackAccount::get().into_account_truncating(); let incentive_account = IncentivePalletId::get().into_account_truncating(); @@ -81,24 +183,161 @@ fn on_idle_should_work() { assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 2000); assert_eq!(Currencies::free_balance(BNC, &buyback_account), 0); assert_eq!(Currencies::free_balance(BNC, &incentive_account), 0); - VeMinting::set_incentive(0, Some(7 * 86400 / 12), Some(buyback_account.clone())); + BbBNC::set_incentive(0, Some(7 * 86400 / 12), Some(buyback_account.clone())); assert_ok!(BuyBack::charge(RuntimeOrigin::signed(ALICE), VKSM, 1000)); - BuyBack::on_idle( - >::block_number(), - Weight::from_parts(100000000, 0), - ); + BuyBack::on_initialize(1); + BuyBack::on_initialize(2); + BuyBack::on_initialize(3); + assert_eq!(Currencies::free_balance(VKSM, &buyback_account), 9000); + assert_eq!(Currencies::free_balance(VKSM, &zenlink_pair_account_id), 3200); + assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 1377); // 362 + assert_eq!(Currencies::free_balance(BNC, &buyback_account), 0); + assert_eq!(Currencies::free_balance(BNC, &incentive_account), 623); + }); +} + +#[test] +fn on_initialize_with_burn_should_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let zenlink_pair_account_id = init_zenlink(PARAID); + let destruction_ratio = Some(Permill::from_percent(10)); + let bias: Permill = Permill::from_percent(10); + + assert_ok!(BuyBack::set_vtoken( + RuntimeOrigin::signed(ALICE), + VKSM, + VALUE, + LIQUID_PROPORTION, + BUYBACK_DURATION, + LIQUID_DURATION, + true, + destruction_ratio, + bias + )); + let buyback_account = ::BuyBackAccount::get().into_account_truncating(); + let incentive_account = IncentivePalletId::get().into_account_truncating(); + assert_eq!(Currencies::free_balance(VKSM, &buyback_account), 9000); + assert_eq!(Currencies::free_balance(VKSM, &zenlink_pair_account_id), 2200); + assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 2000); + assert_eq!(Currencies::free_balance(BNC, &buyback_account), 0); + assert_eq!(Currencies::free_balance(BNC, &incentive_account), 0); + BbBNC::set_incentive(0, Some(7 * 86400 / 12), Some(buyback_account.clone())); + assert_ok!(BuyBack::charge(RuntimeOrigin::signed(ALICE), VKSM, 1000)); + BuyBack::on_initialize(>::block_number() + 1); + System::set_block_number(System::block_number() + 1); + BuyBack::on_initialize(>::block_number() + 1); System::set_block_number(System::block_number() + 1); - assert_eq!(Currencies::free_balance(VKSM, &buyback_account), 0); - assert_eq!(Currencies::free_balance(VKSM, &zenlink_pair_account_id), 12200); - assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 362); + assert_eq!(Currencies::free_balance(VKSM, &buyback_account), 9000); + assert_eq!(Currencies::free_balance(VKSM, &zenlink_pair_account_id), 3200); + assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 1377); assert_eq!(Currencies::free_balance(BNC, &buyback_account), 0); - assert_eq!(Currencies::free_balance(BNC, &incentive_account), 1638); + assert_eq!(Currencies::free_balance(BNC, &incentive_account), 561); // 623 - 62 + }); +} + +#[test] +fn on_initialize_with_bias_should_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let zenlink_pair_account_id = init_zenlink(PARAID); + let destruction_ratio = None; + let bias: Permill = Permill::from_percent(10); + + assert_ok!(BuyBack::set_vtoken( + RuntimeOrigin::signed(ALICE), + VKSM, + VALUE, + LIQUID_PROPORTION, + BUYBACK_DURATION, + LIQUID_DURATION, + true, + destruction_ratio, + bias + )); + let buyback_account = ::BuyBackAccount::get().into_account_truncating(); + let incentive_account = IncentivePalletId::get().into_account_truncating(); + assert_eq!(Currencies::free_balance(VKSM, &buyback_account), 9000); + assert_eq!(Currencies::free_balance(VKSM, &zenlink_pair_account_id), 2200); + assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 2000); + assert_eq!(Currencies::free_balance(BNC, &buyback_account), 0); + assert_eq!(Currencies::free_balance(BNC, &incentive_account), 0); + BbBNC::set_incentive(0, Some(7 * 86400 / 12), Some(buyback_account.clone())); + assert_ok!(BuyBack::charge(RuntimeOrigin::signed(ALICE), VKSM, 1000)); + BuyBack::on_initialize(1); + let path = vec![ + AssetId::try_convert_from(VKSM, PARAID).unwrap(), + AssetId::try_convert_from(BNC, PARAID).unwrap(), + ]; + assert_ok!(ZenlinkProtocol::swap_exact_assets_for_assets( + RuntimeOrigin::signed(ALICE), + 100, + 0, + path, + ALICE, + >::block_number() + BlockNumberFor::::from(1u32) + )); + BuyBack::on_initialize(2); + BuyBack::on_initialize(3); + assert_eq!(Currencies::free_balance(VKSM, &buyback_account), 9000); + assert_eq!(Currencies::free_balance(VKSM, &zenlink_pair_account_id), 3300); + assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 1336); + assert_eq!(Currencies::free_balance(BNC, &buyback_account), 0); + assert_eq!(Currencies::free_balance(BNC, &incentive_account), 578); + }); +} + +#[test] +fn on_initialize_with_bias_should_not_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let zenlink_pair_account_id = init_zenlink(PARAID); + let destruction_ratio = None; + let bias: Permill = Permill::from_percent(5); + + assert_ok!(BuyBack::set_vtoken( + RuntimeOrigin::signed(ALICE), + VKSM, + VALUE, + LIQUID_PROPORTION, + BUYBACK_DURATION, + LIQUID_DURATION, + true, + destruction_ratio, + bias + )); + let buyback_account = ::BuyBackAccount::get().into_account_truncating(); + let incentive_account = IncentivePalletId::get().into_account_truncating(); + assert_eq!(Currencies::free_balance(VKSM, &buyback_account), 9000); + assert_eq!(Currencies::free_balance(VKSM, &zenlink_pair_account_id), 2200); + assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 2000); + assert_eq!(Currencies::free_balance(BNC, &buyback_account), 0); + assert_eq!(Currencies::free_balance(BNC, &incentive_account), 0); + BbBNC::set_incentive(0, Some(7 * 86400 / 12), Some(buyback_account.clone())); + assert_ok!(BuyBack::charge(RuntimeOrigin::signed(ALICE), VKSM, 1000)); + BuyBack::on_initialize(1); + let path = vec![ + AssetId::try_convert_from(VKSM, PARAID).unwrap(), + AssetId::try_convert_from(BNC, PARAID).unwrap(), + ]; + assert_ok!(ZenlinkProtocol::swap_exact_assets_for_assets( + RuntimeOrigin::signed(ALICE), + 100, + 0, + path, + ALICE, + >::block_number() + BlockNumberFor::::from(1u32) + )); + BuyBack::on_initialize(2); + BuyBack::on_initialize(3); + assert_eq!(Currencies::free_balance(VKSM, &buyback_account), 10000); + assert_eq!(Currencies::free_balance(VKSM, &zenlink_pair_account_id), 2300); + assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 1914); + assert_eq!(Currencies::free_balance(BNC, &buyback_account), 0); + assert_eq!(Currencies::free_balance(BNC, &incentive_account), 0); }); } -fn init_zenlink(para_id: u32) -> AccountIdOf { - let asset_0_currency_id: AssetId = AssetId::try_convert_from(BNC, para_id).unwrap(); - let asset_1_currency_id: AssetId = AssetId::try_convert_from(VKSM, para_id).unwrap(); +fn init_zenlink(_para_id: u32) -> AccountIdOf { + let asset_0_currency_id: AssetId = AssetId::try_convert_from(BNC, PARAID).unwrap(); + let asset_1_currency_id: AssetId = AssetId::try_convert_from(VKSM, PARAID).unwrap(); // let path = vec![asset_0_currency_id, asset_1_currency_id]; assert_ok!(ZenlinkProtocol::create_pair( RuntimeOrigin::root(), diff --git a/pallets/channel-commission/Cargo.toml b/pallets/channel-commission/Cargo.toml index 7416e4868..f6f035304 100644 --- a/pallets/channel-commission/Cargo.toml +++ b/pallets/channel-commission/Cargo.toml @@ -16,6 +16,7 @@ bifrost-primitives = { workspace = true } orml-traits = { workspace = true } log = { workspace = true } sp-core = { workspace = true } +sp-io = { workspace = true } [dev-dependencies] orml-tokens = { workspace = true } @@ -35,6 +36,7 @@ std = [ "frame-system/std", "frame-benchmarking?/std", "orml-traits/std", + "sp-io/std", ] runtime-benchmarks = [ diff --git a/pallets/channel-commission/src/benchmarking.rs b/pallets/channel-commission/src/benchmarking.rs index 12f183048..64fa5a4ef 100644 --- a/pallets/channel-commission/src/benchmarking.rs +++ b/pallets/channel-commission/src/benchmarking.rs @@ -181,7 +181,7 @@ benchmarks! { // set channel share let old_amount: BalanceOf = 2000u128.unique_saturated_into(); let new_amount: BalanceOf = 500u128.unique_saturated_into(); - ChannelVtokenShares::::insert(0, vtoken, share.clone()); + ChannelVtokenShares::::insert(0, vtoken, share); PeriodChannelVtokenMint::::insert(0, vtoken, (old_amount, new_amount)); } diff --git a/pallets/channel-commission/src/lib.rs b/pallets/channel-commission/src/lib.rs index 67d656df0..d2343f2ba 100644 --- a/pallets/channel-commission/src/lib.rs +++ b/pallets/channel-commission/src/lib.rs @@ -28,8 +28,9 @@ use bifrost_primitives::{ use frame_support::{pallet_prelude::*, PalletId}; use frame_system::pallet_prelude::*; use orml_traits::MultiCurrency; -use sp_core::U256; +use sp_io::MultiRemovalResults; use sp_runtime::{ + helpers_128bit::multiply_by_rational_with_rounding, traits::{AccountIdConversion, CheckedAdd, UniqueSaturatedFrom, UniqueSaturatedInto, Zero}, PerThing, Percent, Permill, Rounding, SaturatedConversion, Saturating, }; @@ -94,6 +95,13 @@ pub mod pallet { InvalidCommissionRate, CommissionTokenAlreadySet, InvalidVtoken, + /// Error indicating that no changes were made during a modification operation. + NoChangesMade, + /// Represents an error that occurs when a division operation encounters a divisor of zero. + /// This is a critical error, as division by zero is undefined and cannot be performed. + DivisionByZero, + /// Error indicating that the removal operation was not completed successfully. + RemovalNotComplete, } #[pallet::event] @@ -161,17 +169,35 @@ pub mod pallet { commission_token: CurrencyId, amount: BalanceOf, }, + /// Emitted when a Permill calculation fails. + /// This event carries the numerator and denominator that caused the failure. + CalculationFailed { + numerator: BalanceOf, + denominator: BalanceOf, + }, + /// Bifrost commission transfer failed. + /// Parameters are the commission token and the amount that failed to transfer. + BifrostCommissionTransferFailed { + from: AccountIdOf, + to: AccountIdOf, + commission_token: CurrencyId, + amount: BalanceOf, + }, + /// Error event indicating that the removal process of clearing was not completed. + RemovalNotCompleteError { + target_num: u32, + limit: u32, + executed_num: u32, + }, } /// Auto increment channel id #[pallet::storage] - #[pallet::getter(fn channel_next_id)] pub type ChannelNextId = StorageValue<_, ChannelId, ValueQuery>; /// Mapping a channel id to a receive account and a name, 【channel_id =>(receive_account, /// name)】 #[pallet::storage] - #[pallet::getter(fn channels)] pub type Channels = StorageMap< _, Blake2_128Concat, @@ -181,13 +207,11 @@ pub mod pallet { /// Mapping a vtoken to a commission token, 【vtoken => commission_token】 #[pallet::storage] - #[pallet::getter(fn commission_tokens)] pub type CommissionTokens = StorageMap<_, Blake2_128Concat, CurrencyId, CurrencyId>; /// Mapping a channel + vtoken to corresponding commission rate, 【(channel_id, vtoken) => /// commission rate】 #[pallet::storage] - #[pallet::getter(fn channel_commission_token_rates)] pub type ChannelCommissionTokenRates = StorageDoubleMap< _, Blake2_128Concat, @@ -200,7 +224,6 @@ pub mod pallet { /// Mapping a channel + vtoken to corresponding channel share, 【(channel_id, vtoken) => share】 #[pallet::storage] - #[pallet::getter(fn channel_vtoken_shares)] pub type ChannelVtokenShares = StorageDoubleMap< _, Blake2_128Concat, @@ -214,28 +237,24 @@ pub mod pallet { /// 【vtoken => (old_issuance, new_issuance)】,old_issuance is the vtoken issuance at last /// clearing point, new_issuance is the ongoing accumulative issuance the last clearing point #[pallet::storage] - #[pallet::getter(fn vtoken_issuance_snapshots)] pub type VtokenIssuanceSnapshots = StorageMap<_, Blake2_128Concat, CurrencyId, (BalanceOf, BalanceOf), ValueQuery>; /// Vtoken total minted amount in the ongoing period for the chain, 【vtoken => (old_total_mint, /// new_total_mint)】 #[pallet::storage] - #[pallet::getter(fn period_vtoken_total_mint)] pub type PeriodVtokenTotalMint = StorageMap<_, Blake2_128Concat, CurrencyId, (BalanceOf, BalanceOf), ValueQuery>; /// Vtoken total redeemed amount in the ongoing period for the chain, 【vtoken => /// (old_total_redeem, new_total_redeem)】 #[pallet::storage] - #[pallet::getter(fn period_vtoken_total_redeem)] pub type PeriodVtokenTotalRedeem = StorageMap<_, Blake2_128Concat, CurrencyId, (BalanceOf, BalanceOf), ValueQuery>; /// Vtoken minted amount in the ongoing period for the channel, 【(channel_id, vtoken) => /// (old_mint_amount, new_mint_amount)】 #[pallet::storage] - #[pallet::getter(fn period_channel_vtoken_mint)] pub type PeriodChannelVtokenMint = StorageDoubleMap< _, Blake2_128Concat, @@ -249,20 +268,17 @@ pub mod pallet { /// Commission pool for last period and ongoing period, 【commission token => (old_amount, /// new_amount)】 #[pallet::storage] - #[pallet::getter(fn period_total_commissions)] pub type PeriodTotalCommissions = StorageMap<_, Blake2_128Concat, CurrencyId, (BalanceOf, BalanceOf), ValueQuery>; /// Commission amount that has been cleared for the current clearing process, 【commission token /// => amount】 #[pallet::storage] - #[pallet::getter(fn period_cleared_commissions)] pub type PeriodClearedCommissions = StorageMap<_, Blake2_128Concat, CurrencyId, BalanceOf, ValueQuery>; /// Commission amount to be claimed by channels, 【channel id + commission token => amount】 #[pallet::storage] - #[pallet::getter(fn channel_claimable_commissions)] pub type ChannelClaimableCommissions = StorageDoubleMap< _, Blake2_128Concat, @@ -360,18 +376,25 @@ pub mod pallet { Channels::::remove(channel_id); // remove the channel from ChannelCommissionTokenRates storage - let _ = ChannelCommissionTokenRates::::clear_prefix( + Self::check_removed_all(ChannelCommissionTokenRates::::clear_prefix( channel_id, REMOVE_TOKEN_LIMIT, None, - ); + ))?; // remove the channel from ChannelVtokenShares storage - let _ = ChannelVtokenShares::::clear_prefix(channel_id, REMOVE_TOKEN_LIMIT, None); + Self::check_removed_all(ChannelVtokenShares::::clear_prefix( + channel_id, + REMOVE_TOKEN_LIMIT, + None, + ))?; // remove the channel from PeriodChannelVtokenMint storage - let _ = - PeriodChannelVtokenMint::::clear_prefix(channel_id, REMOVE_TOKEN_LIMIT, None); + Self::check_removed_all(PeriodChannelVtokenMint::::clear_prefix( + channel_id, + REMOVE_TOKEN_LIMIT, + None, + ))?; Self::deposit_event(Event::ChannelRemoved { channel_id }); @@ -387,17 +410,13 @@ pub mod pallet { ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - // if the receive account is not changed, do nothing - let channel_op = Channels::::get(channel_id); - - let old_receive_account = if let Some(channel_info) = channel_op { - channel_info.0 - } else { - Err(Error::::ChannelNotExist)? - }; + // If the channel exists, get the receive account; otherwise, return an error. + let old_receive_account = Channels::::get(channel_id) + .map(|channel_info| channel_info.0) + .ok_or(Error::::ChannelNotExist)?; if old_receive_account == receive_account { - return Ok(()); + return Err(Error::::NoChangesMade.into()); } // update the channel receive account @@ -458,14 +477,12 @@ pub mod pallet { T::ControlOrigin::ensure_origin(origin)?; ensure!(vtoken.is_vtoken(), Error::::InvalidVtoken); - if let Some(commission_token) = commission_token_op { - // if old commission token is the same as the new one, do nothing - if let Some(old_commission_token) = CommissionTokens::::get(vtoken) { - if old_commission_token == commission_token { - return Ok(()); - } - } + // if old commission token is the same as the new one, do nothing + if CommissionTokens::::get(vtoken) == commission_token_op { + return Err(Error::::NoChangesMade.into()); + } + if let Some(commission_token) = commission_token_op { // set the commission token CommissionTokens::::insert(vtoken, commission_token); @@ -479,33 +496,33 @@ pub mod pallet { commission_token: Some(commission_token), }); } else { - // remove the commission token - let _ = CommissionTokens::::remove(vtoken); + // remove the commission token、 + CommissionTokens::::remove(vtoken); // remove the vtoken from VtokenIssuanceSnapshots - let _ = VtokenIssuanceSnapshots::::remove(vtoken); + VtokenIssuanceSnapshots::::remove(vtoken); // remove the vtoken from PeriodVtokenTotalMint storage - let _ = PeriodVtokenTotalMint::::remove(vtoken); + PeriodVtokenTotalMint::::remove(vtoken); // remove the vtoken from PeriodVtokenTotalRedeem storage - let _ = PeriodVtokenTotalRedeem::::remove(vtoken); + PeriodVtokenTotalRedeem::::remove(vtoken); // for all channel_ids Channels::::iter_keys().for_each(|channel_id| { // remove the vtoken from ChannelCommissionTokenRates storage - let _ = ChannelCommissionTokenRates::::remove(channel_id, vtoken); + ChannelCommissionTokenRates::::remove(channel_id, vtoken); // remove the vtoken from ChannelVtokenShares storage - let _ = ChannelVtokenShares::::remove(channel_id, vtoken); + ChannelVtokenShares::::remove(channel_id, vtoken); // remove the vtoken from PeriodChannelVtokenMint storage - let _ = PeriodChannelVtokenMint::::remove(channel_id, vtoken); + PeriodChannelVtokenMint::::remove(channel_id, vtoken); }); // remove the vtoken from PeriodTotalCommissions storage - let _ = PeriodTotalCommissions::::remove(vtoken); + PeriodTotalCommissions::::remove(vtoken); // remove the vtoken from PeriodClearedCommissions storage - let _ = PeriodClearedCommissions::::remove(vtoken); + PeriodClearedCommissions::::remove(vtoken); // only ChannelClaimableCommissions not removed. Channel can still claim the // previous commission @@ -562,11 +579,7 @@ pub mod pallet { // if the sum of all shares is greater than 1, throw an error let total_shares_op = total_shares.checked_add(&share); - if let Some(total_shares_new) = total_shares_op { - total_shares = total_shares_new - } else { - Err(Error::::InvalidCommissionRate)? - }; + total_shares = total_shares_op.ok_or_else(|| Error::::InvalidCommissionRate)?; } // update the channel vtoken share @@ -587,67 +600,70 @@ impl Pallet { pub(crate) fn set_clearing_environment() { // Move the vtoken issuance amount from ongoing period to the previous period and clear the // ongoing period issuance amount - VtokenIssuanceSnapshots::::iter().for_each(|(vtoken, issuance)| { - let mut issuance = issuance; - issuance.0 = issuance.1; + let snapshots: Vec = VtokenIssuanceSnapshots::::iter_keys().collect(); + for vtoken in snapshots { + VtokenIssuanceSnapshots::::mutate(vtoken, |issuance| { + issuance.0 = issuance.1; - // get the vtoken new issuance amount from Tokens module issuance storage - let new_issuance = T::MultiCurrency::total_issuance(vtoken); + // get the vtoken new issuance amount from Tokens module issuance storage + let new_issuance = T::MultiCurrency::total_issuance(vtoken); - issuance.1 = new_issuance; - VtokenIssuanceSnapshots::::insert(vtoken, issuance); + issuance.1 = new_issuance; - Self::deposit_event(Event::VtokenIssuanceSnapshotUpdated { - vtoken, - old_issuance: issuance.0, - new_issuance, + Self::deposit_event(Event::VtokenIssuanceSnapshotUpdated { + vtoken, + old_issuance: issuance.0, + new_issuance, + }); }); - }); + } // Move the total minted amount of the period from ongoing period to the previous period and // clear the ongoing period minted amount - PeriodVtokenTotalMint::::iter().for_each(|(vtoken, total_mint)| { - let info = total_mint; + let snapshots: Vec = PeriodVtokenTotalMint::::iter_keys().collect(); + for vtoken in snapshots { + PeriodVtokenTotalMint::::mutate(vtoken, |total_mint| { + let info = *total_mint; - let mut total_mint = total_mint; - total_mint.0 = total_mint.1; - total_mint.1 = Zero::zero(); - PeriodVtokenTotalMint::::insert(vtoken, total_mint); + total_mint.0 = total_mint.1; + total_mint.1 = Zero::zero(); - Self::deposit_event(Event::PeriodVtokenTotalMintUpdated { - vtoken, - old_total_mint: info.0, - new_total_mint: info.1, + Self::deposit_event(Event::PeriodVtokenTotalMintUpdated { + vtoken, + old_total_mint: info.0, + new_total_mint: info.1, + }); }); - }); + } // Move the total redeemed amount of the period from ongoing period to the previous period // and clear the ongoing period redeemed amount - PeriodVtokenTotalRedeem::::iter().for_each(|(vtoken, total_redeem)| { - let info = total_redeem; + let snapshots: Vec = PeriodVtokenTotalRedeem::::iter_keys().collect(); + for vtoken in snapshots { + PeriodVtokenTotalRedeem::::mutate(vtoken, |total_redeem| { + let info = *total_redeem; - let mut total_redeem = total_redeem; - total_redeem.0 = total_redeem.1; - total_redeem.1 = Zero::zero(); - PeriodVtokenTotalRedeem::::insert(vtoken, total_redeem); + total_redeem.0 = total_redeem.1; + total_redeem.1 = Zero::zero(); - Self::deposit_event(Event::PeriodVtokenTotalRedeemUpdated { - vtoken, - old_total_redeem: info.0, - new_total_redeem: info.1, + Self::deposit_event(Event::PeriodVtokenTotalRedeemUpdated { + vtoken, + old_total_redeem: info.0, + new_total_redeem: info.1, + }); }); - }); + } // Move the channel minted amount of the period from ongoing period to the previous period // and clear the ongoing period minted amount - PeriodChannelVtokenMint::::iter().for_each( - |(channel_id, vtoken, channel_vtoken_mint)| { - let info = channel_vtoken_mint; + let snapshots: Vec<(ChannelId, CurrencyId)> = + PeriodChannelVtokenMint::::iter_keys().collect(); + for (channel_id, vtoken) in snapshots { + PeriodChannelVtokenMint::::mutate(channel_id, vtoken, |channel_vtoken_mint| { + let info = *channel_vtoken_mint; - let mut channel_vtoken_mint = channel_vtoken_mint; channel_vtoken_mint.0 = channel_vtoken_mint.1; channel_vtoken_mint.1 = Zero::zero(); - PeriodChannelVtokenMint::::insert(channel_id, vtoken, channel_vtoken_mint); Self::deposit_event(Event::PeriodChannelVtokenMintUpdated { channel_id, @@ -655,25 +671,26 @@ impl Pallet { old_mint_amount: info.0, new_mint_amount: info.1, }); - }, - ); + }); + } // Move the total commission amount of the period from ongoing period to the previous period // and clear the ongoing period commission amount - PeriodTotalCommissions::::iter().for_each(|(commission_token, total_commission)| { - let info = total_commission; - - let mut total_commission = total_commission; - total_commission.0 = total_commission.1; - total_commission.1 = Zero::zero(); - PeriodTotalCommissions::::insert(commission_token, total_commission); - - Self::deposit_event(Event::PeriodTotalCommissionsUpdated { - commission_token, - old_amount: info.0, - new_amount: info.1, + let snapshots: Vec = PeriodTotalCommissions::::iter_keys().collect(); + for commission_token in snapshots { + PeriodTotalCommissions::::mutate(commission_token, |total_commission| { + let info = *total_commission; + + total_commission.0 = total_commission.1; + total_commission.1 = Zero::zero(); + + Self::deposit_event(Event::PeriodTotalCommissionsUpdated { + commission_token, + old_amount: info.0, + new_amount: info.1, + }); }); - }); + } } pub(crate) fn clear_channel_commissions(channel_id: ChannelId) { @@ -740,53 +757,63 @@ impl Pallet { pub(crate) fn update_channel_vtoken_shares(channel_id: ChannelId) { // for a channel_id,update the share of all vtoken - ChannelVtokenShares::::iter_prefix(channel_id).for_each( - |(vtoken, channel_old_share)| { - // get the vtoken issuance amount - let (old_vtoken_issuance, new_vtoken_issuance) = - VtokenIssuanceSnapshots::::get(vtoken); - - // get the total minted amount of the period - let total_mint = PeriodVtokenTotalMint::::get(vtoken).0; - - // get the total redeemed amount of the period - let total_redeem = PeriodVtokenTotalRedeem::::get(vtoken).0; - - // only update the share when total_mint > total_redeem - if total_redeem < total_mint { - // net_mint = total_mint - total_redeem - let net_mint = total_mint.saturating_sub(total_redeem); - // channel mint - let channel_mint = PeriodChannelVtokenMint::::get(channel_id, vtoken).0; - // channel_net_mint: channel_share * net_mint - let channel_period_net_mint = if total_mint.is_zero() { - Zero::zero() - } else { - Self::calculate_mul_div_result(channel_mint, net_mint, total_mint) - }; - - let numerator = - channel_old_share.mul_floor(old_vtoken_issuance) + channel_period_net_mint; - let denominator = new_vtoken_issuance; + for (vtoken, channel_old_share) in ChannelVtokenShares::::iter_prefix(channel_id) { + // get the vtoken issuance amount + let (old_vtoken_issuance, new_vtoken_issuance) = + VtokenIssuanceSnapshots::::get(vtoken); + + // get the total minted amount of the period + let total_mint = PeriodVtokenTotalMint::::get(vtoken).0; + + // get the total redeemed amount of the period + let total_redeem = PeriodVtokenTotalRedeem::::get(vtoken).0; + + // only update the share when total_mint > total_redeem + if total_redeem < total_mint { + // net_mint = total_mint - total_redeem + let net_mint = total_mint.saturating_sub(total_redeem); + // channel mint + let channel_mint = PeriodChannelVtokenMint::::get(channel_id, vtoken).0; + // channel_net_mint: channel_share * net_mint + let channel_period_net_mint = if total_mint.is_zero() { + Zero::zero() + } else { + Self::calculate_mul_div_result(channel_mint, net_mint, total_mint) + .unwrap_or(Zero::zero()) + }; - let channel_new_share: Permill = if denominator.is_zero() { - Zero::zero() - } else { - Permill::from_rational_with_rounding(numerator, denominator, Rounding::Down) - .unwrap_or_default() + let numerator = + channel_old_share.mul_floor(old_vtoken_issuance) + channel_period_net_mint; + let denominator = new_vtoken_issuance; + + ChannelVtokenShares::::mutate(channel_id, vtoken, |share| { + let channel_new_share: Permill = match denominator.is_zero() { + true => Permill::zero(), + false => Permill::from_rational_with_rounding( + numerator, + denominator, + Rounding::Down, + ).unwrap_or_else(|()| { + log::error!("Failed to calculate Permill from numerator: {:?} and denominator: {:?}.",numerator, denominator); + // Emit the failure event + Self::deposit_event(Event::CalculationFailed { + numerator, + denominator, + }); + Permill::zero() // Return zero as a fallback + }), }; - // update the share to ChannelVtokenShares storage - ChannelVtokenShares::::insert(channel_id, vtoken, channel_new_share); + *share = channel_new_share; Self::deposit_event(Event::ChannelVtokenSharesUpdated { channel_id, vtoken, share: channel_new_share, }); - } - }, - ); + }); + } + } } pub(crate) fn clear_bifrost_commissions() { @@ -807,34 +834,56 @@ impl Pallet { // transfer the bifrost commission amount from CommissionPalletId account to the bifrost // commission receiver account - let _ = T::MultiCurrency::transfer( + if let Err(_) = T::MultiCurrency::transfer( commission_token, &Self::account_id(), &T::BifrostCommissionReceiver::get(), bifrost_commission, - ); + ) { + log::error!( + "Failed to transfer bifrost commission for token: {:?}", + commission_token + ); + Self::deposit_event(Event::BifrostCommissionTransferFailed { + from: Self::account_id(), + to: T::BifrostCommissionReceiver::get(), + commission_token, + amount: bifrost_commission, + }); + } }); // clear PeriodClearedCommissions - let _ = PeriodClearedCommissions::::clear(REMOVE_TOKEN_LIMIT, None); + let res = PeriodClearedCommissions::::clear(REMOVE_TOKEN_LIMIT, None); + let executed_num = res.backend; + if let Err(_) = Self::check_removed_all(res) { + log::error!("The removal process was not complete; cursor is still present."); + Self::deposit_event(Event::RemovalNotCompleteError { + target_num: PeriodClearedCommissions::::iter().count() as u32, + limit: REMOVE_TOKEN_LIMIT, + executed_num, + }); + } } pub(crate) fn calculate_mul_div_result( multiplier_1: BalanceOf, multiplier_2: BalanceOf, divider: BalanceOf, - ) -> BalanceOf { + ) -> Result, Error> { if divider.is_zero() { - return Zero::zero(); + return Ok(Zero::zero()); } - let result: u128 = U256::from(multiplier_1.saturated_into::()) - .saturating_mul(multiplier_2.saturated_into::().into()) - .checked_div(divider.saturated_into::().into()) - .map(|x| u128::try_from(x).unwrap_or(Zero::zero())) - .unwrap_or(Zero::zero()); + let result: u128 = multiply_by_rational_with_rounding( + multiplier_1.saturated_into::(), + multiplier_2.saturated_into::(), + divider.saturated_into::(), + Rounding::Down, + ) + .ok_or(Error::DivisionByZero)?; - BalanceOf::::unique_saturated_from(result) + Ok(BalanceOf::::unique_saturated_from(result)) } pub(crate) fn account_id() -> AccountIdOf { @@ -845,13 +894,12 @@ impl Pallet { // get channel receive account let channel_op = Channels::::get(channel_id); - let receiver_account = if let Some(channel_info) = channel_op { - channel_info.0 - } else { - Err(Error::::ChannelNotExist)? - }; + let receiver_account = channel_op + .map(|channel_info| channel_info.0) + .ok_or(Error::::ChannelNotExist)?; // transfer all the claimable commission amount to the channel receive account + let mut tokens_to_remove = Vec::new(); for (commission_token, amount) in ChannelClaimableCommissions::::iter_prefix(channel_id) { T::MultiCurrency::transfer( @@ -862,14 +910,22 @@ impl Pallet { ) .map_err(|_| Error::::TransferError)?; - // remove the commission amount from ChannelClaimableCommissions storage + // Collect the token for removal after iteration + tokens_to_remove.push((commission_token, amount)); + } + // Remove the collected tokens from ChannelClaimableCommissions storage + for (commission_token, amount) in tokens_to_remove { ChannelClaimableCommissions::::remove(channel_id, commission_token); - Self::deposit_event(Event::CommissionClaimed { channel_id, commission_token, amount }); } Ok(()) } + + fn check_removed_all(res: MultiRemovalResults) -> Result<(), Error> { + ensure!(res.maybe_cursor.is_none(), Error::::RemovalNotComplete); + Ok(()) + } } impl VTokenMintRedeemProvider> for Pallet { @@ -882,22 +938,26 @@ impl VTokenMintRedeemProvider> for Pallet return Ok(()); } - // first add to PeriodVtokenTotalMint - let mut total_mint = PeriodVtokenTotalMint::::get(vtoken); - let sum_up_amount = total_mint.1.checked_add(&amount).ok_or(Error::::Overflow)?; - - total_mint.1 = sum_up_amount; - PeriodVtokenTotalMint::::insert(vtoken, total_mint); + // Retrieve and update total mint for the given vtoken in a single step. + PeriodVtokenTotalMint::::mutate(vtoken, |total_mint| -> Result<(), Error> { + // Safely add the new amount to the existing total. + total_mint.1 = total_mint.1.checked_add(&amount).ok_or(Error::::Overflow)?; + Ok(()) + })?; - // only non-bifrost minting needs to record the channel minting amount + // Only non-Bifrost minting needs to record the channel minting amount. if let Some(channel_id) = channel_id { - // then add to PeriodChannelVtokenMint - let mut channel_vtoken_mint = PeriodChannelVtokenMint::::get(channel_id, vtoken); - let sum_up_amount = - channel_vtoken_mint.1.checked_add(&amount).ok_or(Error::::Overflow)?; - - channel_vtoken_mint.1 = sum_up_amount; - PeriodChannelVtokenMint::::insert(channel_id, vtoken, channel_vtoken_mint); + PeriodChannelVtokenMint::::mutate( + channel_id, + vtoken, + |channel_vtoken_mint| -> Result<(), Error> { + let sum_up_amount = + channel_vtoken_mint.1.checked_add(&amount).ok_or(Error::::Overflow)?; + + channel_vtoken_mint.1 = sum_up_amount; + Ok(()) + }, + )?; } Ok(()) @@ -908,12 +968,11 @@ impl VTokenMintRedeemProvider> for Pallet return Ok(()); } - // first add to PeriodVtokenTotalRedeem - let mut total_redeem = PeriodVtokenTotalRedeem::::get(vtoken); - let sum_up_amount = total_redeem.1.checked_add(&amount).ok_or(Error::::Overflow)?; - - total_redeem.1 = sum_up_amount; - PeriodVtokenTotalRedeem::::insert(vtoken, total_redeem); + // First, add to PeriodVtokenTotalRedeem. + PeriodVtokenTotalRedeem::::mutate(vtoken, |total_redeem| -> Result<(), Error> { + total_redeem.1 = total_redeem.1.checked_add(&amount).ok_or(Error::::Overflow)?; + Ok(()) + })?; Ok(()) } @@ -932,16 +991,18 @@ impl SlpHostingFeeProvider, AccountIdOf> // get the commission token of the staking token let vtoken = staking_token.to_vtoken().map_err(|_| Error::::ConversionError)?; - // if the vtoken is not configured for commission, just don't record the hosting fee + // If the vtoken is configured for commission, record the hosting fee if let Some(commission_token) = CommissionTokens::::get(vtoken) { - // add to PeriodTotalCommissions - let mut total_commission = PeriodTotalCommissions::::get(commission_token); - - let sum_up_amount = - total_commission.1.checked_add(&amount).ok_or(Error::::Overflow)?; - - total_commission.1 = sum_up_amount; - PeriodTotalCommissions::::insert(commission_token, total_commission); + PeriodTotalCommissions::::mutate( + commission_token, + |total_commission| -> Result<(), Error> { + let sum_up_amount = + total_commission.1.checked_add(&amount).ok_or(Error::::Overflow)?; + + total_commission.1 = sum_up_amount; + Ok(()) + }, + )?; } Ok(()) diff --git a/pallets/channel-commission/src/tests.rs b/pallets/channel-commission/src/tests.rs index 3ab8bd008..597d81654 100644 --- a/pallets/channel-commission/src/tests.rs +++ b/pallets/channel-commission/src/tests.rs @@ -83,6 +83,48 @@ fn set_commission_tokens_should_work() { }); } +#[test] +fn set_commission_tokens_should_fail_with_invalid_vtoken() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + assert_noop!( + ChannelCommission::set_commission_tokens(RuntimeOrigin::signed(ALICE), KSM, Some(KSM)), + Error::::InvalidVtoken + ); + + assert_noop!( + ChannelCommission::set_commission_tokens(RuntimeOrigin::signed(ALICE), KSM, None), + Error::::InvalidVtoken + ); + }); +} + +#[test] +fn set_commission_tokens_should_fail_with_no_change() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + assert_ok!(ChannelCommission::set_commission_tokens( + RuntimeOrigin::signed(ALICE), + VKSM, + Some(KSM), + )); + + assert_noop!( + ChannelCommission::set_commission_tokens(RuntimeOrigin::signed(ALICE), VKSM, Some(KSM)), + Error::::NoChangesMade + ); + + assert_ok!(ChannelCommission::set_commission_tokens( + RuntimeOrigin::signed(ALICE), + VKSM, + None, + )); + + assert_noop!( + ChannelCommission::set_commission_tokens(RuntimeOrigin::signed(ALICE), VKSM, None), + Error::::NoChangesMade + ); + }); +} + #[test] fn register_channel_should_work() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { @@ -155,6 +197,17 @@ fn remove_channel_should_work() { }); } +#[test] +fn remove_channel_should_fail_with_channel_not_exist() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + assert_eq!(Channels::::get(0), None); + assert_noop!( + ChannelCommission::remove_channel(RuntimeOrigin::signed(ALICE), 0), + Error::::ChannelNotExist + ); + }); +} + #[test] fn update_channel_receive_account_should_work() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { @@ -184,6 +237,49 @@ fn update_channel_receive_account_should_work() { }); } +#[test] +fn update_channel_receive_account_should_fail_with_channel_not_exist() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + assert_eq!(Channels::::get(0), None); + assert_noop!( + ChannelCommission::update_channel_receive_account( + RuntimeOrigin::signed(ALICE), + 0, + CHANNEL_A_RECEIVER, + ), + Error::::ChannelNotExist + ); + }); +} + +#[test] +fn update_channel_receive_account_should_fail_with_no_changes() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + setup(); + + // Channel A is registered + assert_eq!( + Channels::::get(0), + Some((CHANNEL_A_RECEIVER, BoundedVec::try_from(CHANNEL_A_NAME.to_vec()).unwrap())) + ); + + assert_noop!( + ChannelCommission::update_channel_receive_account( + RuntimeOrigin::signed(ALICE), + 0, + CHANNEL_A_RECEIVER, + ), + Error::::NoChangesMade + ); + + // Channel A's receive account is updated + assert_eq!( + Channels::::get(0), + Some((CHANNEL_A_RECEIVER, BoundedVec::try_from(CHANNEL_A_NAME.to_vec()).unwrap())) + ); + }); +} + #[test] fn set_channel_commission_token_should_work() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { @@ -217,6 +313,58 @@ fn set_channel_commission_token_should_work() { }); } +#[test] +fn set_channel_commission_token_should_fail_with_invalid_vtoken() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + assert_noop!( + ChannelCommission::set_channel_commission_token( + RuntimeOrigin::signed(ALICE), + 0, + KSM, + Percent::from_percent(50), + ), + Error::::InvalidVtoken + ); + }); +} + +#[test] +fn set_channel_commission_token_should_fail_with_channel_not_exist() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + assert_eq!(Channels::::get(0), None); + assert_noop!( + ChannelCommission::set_channel_commission_token( + RuntimeOrigin::signed(ALICE), + 0, + VKSM, + Percent::from_percent(50), + ), + Error::::ChannelNotExist + ); + }); +} + +#[test] +fn set_channel_commission_token_should_fail_with_not_configure_commission() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + assert_ok!(ChannelCommission::register_channel( + RuntimeOrigin::signed(ALICE), + CHANNEL_A_NAME.to_vec(), + CHANNEL_A_RECEIVER.clone(), + )); + + assert_noop!( + ChannelCommission::set_channel_commission_token( + RuntimeOrigin::signed(ALICE), + 0, + VKSM, + Percent::from_percent(50), + ), + Error::::VtokenNotConfiguredForCommission + ); + }); +} + #[test] fn claim_commissions_should_work() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { @@ -263,6 +411,35 @@ fn claim_commissions_should_work() { }); } +#[test] +fn claim_commissions_should_fail_with_channel_not_exist() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + assert_noop!( + ChannelCommission::claim_commissions( + RuntimeOrigin::signed(CHANNEL_A_RECEIVER.clone()), + 0, + ), + Error::::ChannelNotExist + ); + }); +} + +#[test] +fn claim_commissions_should_fail_with_transfer_error() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + setup(); + + ChannelClaimableCommissions::::insert(0, KSM, 100); + assert_noop!( + ChannelCommission::claim_commissions( + RuntimeOrigin::signed(CHANNEL_A_RECEIVER.clone()), + 0, + ), + Error::::TransferError + ); + }); +} + #[test] fn channel_commission_distribution_with_net_mint_positive_should_work() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { @@ -542,6 +719,42 @@ fn set_channel_vtoken_shares_should_work() { }); } +#[test] +fn set_channel_vtoken_shares_should_fail_with_channel_not_exist() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + assert_noop!( + ChannelCommission::set_channel_vtoken_shares( + RuntimeOrigin::signed(ALICE), + 0, + VKSM, + Permill::from_percent(90), + ), + Error::::ChannelNotExist + ); + }); +} + +#[test] +fn set_channel_vtoken_shares_should_fail_with_vtoken_not_configured() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + assert_ok!(ChannelCommission::register_channel( + RuntimeOrigin::signed(ALICE), + CHANNEL_A_NAME.to_vec(), + CHANNEL_A_RECEIVER.clone(), + )); + + assert_noop!( + ChannelCommission::set_channel_vtoken_shares( + RuntimeOrigin::signed(ALICE), + 0, + VKSM, + Permill::from_percent(90), + ), + Error::::VtokenNotConfiguredForCommission + ); + }); +} + // register a new channel base on some existing channels, and mint some tokens to see whether the // shares of existing channels are updated correctly.s #[test] @@ -599,3 +812,123 @@ fn register_a_new_channel_and_mint_should_update_shares_and_get_claimable_tokens assert_eq!(ChannelVtokenShares::::get(0, VKSM), channel_a_new_percentage); }); } + +#[test] +fn on_initialize_hook_should_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let commission_account: AccountId = + ::CommissionPalletId::get().into_account_truncating(); + + // set the block number to 35 + System::set_block_number(35); + + setup(); + + // test case 1: net mint is positive.(VKSM) + + // first, set storages for test case 1 + // The first round, set channel A has a share of 20%, channel B has a share of 10%. Channel + // C has not participated yet. + let channel_a_share = Permill::from_percent(20); + ChannelVtokenShares::::insert(0, VKSM, channel_a_share); + + let channel_b_share = Permill::from_percent(10); + ChannelVtokenShares::::insert(1, VKSM, channel_b_share); + + // VtokenIssuanceSnapshots, set both VKSM and VBNC old total issuance to 10000. newly minted + // VKSM is 1000, VBNC is 1000. + VtokenIssuanceSnapshots::::insert(VKSM, (9000, 10000)); + + // PeriodVtokenTotalMint + PeriodVtokenTotalMint::::insert(VKSM, (10000, 2000)); + + // PeriodVtokenTotalRedeem + PeriodVtokenTotalRedeem::::insert(VKSM, (0, 1000)); + + // PeriodChannelVtokenMint. Channel A mint 1000 VKSM, Channel B mint 1000 VKSM. + PeriodChannelVtokenMint::::insert(0, VKSM, (2000, 500)); + PeriodChannelVtokenMint::::insert(1, VKSM, (2000, 100)); + + // PeriodTotalCommissions + PeriodTotalCommissions::::insert(KSM, (0, 100)); + + // set vksm token issuance to 11000 + let _ = Currencies::update_balance( + RuntimeOrigin::root(), + commission_account.clone(), + VKSM, + 11000, + ); + + // set ksm token issuance to 11000 + let _ = Currencies::update_balance( + RuntimeOrigin::root(), + commission_account.clone(), + KSM, + 11000, + ); + + // check balance of commission account + assert_eq!(Currencies::free_balance(VKSM, &commission_account), 11000); + + // set block number to 100 + ChannelCommission::on_initialize(100); + // set_clearing_environment already been called in block 100 + // check whether the clearing environment is set correctly for block 100 + assert_eq!(VtokenIssuanceSnapshots::::get(VKSM), (10000, 11000)); + assert_eq!(PeriodVtokenTotalMint::::get(VKSM), (2000, 0)); + assert_eq!(PeriodVtokenTotalRedeem::::get(VKSM), (1000, 0)); + assert_eq!(PeriodChannelVtokenMint::::get(0, VKSM), (500, 0)); + assert_eq!(PeriodChannelVtokenMint::::get(1, VKSM), (100, 0)); + assert_eq!(PeriodTotalCommissions::::get(KSM), (100, 0)); + + // get channel B's vtoken share before being cleared + let channel_b_vtoken_share_before = ChannelVtokenShares::::get(1, VKSM); + + ChannelCommission::on_initialize(101); + + let channel_a_commission = 4; + // check channel A claimable KSM amount after being cleared + assert_eq!(ChannelClaimableCommissions::::get(0, KSM), channel_a_commission); + + let channel_a_new_percentage = + Permill::from_rational_with_rounding(2250u32, 11000u32, Rounding::Down).unwrap(); + // check channel A vtoken share after being cleared + assert_eq!(ChannelVtokenShares::::get(0, VKSM), channel_a_new_percentage); + + // check channel B has not been cleared yet + assert_eq!(ChannelClaimableCommissions::::get(1, KSM), 0); + assert_eq!(ChannelVtokenShares::::get(1, VKSM), channel_b_vtoken_share_before); + + ChannelCommission::on_initialize(102); + + let channel_b_commission = 2; + // check channel B claimable KSM amount after being cleared + assert_eq!(ChannelClaimableCommissions::::get(1, KSM), channel_b_commission); + + let channel_b_new_percentage = + Permill::from_rational_with_rounding(1050u32, 11000u32, Rounding::Down).unwrap(); + // check channel B vtoken share after being cleared + assert_eq!(ChannelVtokenShares::::get(1, VKSM), channel_b_new_percentage); + + // check PeriodClearedCommissions, should be channel a commission + channel b commission + assert_eq!(PeriodClearedCommissions::::get(KSM), 6); + + let bifrost_commission_receiver: AccountId32 = + ::BifrostCommissionReceiver::get(); + // check Bifrost commission balance before being cleared + let bifrost_account_balance_before = + Currencies::free_balance(KSM, &bifrost_commission_receiver); + assert_eq!(bifrost_account_balance_before, 0); + + ChannelCommission::on_initialize(103); + + // cleared commissions should be none + assert_eq!(PeriodClearedCommissions::::get(KSM), 0); + + // check Bifrost commission balance after being cleared + let bifrost_commission_balance_after = + Currencies::free_balance(KSM, &bifrost_commission_receiver); + assert_eq!(bifrost_commission_balance_after, 100 - 6); + }); +} diff --git a/pallets/clouds-convert/Cargo.toml b/pallets/clouds-convert/Cargo.toml index 088e75647..8a843fb44 100644 --- a/pallets/clouds-convert/Cargo.toml +++ b/pallets/clouds-convert/Cargo.toml @@ -14,7 +14,7 @@ sp-runtime = { workspace = true } frame-benchmarking = { workspace = true, optional = true } bifrost-primitives = { workspace = true } orml-traits = { workspace = true } -bifrost-ve-minting = { workspace = true } +bb-bnc = { workspace = true } sp-core = { workspace = true } pallet-balances = { workspace = true } @@ -37,7 +37,7 @@ std = [ "frame-system/std", "frame-benchmarking?/std", "orml-traits/std", - "bifrost-ve-minting/std", + "bb-bnc/std", "orml-tokens/std", "bifrost-currencies/std", "sp-io/std", diff --git a/pallets/clouds-convert/src/lib.rs b/pallets/clouds-convert/src/lib.rs index 194782e00..100d27baf 100644 --- a/pallets/clouds-convert/src/lib.rs +++ b/pallets/clouds-convert/src/lib.rs @@ -22,11 +22,11 @@ extern crate alloc; use alloc::vec; +use bb_bnc::BbBNCInterface; use bifrost_primitives::{ currency::{CLOUD, VBNC}, CurrencyId, }; -use bifrost_ve_minting::VeMintingInterface; use frame_support::{ ensure, pallet_prelude::*, @@ -70,8 +70,8 @@ pub mod pallet { /// Clouds Pallet Id type CloudsPalletId: Get; - // veMinting interface - type VeMinting: VeMintingInterface< + // bbBNC interface + type BbBNC: BbBNCInterface< AccountIdOf, CurrencyIdOf, BalanceOf, @@ -138,7 +138,7 @@ pub mod pallet { T::MultiCurrency::transfer(VBNC, &vbnc_pool_account, &who, can_get_vbnc)?; // mint veBNC for user - T::VeMinting::create_lock_inner(&who, can_get_vbnc, T::LockedBlocks::get())?; + T::BbBNC::create_lock_inner(&who, can_get_vbnc, T::LockedBlocks::get())?; // deposit event Self::deposit_event(Event::CloudsConverted { clouds: value, vebnc: can_get_vbnc }); diff --git a/pallets/clouds-convert/src/mock.rs b/pallets/clouds-convert/src/mock.rs index ad5914f29..72a89989b 100644 --- a/pallets/clouds-convert/src/mock.rs +++ b/pallets/clouds-convert/src/mock.rs @@ -53,7 +53,7 @@ frame_support::construct_runtime!( Currencies: bifrost_currencies, AssetRegistry: bifrost_asset_registry, CloudsConvert: bifrost_clouds_convert, - VeMinting: bifrost_ve_minting, + BbBNC: bb_bnc, } ); @@ -174,15 +174,15 @@ impl bifrost_clouds_convert::Config for Runtime { type RuntimeEvent = RuntimeEvent; type MultiCurrency = Currencies; type CloudsPalletId = CloudsPalletId; - type VeMinting = VeMinting; + type BbBNC = BbBNC; type WeightInfo = (); type LockedBlocks = MaxBlock; } parameter_types! { - pub const VeMintingTokenType: CurrencyId = CurrencyId::VToken(TokenSymbol::BNC); - pub VeMintingPalletId: PalletId = PalletId(*b"bf/vemnt"); - pub IncentivePalletId: PalletId = PalletId(*b"bf/veict"); + pub const BbBNCTokenType: CurrencyId = CurrencyId::VToken(TokenSymbol::BNC); + pub IncentivePalletId: PalletId = PalletId(*b"bf/bbict"); + pub const BuyBackAccount: PalletId = PalletId(*b"bf/bybck"); pub const Week: BlockNumber = 50400; // a week pub const MaxBlock: BlockNumber = 10512000; // four years pub const Multiplier: Balance = 10_u128.pow(12); @@ -191,13 +191,13 @@ parameter_types! { pub const MarkupRefreshLimit: u32 = 100; } -impl bifrost_ve_minting::Config for Runtime { +impl bb_bnc::Config for Runtime { type RuntimeEvent = RuntimeEvent; type MultiCurrency = Currencies; type ControlOrigin = EnsureSignedBy; - type TokenType = VeMintingTokenType; - type VeMintingPalletId = VeMintingPalletId; + type TokenType = BbBNCTokenType; type IncentivePalletId = IncentivePalletId; + type BuyBackAccount = BuyBackAccount; type WeightInfo = (); type BlockNumberToBalance = ConvertInto; type Week = Week; diff --git a/pallets/clouds-convert/src/tests.rs b/pallets/clouds-convert/src/tests.rs index 3b8cfdcf3..c325395bf 100644 --- a/pallets/clouds-convert/src/tests.rs +++ b/pallets/clouds-convert/src/tests.rs @@ -57,7 +57,7 @@ fn clouds_to_vebnc_should_work() { // check the veBNC balance of Bob let bob_old_vebnc_balance = - ::VeMinting::balance_of(&BOB, None).unwrap(); + ::BbBNC::balance_of(&BOB, None).unwrap(); // check the old pool balance let old_pool_balance = ::MultiCurrency::free_balance( @@ -70,7 +70,7 @@ fn clouds_to_vebnc_should_work() { // check the veBNC balance of Bob assert_eq!( - ::VeMinting::balance_of(&BOB, None).unwrap(), + ::BbBNC::balance_of(&BOB, None).unwrap(), bob_old_vebnc_balance + 20034907200 ); diff --git a/pallets/cross-in-out/src/benchmarking.rs b/pallets/cross-in-out/src/benchmarking.rs index 3130940da..31d102378 100644 --- a/pallets/cross-in-out/src/benchmarking.rs +++ b/pallets/cross-in-out/src/benchmarking.rs @@ -19,6 +19,7 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg(feature = "runtime-benchmarks")] +#![allow(deprecated)] use bifrost_primitives::{CurrencyId, TokenSymbol}; use frame_benchmarking::v1::{account, benchmarks, whitelisted_caller, BenchmarkError}; diff --git a/pallets/cross-in-out/src/lib.rs b/pallets/cross-in-out/src/lib.rs index 5f1841e6c..9cf42a272 100644 --- a/pallets/cross-in-out/src/lib.rs +++ b/pallets/cross-in-out/src/lib.rs @@ -144,24 +144,20 @@ pub mod pallet { /// To store currencies that support indirect cross-in and cross-out. #[pallet::storage] - #[pallet::getter(fn get_cross_currency_registry)] pub type CrossCurrencyRegistry = StorageMap<_, Blake2_128Concat, CurrencyId, ()>; /// Accounts in the whitelist can issue the corresponding Currency. #[pallet::storage] - #[pallet::getter(fn get_issue_whitelist)] pub type IssueWhiteList = StorageMap<_, Blake2_128Concat, CurrencyId, BoundedVec, T::MaxLengthLimit>>; /// Accounts in the whitelist can register the mapping between a multilocation and an accountId. #[pallet::storage] - #[pallet::getter(fn get_register_whitelist)] pub type RegisterWhiteList = StorageMap<_, Blake2_128Concat, CurrencyId, Vec>>; /// Mapping a Bifrost account to a multilocation of a outer chain #[pallet::storage] - #[pallet::getter(fn account_to_outer_multilocation)] pub type AccountToOuterMultilocation = StorageDoubleMap< _, Blake2_128Concat, @@ -174,7 +170,6 @@ pub mod pallet { /// Mapping a multilocation of a outer chain to a Bifrost account #[pallet::storage] - #[pallet::getter(fn outer_multilocation_to_account)] pub type OuterMultilocationToAccount = StorageDoubleMap< _, Blake2_128Concat, @@ -187,7 +182,6 @@ pub mod pallet { /// minimum crossin and crossout amount【crossinMinimum, crossoutMinimum】 #[pallet::storage] - #[pallet::getter(fn get_crossing_minimum_amount)] pub type CrossingMinimumAmount = StorageMap<_, Blake2_128Concat, CurrencyId, (BalanceOf, BalanceOf)>; @@ -217,12 +211,12 @@ pub mod pallet { Error::::CurrencyNotSupportCrossInAndOut ); - let crossing_minimum_amount = Self::get_crossing_minimum_amount(currency_id) + let crossing_minimum_amount = CrossingMinimumAmount::::get(currency_id) .ok_or(Error::::NoCrossingMinimumSet)?; ensure!(amount >= crossing_minimum_amount.0, Error::::AmountLowerThanMinimum); let issue_whitelist = - Self::get_issue_whitelist(currency_id).ok_or(Error::::NotAllowed)?; + IssueWhiteList::::get(currency_id).ok_or(Error::::NotAllowed)?; ensure!(issue_whitelist.contains(&issuer), Error::::NotAllowed); let entrance_account_mutlilcaition = Box::new(MultiLocation { @@ -237,7 +231,7 @@ pub mod pallet { let dest = if entrance_account_mutlilcaition == location { T::EntrancePalletId::get().into_account_truncating() } else { - Self::outer_multilocation_to_account(currency_id, location.clone()) + OuterMultilocationToAccount::::get(currency_id, location.clone()) .ok_or(Error::::NoAccountIdMapping)? }; @@ -268,7 +262,7 @@ pub mod pallet { Error::::CurrencyNotSupportCrossInAndOut ); - let crossing_minimum_amount = Self::get_crossing_minimum_amount(currency_id) + let crossing_minimum_amount = CrossingMinimumAmount::::get(currency_id) .ok_or(Error::::NoCrossingMinimumSet)?; ensure!(amount >= crossing_minimum_amount.1, Error::::AmountLowerThanMinimum); @@ -296,7 +290,7 @@ pub mod pallet { let registerer = ensure_signed(origin)?; let register_whitelist = - Self::get_register_whitelist(currency_id).ok_or(Error::::NotAllowed)?; + RegisterWhiteList::::get(currency_id).ok_or(Error::::NotAllowed)?; ensure!(register_whitelist.contains(®isterer), Error::::NotAllowed); ensure!( @@ -346,7 +340,7 @@ pub mod pallet { ); let original_location = - Self::account_to_outer_multilocation(currency_id, account.clone()) + AccountToOuterMultilocation::::get(currency_id, account.clone()) .ok_or(Error::::NotExist)?; ensure!(original_location != *foreign_location.clone(), Error::::AlreadyExist); @@ -413,7 +407,7 @@ pub mod pallet { ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - let rs = Self::get_issue_whitelist(currency_id); + let rs = IssueWhiteList::::get(currency_id); let mut issue_whitelist; if let Some(bounded_vec) = rs { issue_whitelist = bounded_vec.to_vec(); @@ -471,7 +465,7 @@ pub mod pallet { T::ControlOrigin::ensure_origin(origin)?; let empty_vec: Vec> = Vec::new(); - if Self::get_register_whitelist(currency_id) == None { + if RegisterWhiteList::::get(currency_id) == None { RegisterWhiteList::::insert(currency_id, empty_vec); } diff --git a/pallets/cross-in-out/src/tests.rs b/pallets/cross-in-out/src/tests.rs index 77ee7d706..0e60781cb 100644 --- a/pallets/cross-in-out/src/tests.rs +++ b/pallets/cross-in-out/src/tests.rs @@ -119,11 +119,11 @@ fn cross_in_and_cross_out_should_work() { #[test] fn add_to_and_remove_from_issue_whitelist_should_work() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { - assert_eq!(CrossInOut::get_issue_whitelist(KSM), None); + assert_eq!(IssueWhiteList::::get(KSM), None); assert_ok!(CrossInOut::add_to_issue_whitelist(RuntimeOrigin::signed(ALICE), KSM, ALICE)); let bounded_vector = BoundedVec::try_from(vec![ALICE]).unwrap(); - assert_eq!(CrossInOut::get_issue_whitelist(KSM), Some(bounded_vector)); + assert_eq!(IssueWhiteList::::get(KSM), Some(bounded_vector)); assert_noop!( CrossInOut::remove_from_issue_whitelist(RuntimeOrigin::signed(ALICE), KSM, BOB), @@ -136,17 +136,17 @@ fn add_to_and_remove_from_issue_whitelist_should_work() { ALICE )); let empty_vec = BoundedVec::default(); - assert_eq!(CrossInOut::get_issue_whitelist(KSM), Some(empty_vec)); + assert_eq!(IssueWhiteList::::get(KSM), Some(empty_vec)); }); } #[test] fn add_to_and_remove_from_register_whitelist_should_work() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { - assert_eq!(CrossInOut::get_register_whitelist(KSM), None); + assert_eq!(RegisterWhiteList::::get(KSM), None); assert_ok!(CrossInOut::add_to_register_whitelist(RuntimeOrigin::signed(ALICE), KSM, ALICE)); - assert_eq!(CrossInOut::get_register_whitelist(KSM), Some(vec![ALICE])); + assert_eq!(RegisterWhiteList::::get(KSM), Some(vec![ALICE])); assert_noop!( CrossInOut::remove_from_register_whitelist(RuntimeOrigin::signed(ALICE), KSM, BOB), @@ -158,7 +158,7 @@ fn add_to_and_remove_from_register_whitelist_should_work() { KSM, ALICE )); - assert_eq!(CrossInOut::get_register_whitelist(KSM), Some(vec![])); + assert_eq!(RegisterWhiteList::::get(KSM), Some(vec![])); }); } diff --git a/pallets/call-switchgear/Cargo.toml b/pallets/deprecated/call-switchgear/Cargo.toml similarity index 100% rename from pallets/call-switchgear/Cargo.toml rename to pallets/deprecated/call-switchgear/Cargo.toml diff --git a/pallets/call-switchgear/src/benchmarking.rs b/pallets/deprecated/call-switchgear/src/benchmarking.rs similarity index 100% rename from pallets/call-switchgear/src/benchmarking.rs rename to pallets/deprecated/call-switchgear/src/benchmarking.rs diff --git a/pallets/call-switchgear/src/lib.rs b/pallets/deprecated/call-switchgear/src/lib.rs similarity index 100% rename from pallets/call-switchgear/src/lib.rs rename to pallets/deprecated/call-switchgear/src/lib.rs diff --git a/pallets/call-switchgear/src/mock.rs b/pallets/deprecated/call-switchgear/src/mock.rs similarity index 100% rename from pallets/call-switchgear/src/mock.rs rename to pallets/deprecated/call-switchgear/src/mock.rs diff --git a/pallets/call-switchgear/src/tests.rs b/pallets/deprecated/call-switchgear/src/tests.rs similarity index 100% rename from pallets/call-switchgear/src/tests.rs rename to pallets/deprecated/call-switchgear/src/tests.rs diff --git a/pallets/call-switchgear/src/weights.rs b/pallets/deprecated/call-switchgear/src/weights.rs similarity index 100% rename from pallets/call-switchgear/src/weights.rs rename to pallets/deprecated/call-switchgear/src/weights.rs diff --git a/pallets/lightening-redeem/Cargo.toml b/pallets/deprecated/lightening-redeem/Cargo.toml similarity index 100% rename from pallets/lightening-redeem/Cargo.toml rename to pallets/deprecated/lightening-redeem/Cargo.toml diff --git a/pallets/lightening-redeem/src/benchmarking.rs b/pallets/deprecated/lightening-redeem/src/benchmarking.rs similarity index 100% rename from pallets/lightening-redeem/src/benchmarking.rs rename to pallets/deprecated/lightening-redeem/src/benchmarking.rs diff --git a/pallets/lightening-redeem/src/lib.rs b/pallets/deprecated/lightening-redeem/src/lib.rs similarity index 100% rename from pallets/lightening-redeem/src/lib.rs rename to pallets/deprecated/lightening-redeem/src/lib.rs diff --git a/pallets/lightening-redeem/src/mock.rs b/pallets/deprecated/lightening-redeem/src/mock.rs similarity index 100% rename from pallets/lightening-redeem/src/mock.rs rename to pallets/deprecated/lightening-redeem/src/mock.rs diff --git a/pallets/lightening-redeem/src/tests.rs b/pallets/deprecated/lightening-redeem/src/tests.rs similarity index 100% rename from pallets/lightening-redeem/src/tests.rs rename to pallets/deprecated/lightening-redeem/src/tests.rs diff --git a/pallets/lightening-redeem/src/weights.rs b/pallets/deprecated/lightening-redeem/src/weights.rs similarity index 100% rename from pallets/lightening-redeem/src/weights.rs rename to pallets/deprecated/lightening-redeem/src/weights.rs diff --git a/pallets/liquidity-mining/Cargo.toml b/pallets/deprecated/liquidity-mining/Cargo.toml similarity index 100% rename from pallets/liquidity-mining/Cargo.toml rename to pallets/deprecated/liquidity-mining/Cargo.toml diff --git a/pallets/liquidity-mining/README-CN.md b/pallets/deprecated/liquidity-mining/README-CN.md similarity index 100% rename from pallets/liquidity-mining/README-CN.md rename to pallets/deprecated/liquidity-mining/README-CN.md diff --git a/pallets/liquidity-mining/README.md b/pallets/deprecated/liquidity-mining/README.md similarity index 100% rename from pallets/liquidity-mining/README.md rename to pallets/deprecated/liquidity-mining/README.md diff --git a/pallets/liquidity-mining/img/liquidity-mining-flow@2x.png b/pallets/deprecated/liquidity-mining/img/liquidity-mining-flow@2x.png similarity index 100% rename from pallets/liquidity-mining/img/liquidity-mining-flow@2x.png rename to pallets/deprecated/liquidity-mining/img/liquidity-mining-flow@2x.png diff --git a/pallets/liquidity-mining/rpc/Cargo.toml b/pallets/deprecated/liquidity-mining/rpc/Cargo.toml similarity index 100% rename from pallets/liquidity-mining/rpc/Cargo.toml rename to pallets/deprecated/liquidity-mining/rpc/Cargo.toml diff --git a/pallets/liquidity-mining/rpc/runtime-api/Cargo.toml b/pallets/deprecated/liquidity-mining/rpc/runtime-api/Cargo.toml similarity index 100% rename from pallets/liquidity-mining/rpc/runtime-api/Cargo.toml rename to pallets/deprecated/liquidity-mining/rpc/runtime-api/Cargo.toml diff --git a/pallets/liquidity-mining/rpc/runtime-api/src/lib.rs b/pallets/deprecated/liquidity-mining/rpc/runtime-api/src/lib.rs similarity index 100% rename from pallets/liquidity-mining/rpc/runtime-api/src/lib.rs rename to pallets/deprecated/liquidity-mining/rpc/runtime-api/src/lib.rs diff --git a/pallets/liquidity-mining/rpc/src/lib.rs b/pallets/deprecated/liquidity-mining/rpc/src/lib.rs similarity index 100% rename from pallets/liquidity-mining/rpc/src/lib.rs rename to pallets/deprecated/liquidity-mining/rpc/src/lib.rs diff --git a/pallets/liquidity-mining/src/benchmarking.rs b/pallets/deprecated/liquidity-mining/src/benchmarking.rs similarity index 100% rename from pallets/liquidity-mining/src/benchmarking.rs rename to pallets/deprecated/liquidity-mining/src/benchmarking.rs diff --git a/pallets/liquidity-mining/src/lib.rs b/pallets/deprecated/liquidity-mining/src/lib.rs similarity index 100% rename from pallets/liquidity-mining/src/lib.rs rename to pallets/deprecated/liquidity-mining/src/lib.rs diff --git a/pallets/liquidity-mining/src/migration.rs b/pallets/deprecated/liquidity-mining/src/migration.rs similarity index 100% rename from pallets/liquidity-mining/src/migration.rs rename to pallets/deprecated/liquidity-mining/src/migration.rs diff --git a/pallets/liquidity-mining/src/mock.rs b/pallets/deprecated/liquidity-mining/src/mock.rs similarity index 100% rename from pallets/liquidity-mining/src/mock.rs rename to pallets/deprecated/liquidity-mining/src/mock.rs diff --git a/pallets/liquidity-mining/src/tests.rs b/pallets/deprecated/liquidity-mining/src/tests.rs similarity index 100% rename from pallets/liquidity-mining/src/tests.rs rename to pallets/deprecated/liquidity-mining/src/tests.rs diff --git a/pallets/liquidity-mining/src/weights.rs b/pallets/deprecated/liquidity-mining/src/weights.rs similarity index 100% rename from pallets/liquidity-mining/src/weights.rs rename to pallets/deprecated/liquidity-mining/src/weights.rs diff --git a/pallets/salp-lite/Cargo.toml b/pallets/deprecated/salp-lite/Cargo.toml similarity index 100% rename from pallets/salp-lite/Cargo.toml rename to pallets/deprecated/salp-lite/Cargo.toml diff --git a/pallets/salp-lite/src/benchmarking.rs b/pallets/deprecated/salp-lite/src/benchmarking.rs similarity index 100% rename from pallets/salp-lite/src/benchmarking.rs rename to pallets/deprecated/salp-lite/src/benchmarking.rs diff --git a/pallets/salp-lite/src/lib.rs b/pallets/deprecated/salp-lite/src/lib.rs similarity index 100% rename from pallets/salp-lite/src/lib.rs rename to pallets/deprecated/salp-lite/src/lib.rs diff --git a/pallets/salp-lite/src/mock.rs b/pallets/deprecated/salp-lite/src/mock.rs similarity index 100% rename from pallets/salp-lite/src/mock.rs rename to pallets/deprecated/salp-lite/src/mock.rs diff --git a/pallets/salp-lite/src/tests.rs b/pallets/deprecated/salp-lite/src/tests.rs similarity index 100% rename from pallets/salp-lite/src/tests.rs rename to pallets/deprecated/salp-lite/src/tests.rs diff --git a/pallets/salp-lite/src/weights.rs b/pallets/deprecated/salp-lite/src/weights.rs similarity index 100% rename from pallets/salp-lite/src/weights.rs rename to pallets/deprecated/salp-lite/src/weights.rs diff --git a/pallets/evm-accounts/Cargo.toml b/pallets/evm-accounts/Cargo.toml index 4542bc2d6..65366645c 100644 --- a/pallets/evm-accounts/Cargo.toml +++ b/pallets/evm-accounts/Cargo.toml @@ -26,6 +26,7 @@ sp-core = { workspace = true } frame-benchmarking = { workspace = true, optional = true } sp-io = { workspace = true, optional = true } pallet-traits = { workspace = true } +sp-runtime = { workspace = true } [dev-dependencies] sp-core = { workspace = true } diff --git a/pallets/evm-accounts/src/lib.rs b/pallets/evm-accounts/src/lib.rs index e86a6d5e2..e77dba36a 100644 --- a/pallets/evm-accounts/src/lib.rs +++ b/pallets/evm-accounts/src/lib.rs @@ -53,6 +53,7 @@ #![cfg_attr(not(feature = "std"), no_std)] +use codec::Encode; use frame_support::{ ensure, pallet_prelude::{DispatchResult, Get}, @@ -62,6 +63,7 @@ use sp_core::{ crypto::{AccountId32, ByteArray}, H160, U256, }; +use sp_runtime::traits::Hash; #[cfg(test)] mod mock; @@ -77,6 +79,7 @@ pub use weights::WeightInfo; pub type Balance = u128; pub type EvmAddress = H160; pub type AccountIdLast12Bytes = [u8; 12]; +pub type Hashing = sp_runtime::traits::BlakeTwo256; pub trait EvmNonceProvider { fn get_nonce(evm_address: H160) -> U256; @@ -112,7 +115,6 @@ pub mod pallet { /// Maps an EVM address to the last 12 bytes of a substrate account. #[pallet::storage] - #[pallet::getter(fn account)] pub(super) type AccountExtension = StorageMap<_, Blake2_128Concat, EvmAddress, AccountIdLast12Bytes>; @@ -272,24 +274,17 @@ impl InspectEvmAccounts for Pallet where T::AccountId: AsRef<[u8; 32]> + frame_support::traits::IsType, { - /// Returns `True` if the account is EVM truncated account. - fn is_evm_account(account_id: T::AccountId) -> bool { - let account_ref = account_id.as_ref(); - &account_ref[0..4] == b"ETH\0" && account_ref[24..32] == [0u8; 8] - } - /// Get the EVM address from the substrate address. fn evm_address(account_id: &impl AsRef<[u8; 32]>) -> EvmAddress { let acc = account_id.as_ref(); EvmAddress::from_slice(&acc[..20]) } - /// Get the truncated address from the EVM address. - fn truncated_account_id(evm_address: EvmAddress) -> T::AccountId { - let mut data: [u8; 32] = [0u8; 32]; - data[0..4].copy_from_slice(b"ETH\0"); - data[4..24].copy_from_slice(&evm_address[..]); - AccountId32::from(data).into() + /// Get the AccountId from the EVM address. + fn convert_account_id(evm_address: EvmAddress) -> T::AccountId { + let payload = (b"AccountId32:", evm_address); + let bytes = payload.using_encoded(Hashing::hash).0; + AccountId32::new(bytes).into() } /// Return the Substrate address bound to the EVM account. If not bound, returns `None`. @@ -304,10 +299,9 @@ where } /// Get the Substrate address from the EVM address. - /// Returns the truncated version of the address if the address wasn't bind. + /// Returns the converted address if the address wasn't bind. fn account_id(evm_address: EvmAddress) -> T::AccountId { - Self::bound_account_id(evm_address) - .unwrap_or_else(|| Self::truncated_account_id(evm_address)) + Self::bound_account_id(evm_address).unwrap_or_else(|| Self::convert_account_id(evm_address)) } /// Returns `True` if the address is allowed to deploy smart contracts. diff --git a/pallets/evm-accounts/src/tests.rs b/pallets/evm-accounts/src/tests.rs index e27d4335f..376a66fa6 100644 --- a/pallets/evm-accounts/src/tests.rs +++ b/pallets/evm-accounts/src/tests.rs @@ -27,10 +27,10 @@ fn eth_address_should_convert_to_truncated_address_when_not_bound() { // Arrange let evm_address = H160::from(hex!["222222ff7Be76052e023Ec1a306fCca8F9659D80"]); let truncated_address = AccountId::from(hex![ - "45544800222222ff7be76052e023ec1a306fcca8f9659d800000000000000000" + "d2efb4a4ab6b9c7dff8d8e1aa76dc53a0aab3a0d93747eb25db1bb7b08a76a09" ]); - assert_eq!(EVMAccounts::truncated_account_id(evm_address), truncated_address); + assert_eq!(EVMAccounts::convert_account_id(evm_address), truncated_address.clone()); // Act & Assert assert_eq!(EVMAccounts::bound_account_id(evm_address), None); diff --git a/pallets/farming/Cargo.toml b/pallets/farming/Cargo.toml index 352fd71ef..50853b064 100644 --- a/pallets/farming/Cargo.toml +++ b/pallets/farming/Cargo.toml @@ -21,7 +21,7 @@ sp-runtime = { workspace = true } hex-literal = { workspace = true } pallet-balances = { workspace = true } sp-arithmetic = { workspace = true } -bifrost-ve-minting = { workspace = true } +bb-bnc = { workspace = true } log = { workspace = true } [dev-dependencies] @@ -30,7 +30,7 @@ bifrost-currencies = { workspace = true } sp-io = { workspace = true } sp-core = { workspace = true } sp-runtime = { workspace = true } -bifrost-ve-minting = { workspace = true } +bb-bnc = { workspace = true } bifrost-asset-registry = { workspace = true } bifrost-runtime-common = { workspace = true } env_logger = { workspace = true } diff --git a/pallets/farming/src/boost.rs b/pallets/farming/src/boost.rs index 6601caf2c..a31e28966 100644 --- a/pallets/farming/src/boost.rs +++ b/pallets/farming/src/boost.rs @@ -17,7 +17,7 @@ // along with this program. If not, see . use crate::*; -use bifrost_ve_minting::VeMintingInterface; +use bb_bnc::BbBNCInterface; #[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo, Default)] pub struct BoostPoolInfo { @@ -44,7 +44,7 @@ impl BoostInterface, CurrencyIdOf, BalanceOf, Bl { fn refresh_vebnc_farming(who: &AccountIdOf) -> DispatchResult { let mut boost_pool_info = Self::boost_pool_infos(); - let new_vote_amount = T::VeMinting::balance_of(who, None)?; + let new_vote_amount = T::BbBNC::balance_of(who, None)?; if let Some(mut user_boost_info) = Self::user_boost_infos(who) { // If the user's last voting block height is greater than or equal to the block height @@ -227,7 +227,7 @@ impl Pallet { } } - let new_vote_amount = T::VeMinting::balance_of(who, None)?; + let new_vote_amount = T::BbBNC::balance_of(who, None)?; let mut percent_check = Percent::from_percent(0); vote_list.iter().try_for_each(|(pid, proportion)| -> DispatchResult { ensure!(Self::boost_whitelist(pid) != None, Error::::NotInWhitelist); diff --git a/pallets/farming/src/gauge.rs b/pallets/farming/src/gauge.rs index f5c7d3311..4827eed16 100644 --- a/pallets/farming/src/gauge.rs +++ b/pallets/farming/src/gauge.rs @@ -123,7 +123,7 @@ where })?; let controller = T::GaugeRewardIssuer::get().into_sub_account_truncating(pid); - T::VeMinting::set_incentive(pid, Some(max_block), Some(controller)); + T::BbBNC::set_incentive(pid, Some(max_block), Some(controller)); Ok(()) } @@ -248,14 +248,10 @@ where let pool_info = PoolInfos::::get(pid).ok_or(Error::::PoolDoesNotExist)?; let share_info = SharesAndWithdrawnRewards::::get(pid, who).ok_or(Error::::ShareInfoNotExists)?; - if T::VeMinting::balance_of(who, None)? == BalanceOf::::zero() { + if T::BbBNC::balance_of(who, None)? == BalanceOf::::zero() { return Ok(()); } - T::VeMinting::update_reward( - pid, - Some(who), - Some((share_info.share, pool_info.total_shares)), - )?; + T::BbBNC::update_reward(pid, Some(who), Some((share_info.share, pool_info.total_shares)))?; Ok(()) } } diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index f518fe5e9..16d71fa2b 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -62,7 +62,7 @@ pub type CurrencyIdOf = <::MultiCurrency as MultiCurrency< type BalanceOf = <::MultiCurrency as MultiCurrency>>::Balance; -use bifrost_ve_minting::VeMintingInterface; +use bb_bnc::BbBNCInterface; use parity_scale_codec::FullCodec; use sp_std::fmt::Debug; @@ -109,7 +109,7 @@ pub mod pallet { #[pallet::constant] type FarmingBoost: Get; - type VeMinting: bifrost_ve_minting::VeMintingInterface< + type BbBNC: bb_bnc::BbBNCInterface< AccountIdOf, CurrencyIdOf, BalanceOf, @@ -363,7 +363,7 @@ pub mod pallet { match gauge_pool_info.gauge_state { GaugeState::Bonded => { let rewards = gauge_pool_info.gauge_basic_rewards.into_iter().collect(); - T::VeMinting::auto_notify_reward(gid, n, rewards).unwrap_or_default(); + T::BbBNC::auto_notify_reward(gid, n, rewards).unwrap_or_default(); }, _ => (), } @@ -804,7 +804,7 @@ pub mod pallet { let pool_info = PoolInfos::::get(gid).ok_or(Error::::PoolDoesNotExist)?; let share_info = SharesAndWithdrawnRewards::::get(gid, &who) .ok_or(Error::::ShareInfoNotExists)?; - T::VeMinting::get_rewards(gid, &who, Some((share_info.share, pool_info.total_shares)))?; + T::BbBNC::get_rewards(gid, &who, Some((share_info.share, pool_info.total_shares)))?; Self::deposit_event(Event::GaugeWithdrawn { who, gid }); Ok(()) @@ -827,7 +827,7 @@ pub mod pallet { let pool_info = PoolInfos::::get(gid).ok_or(Error::::PoolDoesNotExist)?; let share_info = SharesAndWithdrawnRewards::::get(gid, &gauge_info.who) .ok_or(Error::::ShareInfoNotExists)?; - T::VeMinting::get_rewards( + T::BbBNC::get_rewards( gid, &gauge_info.who, Some((share_info.share, pool_info.total_shares)), diff --git a/pallets/farming/src/mock.rs b/pallets/farming/src/mock.rs index 899a71430..fe91ffb78 100644 --- a/pallets/farming/src/mock.rs +++ b/pallets/farming/src/mock.rs @@ -49,7 +49,7 @@ frame_support::construct_runtime!( Balances: pallet_balances, Currencies: bifrost_currencies, Farming: bifrost_farming, - VeMinting: bifrost_ve_minting, + BbBNC: bb_bnc, AssetRegistry: bifrost_asset_registry, } ); @@ -145,16 +145,16 @@ impl bifrost_farming::Config for Runtime { type RewardIssuer = FarmingRewardIssuerPalletId; type FarmingBoost = FarmingBoostPalletId; type WeightInfo = (); - type VeMinting = VeMinting; + type BbBNC = BbBNC; type BlockNumberToBalance = ConvertInto; type WhitelistMaximumLimit = WhitelistMaximumLimit; type GaugeRewardIssuer = FarmingGaugeRewardIssuerPalletId; } parameter_types! { - pub const VeMintingTokenType: CurrencyId = CurrencyId::VToken(TokenSymbol::BNC); - pub VeMintingPalletId: PalletId = PalletId(*b"bf/vemnt"); - pub IncentivePalletId: PalletId = PalletId(*b"bf/veict"); + pub const BbBNCTokenType: CurrencyId = CurrencyId::VToken(TokenSymbol::BNC); + pub IncentivePalletId: PalletId = PalletId(*b"bf/bbict"); + pub const BuyBackAccount: PalletId = PalletId(*b"bf/bybck"); pub const Week: BlockNumber = 50400; // a week pub const MaxBlock: BlockNumber = 10512000; // four years pub const Multiplier: Balance = 10_u128.pow(12); @@ -163,13 +163,13 @@ parameter_types! { pub const MarkupRefreshLimit: u32 = 100; } -impl bifrost_ve_minting::Config for Runtime { +impl bb_bnc::Config for Runtime { type RuntimeEvent = RuntimeEvent; type MultiCurrency = Currencies; type ControlOrigin = EnsureSignedBy; - type TokenType = VeMintingTokenType; - type VeMintingPalletId = VeMintingPalletId; + type TokenType = BbBNCTokenType; type IncentivePalletId = IncentivePalletId; + type BuyBackAccount = BuyBackAccount; type WeightInfo = (); type BlockNumberToBalance = ConvertInto; type Week = Week; diff --git a/pallets/farming/src/rewards.rs b/pallets/farming/src/rewards.rs index 64f321df8..a284fa85d 100644 --- a/pallets/farming/src/rewards.rs +++ b/pallets/farming/src/rewards.rs @@ -295,7 +295,7 @@ impl Pallet { let pool_info = PoolInfos::::get(pool).ok_or(Error::::PoolDoesNotExist)?; let share_info = SharesAndWithdrawnRewards::::get(pool, who) .ok_or(Error::::ShareInfoNotExists)?; - T::VeMinting::get_rewards(pool, who, Some((share_info.share, pool_info.total_shares)))?; + T::BbBNC::get_rewards(pool, who, Some((share_info.share, pool_info.total_shares)))?; } SharesAndWithdrawnRewards::::mutate_exists( pool, diff --git a/pallets/farming/src/tests.rs b/pallets/farming/src/tests.rs index cb6e1f2ee..a114c4467 100644 --- a/pallets/farming/src/tests.rs +++ b/pallets/farming/src/tests.rs @@ -21,7 +21,7 @@ #![cfg(test)] use crate::{mock::*, *}; -use bifrost_ve_minting::VeMintingInterface; +use bb_bnc::BbBNCInterface; use frame_support::{assert_err, assert_ok}; #[test] @@ -79,7 +79,7 @@ fn deposit() { (BalanceOf, BalanceOf, BalanceOf), >::new(), gauge_basic_rewards, - max_block: 1000, + max_block: 7 * 86400 / 12, gauge_amount: 0, total_time_factor: 0, gauge_last_block: 0, @@ -281,7 +281,7 @@ fn init_gauge() -> (PoolId, BalanceOf) { RuntimeOrigin::signed(ALICE), tokens_proportion.clone(), basic_rewards.clone(), - Some((1000, gauge_basic_rewards.clone())), + Some((7 * 86400 / 12, gauge_basic_rewards.clone())), 0, 0, 0, @@ -293,14 +293,9 @@ fn init_gauge() -> (PoolId, BalanceOf) { let charge_rewards = vec![(KSM, 300000)]; assert_ok!(Farming::charge(RuntimeOrigin::signed(BOB), pid, charge_rewards, false)); assert_ok!(Farming::deposit(RuntimeOrigin::signed(ALICE), pid, tokens, Some((100, 100)))); - assert_ok!(VeMinting::set_config(RuntimeOrigin::signed(ALICE), Some(0), Some(7 * 86400 / 12))); - assert_ok!(VeMinting::notify_rewards( - RuntimeOrigin::signed(ALICE), - CHARLIE, - Some(7 * 86400 / 12), - gauge_basic_rewards.clone() - )); - assert_ok!(VeMinting::create_lock_inner( + assert_ok!(BbBNC::set_config(RuntimeOrigin::signed(ALICE), Some(0), Some(7 * 86400 / 12))); + assert_ok!(BbBNC::notify_reward_amount(pid, &Some(CHARLIE), gauge_basic_rewards.clone())); + assert_ok!(BbBNC::create_lock_inner( &ALICE, 100_000_000_000, System::block_number() + (4 * 365 * 86400 - 7 * 86400) / 12 diff --git a/pallets/fee-share/Cargo.toml b/pallets/fee-share/Cargo.toml index 6c26a6710..48bb407a4 100644 --- a/pallets/fee-share/Cargo.toml +++ b/pallets/fee-share/Cargo.toml @@ -8,37 +8,41 @@ edition = "2021" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -log = { workspace = true } -parity-scale-codec = { workspace = true, features = ["derive"] } -scale-info = { workspace = true, features = ["derive"] } +bifrost-primitives = { workspace = true } +bifrost-slp = { workspace = true } +bifrost-vtoken-minting = { workspace = true } +cumulus-primitives-core = { workspace = true } +frame-benchmarking = { workspace = true, optional = true } frame-support = { workspace = true } frame-system = { workspace = true } -frame-benchmarking = { workspace = true, optional = true } -bifrost-primitives = { workspace = true } -orml-traits = { workspace = true } -sp-std = { workspace = true } hex-literal = { workspace = true } +log = { workspace = true } +orml-traits = { workspace = true } pallet-balances = { workspace = true } +pallet-traits = { workspace = true } +parity-scale-codec = { workspace = true, features = ["derive"] } +scale-info = { workspace = true, features = ["derive"] } sp-arithmetic = { workspace = true } sp-core = { workspace = true } +sp-std = { workspace = true } xcm = { workspace = true } -bifrost-vtoken-minting = { workspace = true } zenlink-protocol = { workspace = true } -bifrost-slp = { workspace = true } -cumulus-primitives-core = { workspace = true } [dev-dependencies] +bifrost-asset-registry = { workspace = true } +bifrost-currencies = { workspace = true } +env_logger = { workspace = true } +orml-oracle = { workspace = true } orml-tokens = { workspace = true } -orml-xtokens = { workspace = true } orml-traits = { workspace = true } -bifrost-currencies = { workspace = true } -xcm-executor = { workspace = true } -xcm-builder = { workspace = true } +orml-xtokens = { workspace = true } +pallet-prices = { workspace = true } pallet-xcm = { workspace = true } -sp-io = { workspace = true } sp-core = { workspace = true } +sp-io = { workspace = true } sp-runtime = { workspace = true } -bifrost-asset-registry = { workspace = true } +xcm-builder = { workspace = true } +xcm-executor = { workspace = true } [features] default = ["std"] @@ -51,14 +55,16 @@ std = [ "bifrost-primitives/std", "orml-xtokens/std", "orml-traits/std", - "bifrost-vtoken-minting/std", + "bifrost-vtoken-minting/std", "zenlink-protocol/std", "bifrost-slp/std", "bifrost-asset-registry/std", + "pallet-traits/std", + "pallet-prices/std", ] runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", - "frame-benchmarking/runtime-benchmarks" + "frame-benchmarking/runtime-benchmarks", ] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/fee-share/src/benchmarking.rs b/pallets/fee-share/src/benchmarking.rs index e7f3a75a2..c07911913 100644 --- a/pallets/fee-share/src/benchmarking.rs +++ b/pallets/fee-share/src/benchmarking.rs @@ -36,8 +36,8 @@ benchmarks! { const KSM: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); let token_type = vec![KSM]; }: _(RawOrigin::Root, - token_type.clone(), - tokens_proportion.clone(), + BoundedVec::try_from(token_type.clone()).unwrap(), + BoundedVec::try_from(tokens_proportion.clone()).unwrap(), true) edit_distribution { @@ -47,14 +47,14 @@ benchmarks! { let token_type = vec![KSM]; assert_ok!(FeeShare::::create_distribution( RawOrigin::Root.into(), - vec![KSM], - tokens_proportion.clone(), + BoundedVec::try_from(vec![KSM]).unwrap(), + BoundedVec::try_from(tokens_proportion.clone()).unwrap(), true, )); }: _(RawOrigin::Root, 0, None, - Some(tokens_proportion.clone()), + Some(BoundedVec::try_from(tokens_proportion.clone()).unwrap()), Some(true)) set_era_length {}: _(RawOrigin::Root,BlockNumberFor::::from(10u32)) execute_distribute { @@ -64,8 +64,8 @@ benchmarks! { let token_type = vec![KSM]; assert_ok!(FeeShare::::create_distribution( RawOrigin::Root.into(), - vec![KSM], - tokens_proportion.clone(), + BoundedVec::try_from(vec![KSM]).unwrap(), + BoundedVec::try_from(tokens_proportion.clone()).unwrap(), true, )); }: _(RawOrigin::Root,0) @@ -76,9 +76,25 @@ benchmarks! { let token_type = vec![KSM]; assert_ok!(FeeShare::::create_distribution( RawOrigin::Root.into(), - vec![KSM], - tokens_proportion.clone(), + BoundedVec::try_from(vec![KSM]).unwrap(), + BoundedVec::try_from(tokens_proportion.clone()).unwrap(), true, )); }: _(RawOrigin::Root,0) + set_usd_config { + let caller: T::AccountId = whitelisted_caller(); + let tokens_proportion = vec![(caller.clone(), Perbill::from_percent(100))]; + const KSM: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); + let token_type = vec![KSM]; + assert_ok!(FeeShare::::create_distribution( + RawOrigin::Root.into(), + BoundedVec::try_from(vec![KSM]).unwrap(), + BoundedVec::try_from(tokens_proportion.clone()).unwrap(), + true, + )); + }: _(RawOrigin::Root, + 0, + 100u128, + 10u32.into(), + caller) } diff --git a/pallets/fee-share/src/lib.rs b/pallets/fee-share/src/lib.rs index 4c5eee0f7..7a5d4f670 100644 --- a/pallets/fee-share/src/lib.rs +++ b/pallets/fee-share/src/lib.rs @@ -30,19 +30,22 @@ mod benchmarking; pub mod weights; -use bifrost_primitives::{CurrencyId, DistributionId}; +use bifrost_primitives::{CurrencyId, DistributionId, Price}; use frame_support::{ pallet_prelude::*, sp_runtime::{ - traits::{AccountIdConversion, CheckedAdd, Saturating}, - ArithmeticError, Perbill, + traits::{ + AccountIdConversion, CheckedAdd, CheckedMul, SaturatedConversion, Saturating, Zero, + }, + ArithmeticError, FixedU128, Perbill, }, PalletId, }; use frame_system::pallet_prelude::*; use orml_traits::MultiCurrency; pub use pallet::*; -use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; +use pallet_traits::PriceFeeder; +use sp_std::cmp::Ordering; pub use weights::WeightInfo; pub type AccountIdOf = ::AccountId; @@ -51,6 +54,33 @@ pub type CurrencyIdOf = <::MultiCurrency as MultiCurrency< ::AccountId, >>::CurrencyId; +type BalanceOf = <::MultiCurrency as MultiCurrency>>::Balance; + +/// Distribution information +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub struct Info { + /// Account id used for distribution + pub fee_share_account_id: AccountIdOf, + /// The token type of the distribution + pub token_type: BoundedVec>, + /// If the distribution is auto + pub if_auto: bool, +} + +/// USD Standard Accumulation Logic Configuration +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub struct DollarStandardInfo { + /// The target value of the USD standard + pub target_value: u128, + /// The cumulative value of the USD standard + pub cumulative: u128, + /// The target account id of the USD standard + pub target_account_id: AccountIdOf, + /// Target block to perform accumulation clear operation + pub target_block: BlockNumberFor, + /// Cumulative clearing operation interval + pub interval: BlockNumberFor, +} #[frame_support::pallet] pub mod pallet { use super::*; @@ -71,73 +101,128 @@ pub mod pallet { #[pallet::constant] type FeeSharePalletId: Get; + + /// The oracle price feeder + type PriceFeeder: PriceFeeder; } #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { + /// A successful call of the `CreateDistribution` extrinsic will create this event. Created { + /// Distribution ID + distribution_id: DistributionId, + /// Distribution information info: Info>, }, + /// A successful call of the `EditDistribution` extrinsic will create this event. Edited { + /// Distribution ID + distribution_id: DistributionId, + /// Distribution information info: Info>, }, + /// A successful call of the `SetEraLength` extrinsic will create this event. EraLengthSet { + /// The interval between distribution executions era_length: BlockNumberFor, + /// The block number of the next era next_era: BlockNumberFor, }, + /// A successful call of the `ExecuteDistribute` extrinsic will create this event. Executed { + /// Distribution ID distribution_id: DistributionId, }, + /// A successful call of the `DeleteDistribution` extrinsic will create this event. Deleted { + /// Distribution ID distribution_id: DistributionId, }, + /// A failed call of the `ExecuteDistribute` extrinsic will create this event. ExecuteFailed { + /// Distribution ID distribution_id: DistributionId, + /// Distribution information info: Info>, + /// The block number of the next era next_era: BlockNumberFor, }, + /// A successful call of the `SetUSDConfig` extrinsic will create this event. + USDConfigSet { + /// Distribution ID + distribution_id: DistributionId, + /// USD standard information + info: DollarStandardInfo, AccountIdOf>, + }, } #[pallet::error] pub enum Error { - NotEnoughBalance, + /// Not support proportion NotSupportProportion, - CalculationOverflow, + /// Existential deposit ExistentialDeposit, + /// Distribution not exist DistributionNotExist, + /// Price oracle not ready + PriceOracleNotReady, + /// Price is zero + PriceIsZero, + /// Interval is zero + IntervalIsZero, + /// Value is zero + ValueIsZero, + /// Tokens proportions not cleared + TokensProportionsNotCleared, } + /// The distribution information #[pallet::storage] - #[pallet::getter(fn distribution_infos)] pub type DistributionInfos = StorageMap<_, Twox64Concat, DistributionId, Info>>; - #[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo)] - pub struct Info { - pub receiving_address: AccountIdOf, - pub token_type: Vec, - pub tokens_proportion: BTreeMap, - pub if_auto: bool, - } + /// The proportion of the token distribution + #[pallet::storage] + pub type TokensProportions = + StorageDoubleMap<_, Twox64Concat, DistributionId, Twox64Concat, AccountIdOf, Perbill>; + /// USD Standard Accumulation Logic Configuration + #[pallet::storage] + pub type DollarStandardInfos = StorageMap< + _, + Twox64Concat, + DistributionId, + DollarStandardInfo, AccountIdOf>, + >; + + /// The next distribution ID #[pallet::storage] - #[pallet::getter(fn distribution_next_id)] pub type DistributionNextId = StorageValue<_, DistributionId, ValueQuery>; + /// The era length and the next era #[pallet::storage] - #[pallet::getter(fn auto_era)] pub type AutoEra = StorageValue<_, (BlockNumberFor, BlockNumberFor), ValueQuery>; #[pallet::hooks] impl Hooks> for Pallet { fn on_idle(bn: BlockNumberFor, _remaining_weight: Weight) -> Weight { - let (era_length, next_era) = Self::auto_era(); + DollarStandardInfos::::iter().for_each(|(distribution_id, mut info)| { + if bn.eq(&info.target_block) { + info.target_block = info.target_block.saturating_add(info.interval); + info.cumulative = Zero::zero(); + DollarStandardInfos::::insert(distribution_id, info); + } + }); + let (era_length, next_era) = AutoEra::::get(); if bn.eq(&next_era) { - for (distribution_id, info) in DistributionInfos::::iter() { + DistributionInfos::::iter().for_each(|(distribution_id, info)| { if info.if_auto { - if let Some(e) = Self::execute_distribute_inner(&info).err() { + if let Some(e) = + Self::execute_distribute_inner(distribution_id, &info).err() + { Self::deposit_event(Event::ExecuteFailed { distribution_id, info, @@ -145,13 +230,15 @@ pub mod pallet { }); log::error!( - target: "runtime::fee-share", + target: "fee-share::execute_distribute", "Received invalid justification for {:?}", e, ); + } else { + Self::deposit_event(Event::Executed { distribution_id }); } } - } + }); let next_era = next_era.saturating_add(era_length); AutoEra::::put((era_length, next_era)); } @@ -161,69 +248,73 @@ pub mod pallet { #[pallet::call] impl Pallet { + /// Create a distribution + /// + /// - `token_type`: The token types involved in this distribution + /// - `tokens_proportion`: The proportion of the token distribution + /// - `if_auto`: Whether the distribution is automatic #[pallet::call_index(0)] #[pallet::weight(T::WeightInfo::create_distribution())] pub fn create_distribution( origin: OriginFor, - token_type: Vec, - tokens_proportion: Vec<(AccountIdOf, Perbill)>, + token_type: BoundedVec>, + tokens_proportion: BoundedVec<(AccountIdOf, Perbill), ConstU32<256>>, if_auto: bool, ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; + let distribution_id = DistributionNextId::::get(); let mut total_proportion = Perbill::from_percent(0); - let tokens_proportion_map: BTreeMap, Perbill> = tokens_proportion - .into_iter() - .map(|(k, v)| { - total_proportion = total_proportion.saturating_add(v); - (k, v) - }) - .collect(); + tokens_proportion.into_iter().for_each(|(k, v)| { + total_proportion = total_proportion.saturating_add(v); + TokensProportions::::insert(distribution_id, k, v); + }); ensure!(total_proportion.is_one(), Error::::NotSupportProportion); - let distribution_id = Self::distribution_next_id(); - let receiving_address = + let fee_share_account_id = T::FeeSharePalletId::get().into_sub_account_truncating(distribution_id); - let info = Info { - receiving_address, - token_type, - tokens_proportion: tokens_proportion_map, - if_auto, - }; + let info = Info { fee_share_account_id, token_type, if_auto }; DistributionInfos::::insert(distribution_id, info.clone()); DistributionNextId::::mutate(|id| -> DispatchResult { *id = id.checked_add(1).ok_or(ArithmeticError::Overflow)?; Ok(()) })?; - Self::deposit_event(Event::Created { info }); + Self::deposit_event(Event::Created { distribution_id, info }); Ok(()) } + /// Edit the distribution + /// + /// - `distribution_id`: Distribution ID + /// - `token_type`: The token types involved in this distribution + /// - `tokens_proportion`: The proportion of the token distribution + /// - `if_auto`: Whether the distribution is automatic #[pallet::call_index(1)] #[pallet::weight(T::WeightInfo::edit_distribution())] pub fn edit_distribution( origin: OriginFor, distribution_id: DistributionId, - token_type: Option>, - tokens_proportion: Option, Perbill)>>, + token_type: Option>>, + tokens_proportion: Option, Perbill), ConstU32<256>>>, if_auto: Option, ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - let mut info = Self::distribution_infos(distribution_id) + let mut info = DistributionInfos::::get(distribution_id) .ok_or(Error::::DistributionNotExist)?; if let Some(tokens_proportion) = tokens_proportion { + // Clear the original proportion + let res = + TokensProportions::::clear_prefix(distribution_id, u32::max_value(), None); + ensure!(res.maybe_cursor.is_none(), Error::::TokensProportionsNotCleared); + let mut total_proportion = Perbill::from_percent(0); - let tokens_proportion_map: BTreeMap, Perbill> = tokens_proportion - .into_iter() - .map(|(k, v)| { - total_proportion = total_proportion.saturating_add(v); - (k, v) - }) - .collect(); + tokens_proportion.into_iter().for_each(|(k, v)| { + total_proportion = total_proportion.saturating_add(v); + TokensProportions::::insert(distribution_id, k, v); + }); ensure!(total_proportion.is_one(), Error::::NotSupportProportion); - info.tokens_proportion = tokens_proportion_map; } if let Some(token_type) = token_type { @@ -235,10 +326,13 @@ pub mod pallet { } DistributionInfos::::insert(distribution_id, info.clone()); - Self::deposit_event(Event::Edited { info }); + Self::deposit_event(Event::Edited { distribution_id, info }); Ok(()) } + /// Set the era length + /// + /// - `era_length`: The interval between distribution executions #[pallet::call_index(2)] #[pallet::weight(T::WeightInfo::set_era_length())] pub fn set_era_length( @@ -256,6 +350,9 @@ pub mod pallet { Ok(()) } + /// Execute the distribution + /// + /// - `distribution_id`: Distribution ID #[pallet::call_index(3)] #[pallet::weight(T::WeightInfo::execute_distribute())] pub fn execute_distribute( @@ -264,14 +361,17 @@ pub mod pallet { ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - if let Some(info) = Self::distribution_infos(distribution_id) { - Self::execute_distribute_inner(&info)?; - } + let info = DistributionInfos::::get(distribution_id) + .ok_or(Error::::DistributionNotExist)?; + Self::execute_distribute_inner(distribution_id, &info)?; Self::deposit_event(Event::Executed { distribution_id }); Ok(()) } + /// Delete the distribution + /// + /// - `distribution_id`: Distribution ID #[pallet::call_index(4)] #[pallet::weight(T::WeightInfo::delete_distribution())] pub fn delete_distribution( @@ -280,23 +380,93 @@ pub mod pallet { ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; - if let Some(info) = Self::distribution_infos(distribution_id) { - Self::execute_distribute_inner(&info)?; - DistributionInfos::::remove(distribution_id); - } + let info = DistributionInfos::::get(distribution_id) + .ok_or(Error::::DistributionNotExist)?; + Self::execute_distribute_inner(distribution_id, &info)?; + DistributionInfos::::remove(distribution_id); Self::deposit_event(Event::Deleted { distribution_id }); Ok(()) } + + /// USD Standard Accumulation Logic Configuration, can be overridden by the governance + /// + /// - `distribution_id`: Distribution ID + /// - `target_value`: Target's USD based value + /// - `interval`: The interval of the cumulative clearing operation + /// - `target_account_id`: When the cumulative dollar value falls below the target_value, + /// the funds will be transferred to the target_account_id + #[pallet::call_index(5)] + #[pallet::weight(T::WeightInfo::set_usd_config())] + pub fn set_usd_config( + origin: OriginFor, + distribution_id: DistributionId, + target_value: u128, + interval: BlockNumberFor, + target_account_id: AccountIdOf, + ) -> DispatchResult { + T::ControlOrigin::ensure_origin(origin)?; + + ensure!( + DistributionInfos::::contains_key(distribution_id), + Error::::DistributionNotExist + ); + ensure!(interval > Zero::zero(), Error::::IntervalIsZero); + ensure!(target_value > 0, Error::::ValueIsZero); + + let now = frame_system::Pallet::::block_number(); + let info = DollarStandardInfo { + target_value, + cumulative: Zero::zero(), + target_account_id, + target_block: now.saturating_add(interval), + interval, + }; + DollarStandardInfos::::insert(distribution_id, info.clone()); + + Self::deposit_event(Event::USDConfigSet { distribution_id, info }); + Ok(()) + } } impl Pallet { - fn execute_distribute_inner(infos: &Info>) -> DispatchResult { + fn execute_distribute_inner( + distribution_id: DistributionId, + infos: &Info>, + ) -> DispatchResult { + let mut usd_value: FixedU128 = Zero::zero(); + // Calculate the total value based on the US dollar standard + infos.token_type.iter().try_for_each(|¤cy_id| -> DispatchResult { + let amount = + T::MultiCurrency::free_balance(currency_id, &infos.fee_share_account_id); + let value = Self::get_asset_value(currency_id, amount)?; + usd_value = usd_value.checked_add(&value).ok_or(ArithmeticError::Overflow)?; + Ok(()) + })?; + if let Some(mut usd_infos) = DollarStandardInfos::::get(distribution_id) { + match usd_infos.cumulative.cmp(&usd_infos.target_value) { + // If the cumulative value is greater than or equal to the target value, the + // distribution is triggered + Ordering::Equal | Ordering::Greater => (), + // If the cumulative value is less than the target value, the cumulative value + // is added, and the distribution is not triggered + Ordering::Less => { + usd_infos.cumulative = usd_infos + .cumulative + .checked_add(usd_value.into_inner()) + .ok_or(ArithmeticError::Overflow)?; + DollarStandardInfos::::insert(distribution_id, &usd_infos); + return Self::transfer_all(infos, usd_infos.target_account_id); + }, + } + } + infos.token_type.iter().try_for_each(|¤cy_id| -> DispatchResult { let ed = T::MultiCurrency::minimum_balance(currency_id); - let amount = T::MultiCurrency::free_balance(currency_id, &infos.receiving_address); - infos.tokens_proportion.iter().try_for_each( - |(account_to_send, &proportion)| -> DispatchResult { + let amount = + T::MultiCurrency::free_balance(currency_id, &infos.fee_share_account_id); + TokensProportions::::iter_prefix(distribution_id).try_for_each( + |(account_to_send, proportion)| -> DispatchResult { let withdraw_amount = proportion.mul_floor(amount); if withdraw_amount < ed { let receiver_balance = @@ -306,12 +476,14 @@ pub mod pallet { .checked_add(&withdraw_amount) .ok_or(ArithmeticError::Overflow)?; if receiver_balance_after < ed { - Err(Error::::ExistentialDeposit)?; + // If the balance of the receiving account is less than the + // existential deposit, the balance is not transferred + return Ok(()); } } T::MultiCurrency::transfer( currency_id, - &infos.receiving_address, + &infos.fee_share_account_id, &account_to_send, withdraw_amount, ) @@ -319,5 +491,45 @@ pub mod pallet { ) }) } + + pub fn get_price(currency_id: CurrencyIdOf) -> Result { + let (price, _) = + T::PriceFeeder::get_price(¤cy_id).ok_or(Error::::PriceOracleNotReady)?; + log::trace!( + target: "fee-share::get_price", "price: {:?}", price.into_inner() + ); + if price.is_zero() { + return Err(Error::::PriceIsZero.into()); + } + + Ok(price) + } + + pub fn get_asset_value( + currency_id: CurrencyIdOf, + amount: BalanceOf, + ) -> Result { + let value = Self::get_price(currency_id)? + .checked_mul(&FixedU128::from_inner(amount.saturated_into())) + .ok_or(ArithmeticError::Overflow)?; + + Ok(value) + } + + fn transfer_all( + infos: &Info>, + target_account_id: AccountIdOf, + ) -> DispatchResult { + infos.token_type.iter().try_for_each(|¤cy_id| -> DispatchResult { + let amount = + T::MultiCurrency::free_balance(currency_id, &infos.fee_share_account_id); + T::MultiCurrency::transfer( + currency_id, + &infos.fee_share_account_id, + &target_account_id, + amount, + ) + }) + } } } diff --git a/pallets/fee-share/src/mock.rs b/pallets/fee-share/src/mock.rs index ece282274..a885cf11b 100644 --- a/pallets/fee-share/src/mock.rs +++ b/pallets/fee-share/src/mock.rs @@ -20,28 +20,39 @@ #![cfg(test)] #![allow(non_upper_case_globals)] +pub use super::*; use bifrost_asset_registry::AssetIdMaps; -pub use bifrost_primitives::{currency::*, CurrencyId, SlpxOperator, TokenSymbol}; +pub use bifrost_primitives::{currency::*, CurrencyId, Moment, SlpxOperator, TokenSymbol}; +use bifrost_primitives::{MoonbeamChainId, PriceDetail}; use bifrost_slp::{QueryId, QueryResponseManager}; pub use cumulus_primitives_core::ParaId; use frame_support::{ derive_impl, ord_parameter_types, pallet_prelude::Get, parameter_types, - sp_runtime::{DispatchError, DispatchResult}, + sp_runtime::{DispatchError, DispatchResult, FixedPointNumber}, traits::{Everything, Nothing}, PalletId, }; use frame_system::{EnsureRoot, EnsureSignedBy}; use hex_literal::hex; -use orml_traits::{location::RelativeReserveProvider, parameter_type_with_key, MultiCurrency}; +use orml_traits::{ + location::RelativeReserveProvider, parameter_type_with_key, DataFeeder, DataProvider, + DataProviderExtended, MultiCurrency, +}; +use pallet_traits::PriceFeeder; use sp_core::ConstU32; use sp_runtime::{ traits::{AccountIdConversion, IdentityLookup, UniqueSaturatedInto}, AccountId32, BuildStorage, SaturatedConversion, }; use sp_std::marker::PhantomData; +use std::{ + cell::RefCell, + collections::HashMap, + hash::{Hash, Hasher}, +}; use xcm::{prelude::*, v3::Weight}; use xcm_builder::{FixedWeightBounds, FrameTransactionalProcessor}; use xcm_executor::XcmExecutor; @@ -74,6 +85,7 @@ frame_support::construct_runtime!( ZenlinkProtocol: zenlink_protocol, AssetRegistry: bifrost_asset_registry, PolkadotXcm: pallet_xcm, + Prices: pallet_prices::{Pallet, Storage, Call, Event}, } ); @@ -171,6 +183,101 @@ impl bifrost_fee_share::Config for Runtime { type ControlOrigin = EnsureSignedBy; type WeightInfo = (); type FeeSharePalletId = FeeSharePalletId; + type PriceFeeder = MockPriceFeeder; +} + +impl pallet_prices::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Source = MockDataProvider; + type FeederOrigin = EnsureRoot; + type UpdateOrigin = EnsureRoot; + type RelayCurrency = RelayCurrencyId; + type Assets = Currencies; + type CurrencyIdConvert = AssetIdMaps; + type WeightInfo = (); +} + +// pallet-price is using for benchmark compilation +pub type TimeStampedPrice = orml_oracle::TimestampedValue; +pub struct MockDataProvider; +impl DataProvider for MockDataProvider { + fn get(_asset_id: &CurrencyId) -> Option { + Some(TimeStampedPrice { value: Price::saturating_from_integer(100), timestamp: 0 }) + } +} + +impl DataProviderExtended for MockDataProvider { + fn get_no_op(_key: &CurrencyId) -> Option { + None + } + + fn get_all_values() -> Vec<(CurrencyId, Option)> { + vec![] + } +} + +impl DataFeeder for MockDataProvider { + fn feed_value( + _: Option, + _: CurrencyId, + _: TimeStampedPrice, + ) -> sp_runtime::DispatchResult { + Ok(()) + } +} +pub struct MockPriceFeeder; +#[derive(Encode, Decode, Clone, Copy, RuntimeDebug)] +pub struct CurrencyIdWrap(CurrencyId); + +impl Hash for CurrencyIdWrap { + fn hash(&self, state: &mut H) { + state.write_u8(1); + } +} + +impl PartialEq for CurrencyIdWrap { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +impl Eq for CurrencyIdWrap {} + +impl MockPriceFeeder { + thread_local! { + pub static PRICES: RefCell>> = { + RefCell::new( + vec![BNC, DOT, KSM, DOT_U, VKSM, VDOT, PHA] + .iter() + .map(|&x| (CurrencyIdWrap(x), Some((Price::saturating_from_integer(1), 1)))) + .collect() + ) + }; + } + + pub fn set_price(asset_id: CurrencyId, price: Price) { + Self::PRICES.with(|prices| { + prices.borrow_mut().insert(CurrencyIdWrap(asset_id), Some((price, 1u64))); + }); + } + + pub fn reset() { + Self::PRICES.with(|prices| { + for (_, val) in prices.borrow_mut().iter_mut() { + *val = Some((Price::saturating_from_integer(1), 1u64)); + } + }) + } +} + +impl PriceFeeder for MockPriceFeeder { + fn get_price(asset_id: &CurrencyId) -> Option { + Self::PRICES.with(|prices| *prices.borrow().get(&CurrencyIdWrap(*asset_id)).unwrap()) + } + + fn get_normal_price(_asset_id: &CurrencyId) -> Option { + todo!() + } } pub struct ParaInfo; @@ -298,15 +405,11 @@ impl bifrost_vtoken_minting::Config for Runtime { type WeightInfo = (); type OnRedeemSuccess = (); type XcmTransfer = XTokens; - type AstarParachainId = ConstU32<2007>; - type MoonbeamParachainId = ConstU32<2023>; - type HydradxParachainId = ConstU32<2034>; - type MantaParachainId = ConstU32<2104>; - type InterlayParachainId = ConstU32<2032>; + type MoonbeamChainId = MoonbeamChainId; type ChannelCommission = (); type MaxLockRecords = ConstU32<100>; type IncentivePoolAccount = IncentivePoolAccount; - type VeMinting = (); + type BbBNC = (); type AssetIdMaps = AssetIdMaps; } @@ -489,6 +592,7 @@ impl ExtBuilder { } pub fn build(self) -> sp_io::TestExternalities { + env_logger::try_init().unwrap_or(()); let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { diff --git a/pallets/fee-share/src/tests.rs b/pallets/fee-share/src/tests.rs index 18575d021..677e88227 100644 --- a/pallets/fee-share/src/tests.rs +++ b/pallets/fee-share/src/tests.rs @@ -21,7 +21,7 @@ #![cfg(test)] use crate::{mock::*, *}; -use frame_support::assert_ok; +use frame_support::{assert_err, assert_ok}; use sp_arithmetic::per_things::Perbill; #[test] @@ -31,8 +31,8 @@ fn on_idle() { assert_ok!(FeeShare::create_distribution( RuntimeOrigin::signed(ALICE), - vec![KSM], - tokens_proportion, + BoundedVec::try_from(vec![KSM]).unwrap(), + BoundedVec::try_from(tokens_proportion).unwrap(), true, )); let keeper: AccountId = @@ -53,15 +53,15 @@ fn edit_delete_distribution() { assert_ok!(FeeShare::create_distribution( RuntimeOrigin::signed(ALICE), - vec![KSM], - tokens_proportion.clone(), + BoundedVec::try_from(vec![KSM]).unwrap(), + BoundedVec::try_from(tokens_proportion.clone()).unwrap(), true, )); assert_ok!(FeeShare::edit_distribution( RuntimeOrigin::signed(ALICE), 0, None, // Some(vec![KSM]), - Some(tokens_proportion), + Some(BoundedVec::try_from(tokens_proportion).unwrap()), Some(false), )); let keeper: AccountId = @@ -75,10 +75,99 @@ fn edit_delete_distribution() { assert_ok!(FeeShare::execute_distribute(RuntimeOrigin::signed(ALICE), 0)); assert_eq!(Tokens::free_balance(KSM, &keeper), 0); - if let Some(infos) = FeeShare::distribution_infos(0) { + if let Some(infos) = DistributionInfos::::get(0) { assert_eq!(infos.token_type, vec![KSM]) } assert_ok!(FeeShare::delete_distribution(RuntimeOrigin::signed(ALICE), 0)); - assert_eq!(FeeShare::distribution_infos(0), None); + assert_eq!(DistributionInfos::::get(0), None); + }); +} + +#[test] +fn set_usd_config_should_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let tokens_proportion = vec![(ALICE, Perbill::from_percent(100))]; + + assert_ok!(FeeShare::create_distribution( + RuntimeOrigin::signed(ALICE), + BoundedVec::try_from(vec![KSM]).unwrap(), + BoundedVec::try_from(tokens_proportion.clone()).unwrap(), + true, + )); + + let distribution_id = 0; + let target_value = 100; + let interval = 10; + assert_ok!(FeeShare::set_usd_config( + RuntimeOrigin::signed(ALICE), + distribution_id, + target_value, + interval, + BOB, + )); + + let keeper: AccountId = + ::FeeSharePalletId::get().into_sub_account_truncating(0); + + assert_ok!(FeeShare::set_era_length(RuntimeOrigin::signed(ALICE), 1)); + assert_eq!(Tokens::free_balance(KSM, &BOB), 100); + FeeShare::on_idle(>::block_number() + 1, Weight::zero()); + assert_ok!(>::transfer(KSM, &ALICE, &keeper, 100,)); + assert_eq!(Tokens::free_balance(KSM, &BOB), 10100); + assert_eq!(DollarStandardInfos::::get(0).unwrap().cumulative, 10000); + FeeShare::on_idle(>::block_number() + 2, Weight::zero()); + assert_eq!(Tokens::free_balance(KSM, &keeper), 0); + assert_eq!(Tokens::free_balance(KSM, &BOB), 10100); + assert_eq!(DollarStandardInfos::::get(0).unwrap().cumulative, 10000); + assert_ok!(>::transfer(KSM, &ALICE, &keeper, 100,)); + FeeShare::on_idle(>::block_number() + 10, Weight::zero()); + assert_eq!(DollarStandardInfos::::get(0).unwrap().cumulative, 0); + }); +} + +#[test] +fn set_usd_config_should_not_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let tokens_proportion = vec![(ALICE, Perbill::from_percent(100))]; + let distribution_id = 0; + let target_value = 100; + let interval = 10; + + assert_err!( + FeeShare::set_usd_config( + RuntimeOrigin::signed(ALICE), + distribution_id, + target_value, + interval, + BOB, + ), + Error::::DistributionNotExist + ); + assert_ok!(FeeShare::create_distribution( + RuntimeOrigin::signed(ALICE), + BoundedVec::try_from(vec![KSM]).unwrap(), + BoundedVec::try_from(tokens_proportion.clone()).unwrap(), + true, + )); + assert_err!( + FeeShare::set_usd_config( + RuntimeOrigin::signed(ALICE), + distribution_id, + target_value, + 0, + BOB, + ), + Error::::IntervalIsZero + ); + assert_err!( + FeeShare::set_usd_config( + RuntimeOrigin::signed(ALICE), + distribution_id, + 0, + interval, + BOB, + ), + Error::::ValueIsZero + ); }); } diff --git a/pallets/fee-share/src/weights.rs b/pallets/fee-share/src/weights.rs index 1d4a4a9ed..6e081da5f 100644 --- a/pallets/fee-share/src/weights.rs +++ b/pallets/fee-share/src/weights.rs @@ -59,6 +59,7 @@ pub trait WeightInfo { fn set_era_length() -> Weight; fn execute_distribute() -> Weight; fn delete_distribution() -> Weight; + fn set_usd_config() -> Weight; } // For backwards compatibility and tests @@ -136,4 +137,18 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } + /// Storage: `FeeShare::DistributionInfos` (r:1 w:0) + /// Proof: `FeeShare::DistributionInfos` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `FeeShare::DollarStandardInfos` (r:0 w:1) + /// Proof: `FeeShare::DollarStandardInfos` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn set_usd_config() -> Weight { + // Proof Size summary in bytes: + // Measured: `94` + // Estimated: `3559` + // Minimum execution time: 9_077_000 picoseconds. + Weight::from_parts(9_408_000, 0) + .saturating_add(Weight::from_parts(0, 3559)) + .saturating_add(RocksDbWeight::get().reads(1)) + .saturating_add(RocksDbWeight::get().writes(1)) + } } diff --git a/pallets/flexible-fee/Cargo.toml b/pallets/flexible-fee/Cargo.toml index 6e4285a9e..c90cfbe81 100644 --- a/pallets/flexible-fee/Cargo.toml +++ b/pallets/flexible-fee/Cargo.toml @@ -24,6 +24,7 @@ bifrost-asset-registry = { workspace = true } polkadot-parachain-primitives = { workspace = true } log = { workspace = true } xcm = { workspace = true } +sp-core = { workspace = true } [dev-dependencies] orml-tokens = { workspace = true } @@ -55,6 +56,7 @@ std = [ "cumulus-primitives-core/std", "bifrost-asset-registry/std", "pallet-xcm/std", + "sp-core/std", ] runtime-benchmarks = [ diff --git a/pallets/flexible-fee/src/lib.rs b/pallets/flexible-fee/src/lib.rs index 6473b6241..a66a3cfb9 100644 --- a/pallets/flexible-fee/src/lib.rs +++ b/pallets/flexible-fee/src/lib.rs @@ -20,9 +20,10 @@ pub use crate::pallet::*; use bifrost_primitives::{ - currency::WETH, + currency::{VGLMR, VMANTA, WETH}, traits::{FeeGetter, XcmDestWeightAndFeeHandler}, - AccountFeeCurrency, CurrencyId, ExtraFeeName, TryConvertFrom, XcmOperationType, BNC, + AccountFeeCurrency, BalanceCmp, CurrencyId, ExtraFeeName, TryConvertFrom, XcmOperationType, + BNC, DOT, GLMR, MANTA, VBNC, VDOT, }; use bifrost_xcm_interface::{polkadot::RelaychainCall, traits::parachains, PolkadotXcmCall}; use core::convert::Into; @@ -30,6 +31,8 @@ use cumulus_primitives_core::ParaId; use frame_support::{ pallet_prelude::*, traits::{ + fungibles::Inspect, + tokens::{Fortitude, Preservation}, Currency, ExistenceRequirement, Get, Imbalance, OnUnbalanced, ReservableCurrency, WithdrawReasons, }, @@ -42,12 +45,13 @@ use orml_traits::MultiCurrency; use pallet_transaction_payment::OnChargeTransaction; use polkadot_parachain_primitives::primitives::Sibling; use sp_arithmetic::traits::{CheckedAdd, SaturatedConversion, UniqueSaturatedInto}; +use sp_core::U256; use sp_runtime::{ traits::{AccountIdConversion, DispatchInfoOf, PostDispatchInfoOf, Saturating, Zero}, transaction_validity::TransactionValidityError, BoundedVec, }; -use sp_std::{boxed::Box, vec, vec::Vec}; +use sp_std::{boxed::Box, cmp::Ordering, vec, vec::Vec}; pub use weights::WeightInfo; use xcm::{prelude::Unlimited, v4::prelude::*}; use zenlink_protocol::{AssetBalance, AssetId, ExportZenlink}; @@ -79,6 +83,8 @@ pub enum TargetChain { #[frame_support::pallet] pub mod pallet { use super::*; + use bifrost_primitives::Balance; + use frame_support::traits::fungibles::Inspect; #[pallet::config] pub trait Config: frame_system::Config + pallet_transaction_payment::Config { @@ -87,11 +93,8 @@ pub mod pallet { /// Weight information for the extrinsics in this module. type WeightInfo: WeightInfo; /// Handler for both NativeCurrency and MultiCurrency - type MultiCurrency: MultiCurrency< - Self::AccountId, - CurrencyId = CurrencyId, - Balance = PalletBalanceOf, - >; + type MultiCurrency: MultiCurrency> + + Inspect; /// The currency type in which fees will be paid. type Currency: Currency + ReservableCurrency; /// Handler for the unbalanced decrease @@ -184,14 +187,12 @@ pub mod pallet { /// Universal fee currency order list for all users #[pallet::storage] - #[pallet::getter(fn get_universal_fee_currency_order_list)] pub type UniversalFeeCurrencyOrderList = StorageValue<_, BoundedVec, T::MaxFeeCurrencyOrderListLen>, ValueQuery>; /// User default fee currency, if set, will be used as the first fee currency, and then use the /// universal fee currency order list #[pallet::storage] - #[pallet::getter(fn get_user_default_fee_currency)] pub type UserDefaultFeeCurrency = StorageMap<_, Twox64Concat, T::AccountId, CurrencyIdOf, OptionQuery>; @@ -210,6 +211,9 @@ pub mod pallet { DexFailedToGetAmountInByPath, UnweighableMessage, XcmExecutionFailed, + /// Maximum number of currencies reached. + MaxCurrenciesReached, + CurrencyNotSupport, } #[pallet::call] @@ -650,7 +654,124 @@ where /// Provides account's fee payment asset or default fee asset ( Native asset ) impl AccountFeeCurrency for Pallet { - fn get(who: &T::AccountId) -> CurrencyId { - Pallet::::get_user_default_fee_currency(who).unwrap_or_else(|| WETH) + type Error = Error; + + /// Determines the appropriate currency to be used for paying transaction fees based on a + /// prioritized order: + /// 1. User's default fee currency (`UserDefaultFeeCurrency`) + /// 2. WETH + /// 3. Currencies in the `UniversalFeeCurrencyOrderList` + /// + /// The method first checks if the balance of the highest-priority currency is sufficient to + /// cover the fee.If the balance is insufficient, it iterates through the list of currencies in + /// priority order.If no currency has a sufficient balance, it returns the currency with the + /// highest balance. + fn get_fee_currency(account: &T::AccountId, fee: U256) -> Result> { + let fee: u128 = fee.unique_saturated_into(); + let priority_currency = UserDefaultFeeCurrency::::get(account); + let mut currency_list = UniversalFeeCurrencyOrderList::::get(); + + let first_item_index = 0; + currency_list + .try_insert(first_item_index, WETH) + .map_err(|_| Error::::MaxCurrenciesReached)?; + + // When all currency balances are insufficient, return the one with the highest balance + let mut hopeless_currency = WETH; + + if let Some(currency) = priority_currency { + currency_list + .try_insert(first_item_index, currency) + .map_err(|_| Error::::MaxCurrenciesReached)?; + hopeless_currency = currency; + } + + for maybe_currency in currency_list.iter() { + let comp_res = Self::cmp_with_precision(account, maybe_currency, fee, 18)?; + + match comp_res { + Ordering::Less => { + // Get the currency with the highest balance + let hopeless_currency_balance = T::MultiCurrency::reducible_balance( + hopeless_currency, + account, + Preservation::Preserve, + Fortitude::Polite, + ); + let maybe_currency_balance = T::MultiCurrency::reducible_balance( + *maybe_currency, + account, + Preservation::Preserve, + Fortitude::Polite, + ); + hopeless_currency = match hopeless_currency_balance.cmp(&maybe_currency_balance) + { + Ordering::Less => *maybe_currency, + _ => hopeless_currency, + }; + continue; + }, + Ordering::Equal => return Ok(*maybe_currency), + Ordering::Greater => return Ok(*maybe_currency), + }; + } + + return Ok(hopeless_currency); + } +} + +impl BalanceCmp for Pallet { + type Error = Error; + + /// Compares the balance of a specific `currency` for a given `account` against an `amount` + /// while considering different currency precisions. + /// + /// # Parameters + /// - `account`: The account ID whose balance will be checked. + /// - `currency`: The currency ID to be compared. + /// - `amount`: The amount to compare against the account's balance, with the precision + /// specified by `amount_precision`. + /// - `amount_precision`: The precision of the `amount` specified. If greater than 18, the + /// precision of the `currency` will be adjusted accordingly. + /// + /// # Returns + /// - `Ok(std::cmp::Ordering)`: Returns the ordering result (`Less`, `Equal`, `Greater`) based + /// on the comparison between the adjusted balance and the adjusted amount. + /// - `Err(Error)`: Returns an error if the currency is not supported. + fn cmp_with_precision( + account: &T::AccountId, + currency: &CurrencyId, + amount: u128, + amount_precision: u32, + ) -> Result> { + // Get the reducible balance for the specified account and currency. + let mut balance = T::MultiCurrency::reducible_balance( + *currency, + account, + Preservation::Preserve, + Fortitude::Polite, + ); + + // Define the standard precision as 18 decimal places. + let standard_precision: u32 = amount_precision.max(18); + + // Adjust the amount to the standard precision. + let precision_offset = standard_precision.saturating_sub(amount_precision); + let adjust_precision = 10u128.pow(precision_offset); + let amount = amount.saturating_mul(adjust_precision); + + // Adjust the balance based on currency type. + let balance_precision_offset = match *currency { + WETH | GLMR | VGLMR | MANTA | VMANTA => standard_precision.saturating_sub(18), + BNC | VBNC => standard_precision.saturating_sub(12), + DOT | VDOT => standard_precision.saturating_sub(10), + _ => return Err(Error::::CurrencyNotSupport), + }; + + // Apply precision adjustment to balance. + balance = balance.saturating_mul(10u128.pow(balance_precision_offset)); + + // Compare the adjusted balance with the input amount. + Ok(balance.cmp(&amount)) } } diff --git a/pallets/flexible-fee/src/mock.rs b/pallets/flexible-fee/src/mock.rs index 6ed57ad38..e263a82a3 100644 --- a/pallets/flexible-fee/src/mock.rs +++ b/pallets/flexible-fee/src/mock.rs @@ -523,6 +523,27 @@ impl bifrost_vtoken_voting::Config for Test { type WeightInfo = (); } +impl AccountFeeCurrency for Test { + type Error = Error; + + fn get_fee_currency(account: &AccountId32, fee: U256) -> Result { + Pallet::::get_fee_currency(account, fee) + } +} + +impl BalanceCmp for Test { + type Error = Error; + + fn cmp_with_precision( + account: &AccountId, + currency: &CurrencyId, + amount: u128, + amount_precision: u32, + ) -> Result { + Pallet::::cmp_with_precision(account, currency, amount, amount_precision) + } +} + pub struct DerivativeAccount; impl DerivativeAccountHandler for DerivativeAccount { fn check_derivative_index_exists( diff --git a/pallets/flexible-fee/src/tests.rs b/pallets/flexible-fee/src/tests.rs index 8ad017fbc..b15c3eef6 100644 --- a/pallets/flexible-fee/src/tests.rs +++ b/pallets/flexible-fee/src/tests.rs @@ -20,12 +20,8 @@ #![cfg(test)] -use bifrost_primitives::TryConvertFrom; -// use balances::Call as BalancesCall; -use crate::{ - mock::*, BlockNumberFor, BoundedVec, Config, DispatchError::BadOrigin, UserDefaultFeeCurrency, -}; -use bifrost_primitives::{CurrencyId, TokenSymbol}; +use std::cmp::Ordering::{Greater, Less}; + use frame_support::{ assert_noop, assert_ok, dispatch::{GetDispatchInfo, Pays, PostDispatchInfo}, @@ -37,16 +33,27 @@ use pallet_transaction_payment::OnChargeTransaction; use sp_runtime::{testing::TestXt, AccountId32}; use zenlink_protocol::AssetId; +use bifrost_primitives::{ + currency::WETH, AccountFeeCurrency, BalanceCmp, CurrencyId, TokenSymbol, TryConvertFrom, BNC, + DOT, KSM, VDOT, +}; + +// use balances::Call as BalancesCall; +use crate::{ + mock::*, BlockNumberFor, BoundedVec, Config, DispatchError::BadOrigin, UserDefaultFeeCurrency, +}; + // some common variables pub const CHARLIE: AccountId32 = AccountId32::new([0u8; 32]); pub const BOB: AccountId32 = AccountId32::new([1u8; 32]); pub const ALICE: AccountId32 = AccountId32::new([2u8; 32]); pub const DICK: AccountId32 = AccountId32::new([3u8; 32]); -pub const CURRENCY_ID_0: CurrencyId = CurrencyId::Native(TokenSymbol::BNC); +pub const CURRENCY_ID_0: CurrencyId = BNC; pub const CURRENCY_ID_1: CurrencyId = CurrencyId::Stable(TokenSymbol::KUSD); -pub const CURRENCY_ID_2: CurrencyId = CurrencyId::Token(TokenSymbol::DOT); -pub const CURRENCY_ID_3: CurrencyId = CurrencyId::VToken(TokenSymbol::DOT); -pub const CURRENCY_ID_4: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); +pub const CURRENCY_ID_2: CurrencyId = DOT; +pub const CURRENCY_ID_3: CurrencyId = VDOT; +pub const CURRENCY_ID_4: CurrencyId = KSM; +pub const CURRENCY_ID_5: CurrencyId = WETH; fn basic_setup() { // Deposit some money in Alice, Bob and Charlie's accounts. @@ -551,3 +558,248 @@ fn get_currency_asset_id_should_work() { assert_eq!(asset_id, ksm_asset_id); }); } + +#[test] +fn get_fee_currency_should_work_with_default_currency() { + new_test_ext().execute_with(|| { + let origin_signed_alice = RuntimeOrigin::signed(ALICE); + assert_ok!(FlexibleFee::set_user_default_fee_currency( + origin_signed_alice.clone(), + Some(CURRENCY_ID_0) + )); + + assert_ok!(Currencies::deposit(CURRENCY_ID_0, &ALICE, 100u128.pow(12))); // BNC + assert_ok!(Currencies::deposit(CURRENCY_ID_1, &ALICE, 100u128.pow(18))); // KUSD CurrencyNotSupport + assert_ok!(Currencies::deposit(CURRENCY_ID_2, &ALICE, 100u128.pow(10))); // DOT + assert_ok!(Currencies::deposit(CURRENCY_ID_3, &ALICE, 100u128.pow(10))); // vDOT + assert_ok!(Currencies::deposit(CURRENCY_ID_4, &ALICE, 100u128.pow(12))); // KSM CurrencyNotSupport + assert_ok!(Currencies::deposit(CURRENCY_ID_5, &ALICE, 100u128.pow(18))); // ETH + + let currency = >::get_fee_currency( + &ALICE, + 10u128.pow(18).into(), + ) + .unwrap(); + assert_eq!(currency, BNC); + }); +} + +#[test] +fn get_fee_currency_should_work_with_default_currency_poor() { + new_test_ext().execute_with(|| { + let origin_signed_alice = RuntimeOrigin::signed(ALICE); + assert_ok!(FlexibleFee::set_user_default_fee_currency( + origin_signed_alice.clone(), + Some(CURRENCY_ID_0) + )); + + assert_ok!(Currencies::deposit(CURRENCY_ID_0, &ALICE, 1u128.pow(12))); // BNC + assert_ok!(Currencies::deposit(CURRENCY_ID_1, &ALICE, 100u128.pow(18))); // KUSD CurrencyNotSupport + assert_ok!(Currencies::deposit(CURRENCY_ID_2, &ALICE, 100u128.pow(10))); // DOT + assert_ok!(Currencies::deposit(CURRENCY_ID_3, &ALICE, 100u128.pow(10))); // vDOT + assert_ok!(Currencies::deposit(CURRENCY_ID_4, &ALICE, 100u128.pow(12))); // KSM CurrencyNotSupport + assert_ok!(Currencies::deposit(CURRENCY_ID_5, &ALICE, 100u128.pow(18))); // ETH + + let currency = >::get_fee_currency( + &ALICE, + 10u128.pow(18).into(), + ) + .unwrap(); + assert_eq!(currency, WETH); + }); +} + +#[test] +fn get_fee_currency_should_work_with_weth() { + new_test_ext().execute_with(|| { + assert_ok!(Currencies::deposit(CURRENCY_ID_0, &ALICE, 100u128.pow(12))); // BNC + assert_ok!(Currencies::deposit(CURRENCY_ID_1, &ALICE, 100u128.pow(18))); // KUSD CurrencyNotSupport + assert_ok!(Currencies::deposit(CURRENCY_ID_2, &ALICE, 100u128.pow(10))); // DOT + assert_ok!(Currencies::deposit(CURRENCY_ID_3, &ALICE, 100u128.pow(10))); // vDOT + assert_ok!(Currencies::deposit(CURRENCY_ID_4, &ALICE, 100u128.pow(12))); // KSM CurrencyNotSupport + assert_ok!(Currencies::deposit(CURRENCY_ID_5, &ALICE, 100u128.pow(18))); // ETH + + let currency = >::get_fee_currency( + &ALICE, + 10u128.pow(18).into(), + ) + .unwrap(); + assert_eq!(currency, WETH); + }); +} + +#[test] +fn get_fee_currency_should_work_with_weth_poor() { + new_test_ext().execute_with(|| { + assert_ok!(Currencies::deposit(CURRENCY_ID_0, &ALICE, 100u128.pow(12))); // BNC + assert_ok!(Currencies::deposit(CURRENCY_ID_1, &ALICE, 100u128.pow(18))); // KUSD CurrencyNotSupport + assert_ok!(Currencies::deposit(CURRENCY_ID_2, &ALICE, 100u128.pow(10))); // DOT + assert_ok!(Currencies::deposit(CURRENCY_ID_3, &ALICE, 100u128.pow(10))); // vDOT + assert_ok!(Currencies::deposit(CURRENCY_ID_4, &ALICE, 100u128.pow(12))); // KSM CurrencyNotSupport + assert_ok!(Currencies::deposit(CURRENCY_ID_5, &ALICE, 1u128.pow(18))); // ETH + + let asset_order_list_vec: BoundedVec< + CurrencyId, + ::MaxFeeCurrencyOrderListLen, + > = BoundedVec::try_from(vec![CURRENCY_ID_3, CURRENCY_ID_2, CURRENCY_ID_0]).unwrap(); + + assert_ok!(FlexibleFee::set_universal_fee_currency_order_list( + RuntimeOrigin::root(), + asset_order_list_vec.clone() + )); + + let currency = >::get_fee_currency( + &ALICE, + 10u128.pow(18).into(), + ) + .unwrap(); + assert_eq!(currency, VDOT); + }); +} + +#[test] +fn get_fee_currency_should_work_with_universal_fee_currency() { + new_test_ext().execute_with(|| { + let origin_signed_alice = RuntimeOrigin::signed(ALICE); + assert_ok!(FlexibleFee::set_user_default_fee_currency( + origin_signed_alice.clone(), + Some(CURRENCY_ID_0) + )); + + assert_ok!(Currencies::deposit(CURRENCY_ID_0, &ALICE, 1u128.pow(12))); // BNC + assert_ok!(Currencies::deposit(CURRENCY_ID_1, &ALICE, 100u128.pow(18))); // KUSD CurrencyNotSupport + assert_ok!(Currencies::deposit(CURRENCY_ID_2, &ALICE, 100u128.pow(10))); // DOT + assert_ok!(Currencies::deposit(CURRENCY_ID_3, &ALICE, 100u128.pow(10))); // vDOT + assert_ok!(Currencies::deposit(CURRENCY_ID_4, &ALICE, 100u128.pow(12))); // KSM CurrencyNotSupport + assert_ok!(Currencies::deposit(CURRENCY_ID_5, &ALICE, 1u128.pow(18))); // ETH + + let asset_order_list_vec: BoundedVec< + CurrencyId, + ::MaxFeeCurrencyOrderListLen, + > = BoundedVec::try_from(vec![CURRENCY_ID_3, CURRENCY_ID_2, CURRENCY_ID_0]).unwrap(); + + assert_ok!(FlexibleFee::set_universal_fee_currency_order_list( + RuntimeOrigin::root(), + asset_order_list_vec.clone() + )); + + let currency = >::get_fee_currency( + &ALICE, + 10u128.pow(18).into(), + ) + .unwrap(); + assert_eq!(currency, VDOT); + }); +} + +#[test] +fn get_fee_currency_should_work_with_universal_fee_currency_poor() { + new_test_ext().execute_with(|| { + assert_ok!(Currencies::deposit(CURRENCY_ID_0, &ALICE, 1u128.pow(12))); // BNC + assert_ok!(Currencies::deposit(CURRENCY_ID_1, &ALICE, 100u128.pow(18))); // KUSD CurrencyNotSupport + assert_ok!(Currencies::deposit(CURRENCY_ID_2, &ALICE, 100u128.pow(10))); // DOT + assert_ok!(Currencies::deposit(CURRENCY_ID_3, &ALICE, 1u128.pow(10))); // vDOT + assert_ok!(Currencies::deposit(CURRENCY_ID_4, &ALICE, 100u128.pow(12))); // KSM CurrencyNotSupport + assert_ok!(Currencies::deposit(CURRENCY_ID_5, &ALICE, 1u128.pow(18))); // ETH + + let asset_order_list_vec: BoundedVec< + CurrencyId, + ::MaxFeeCurrencyOrderListLen, + > = BoundedVec::try_from(vec![CURRENCY_ID_3, CURRENCY_ID_2, CURRENCY_ID_0]).unwrap(); + + assert_ok!(FlexibleFee::set_universal_fee_currency_order_list( + RuntimeOrigin::root(), + asset_order_list_vec.clone() + )); + + let currency = >::get_fee_currency( + &ALICE, + 10u128.pow(18).into(), + ) + .unwrap(); + assert_eq!(currency, DOT); + }); +} + +#[test] +fn get_fee_currency_should_work_with_all_currency_poor() { + new_test_ext().execute_with(|| { + let origin_signed_alice = RuntimeOrigin::signed(ALICE); + assert_ok!(FlexibleFee::set_user_default_fee_currency( + origin_signed_alice.clone(), + Some(CURRENCY_ID_0) + )); + + assert_ok!(Currencies::deposit(CURRENCY_ID_0, &ALICE, 7u128.pow(12))); // BNC + assert_ok!(Currencies::deposit(CURRENCY_ID_1, &ALICE, 6u128.pow(18))); // KUSD CurrencyNotSupport + assert_ok!(Currencies::deposit(CURRENCY_ID_2, &ALICE, 5u128.pow(10))); // DOT + assert_ok!(Currencies::deposit(CURRENCY_ID_3, &ALICE, 4u128.pow(10))); // vDOT + assert_ok!(Currencies::deposit(CURRENCY_ID_4, &ALICE, 3u128.pow(12))); // KSM CurrencyNotSupport + assert_ok!(Currencies::deposit(CURRENCY_ID_5, &ALICE, 2u128.pow(18))); // ETH + + let asset_order_list_vec: BoundedVec< + CurrencyId, + ::MaxFeeCurrencyOrderListLen, + > = BoundedVec::try_from(vec![CURRENCY_ID_3, CURRENCY_ID_2, CURRENCY_ID_0]).unwrap(); + + assert_ok!(FlexibleFee::set_universal_fee_currency_order_list( + RuntimeOrigin::root(), + asset_order_list_vec.clone() + )); + + let currency = >::get_fee_currency( + &ALICE, + 10u128.pow(18).into(), + ) + .unwrap(); + assert_eq!(currency, BNC); + }); +} + +#[test] +fn cmp_with_precision_should_work_with_weth() { + new_test_ext().execute_with(|| { + assert_ok!(Currencies::deposit(CURRENCY_ID_5, &ALICE, 10u128.pow(18) - 1)); // ETH + + let ordering = >::cmp_with_precision( + &ALICE, + &WETH, + 10u128.pow(18), + 18u32, + ) + .unwrap(); + assert_eq!(ordering, Less); + }); +} + +#[test] +fn cmp_with_precision_should_work_with_dot() { + new_test_ext().execute_with(|| { + assert_ok!(Currencies::deposit(CURRENCY_ID_2, &ALICE, 10u128.pow(11) + 1)); // DOT + + let ordering = >::cmp_with_precision( + &ALICE, + &DOT, + 10u128.pow(18), + 18u32, + ) + .unwrap(); + assert_eq!(ordering, Greater); + }); +} + +#[test] +fn cmp_with_precision_should_work_with_bnc() { + new_test_ext().execute_with(|| { + assert_ok!(Currencies::deposit(CURRENCY_ID_0, &ALICE, 11u128.pow(12))); // BNC + + let ordering = >::cmp_with_precision( + &ALICE, + &BNC, + 10u128.pow(18), + 18u32, + ) + .unwrap(); + assert_eq!(ordering, Greater); + }); +} diff --git a/pallets/lend-market/src/interest.rs b/pallets/lend-market/src/interest.rs index f12daa6fb..f09041a1d 100644 --- a/pallets/lend-market/src/interest.rs +++ b/pallets/lend-market/src/interest.rs @@ -21,7 +21,7 @@ impl Pallet { /// Accrue interest and update corresponding storage pub(crate) fn accrue_interest(asset_id: AssetIdOf) -> DispatchResult { let now = T::UnixTime::now().as_secs(); - let last_accrued_interest_time = Self::last_accrued_interest_time(asset_id); + let last_accrued_interest_time = LastAccruedInterestTime::::get(asset_id); if last_accrued_interest_time.is_zero() { // For the initialization Self::update_last_accrued_interest_time(asset_id, now)?; @@ -59,11 +59,11 @@ impl Pallet { asset_id: AssetIdOf, ) -> Result<(Rate, Rate, Rate, Ratio, BalanceOf, BalanceOf, FixedU128), DispatchError> { let market = Self::market(asset_id)?; - let total_supply = Self::total_supply(asset_id); + let total_supply = TotalSupply::::get(asset_id); let total_cash = Self::get_total_cash(asset_id); - let mut total_borrows = Self::total_borrows(asset_id); - let mut total_reserves = Self::total_reserves(asset_id); - let mut borrow_index = Self::borrow_index(asset_id); + let mut total_borrows = TotalBorrows::::get(asset_id); + let mut total_reserves = TotalReserves::::get(asset_id); + let mut borrow_index = BorrowIndex::::get(asset_id); let util = Self::calc_utilization_ratio(total_cash, total_borrows, total_reserves)?; let borrow_rate = @@ -72,7 +72,7 @@ impl Pallet { InterestRateModel::get_supply_rate(borrow_rate, util, market.reserve_factor); let now = T::UnixTime::now().as_secs(); - let last_accrued_interest_time = Self::last_accrued_interest_time(asset_id); + let last_accrued_interest_time = LastAccruedInterestTime::::get(asset_id); if now > last_accrued_interest_time { let delta_time = now - last_accrued_interest_time; let interest_accumulated = @@ -110,10 +110,10 @@ impl Pallet { /// This function does not accrue interest before calculating the exchange rate. /// exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply pub fn exchange_rate_stored(asset_id: AssetIdOf) -> Result { - let total_supply = Self::total_supply(asset_id); + let total_supply = TotalSupply::::get(asset_id); let total_cash = Self::get_total_cash(asset_id); - let total_borrows = Self::total_borrows(asset_id); - let total_reserves = Self::total_reserves(asset_id); + let total_borrows = TotalBorrows::::get(asset_id); + let total_reserves = TotalReserves::::get(asset_id); Self::calculate_exchange_rate(total_supply, total_cash, total_borrows, total_reserves) } diff --git a/pallets/lend-market/src/lend_token.rs b/pallets/lend-market/src/lend_token.rs index 9076edc9c..284f10322 100644 --- a/pallets/lend-market/src/lend_token.rs +++ b/pallets/lend-market/src/lend_token.rs @@ -28,7 +28,7 @@ impl Inspect for Pallet { /// The total amount of issuance in the system. fn total_issuance(lend_token_id: Self::AssetId) -> Self::Balance { if let Ok(underlying_id) = Self::underlying_id(lend_token_id) { - Self::total_supply(underlying_id) + TotalSupply::::get(underlying_id) } else { Balance::default() } @@ -42,7 +42,7 @@ impl Inspect for Pallet { /// Get the lend token balance of `who`. fn balance(lend_token_id: Self::AssetId, who: &T::AccountId) -> Self::Balance { if let Ok(underlying_id) = Self::underlying_id(lend_token_id) { - Self::account_deposits(underlying_id, who).voucher_balance + AccountDeposits::::get(underlying_id, who).voucher_balance } else { Balance::default() } @@ -77,7 +77,7 @@ impl Inspect for Pallet { return res; } - if Self::total_supply(underlying_id).checked_add(amount).is_none() { + if TotalSupply::::get(underlying_id).checked_add(amount).is_none() { return DepositConsequence::Overflow; } @@ -200,7 +200,7 @@ impl Pallet { ) -> Result, DispatchError> { let underlying_id = Self::underlying_id(lend_token_id)?; let Deposits { is_collateral, voucher_balance } = - Self::account_deposits(underlying_id, who); + AccountDeposits::::get(underlying_id, who); if !is_collateral { return Ok(voucher_balance); @@ -229,7 +229,7 @@ impl Pallet { .ok_or(ArithmeticError::Underflow)? .into_inner(); - let exchange_rate = Self::exchange_rate(underlying_id); + let exchange_rate = ExchangeRate::::get(underlying_id); let amount = Self::calc_collateral_amount(reducible_underlying_amount, exchange_rate)?; Ok(amount) } diff --git a/pallets/lend-market/src/lib.rs b/pallets/lend-market/src/lib.rs index f31bfab89..e0dbb842f 100644 --- a/pallets/lend-market/src/lib.rs +++ b/pallets/lend-market/src/lib.rs @@ -270,40 +270,34 @@ pub mod pallet { /// The timestamp of the last calculation of accrued interest #[pallet::storage] - #[pallet::getter(fn last_accrued_interest_time)] pub type LastAccruedInterestTime = StorageMap<_, Blake2_128Concat, AssetIdOf, Timestamp, ValueQuery>; /// Liquidation free collateral. #[pallet::storage] - #[pallet::getter(fn liquidation_free_collaterals)] pub type LiquidationFreeCollaterals = StorageValue<_, Vec>, ValueQuery>; /// Total number of collateral tokens in circulation /// CollateralType -> Balance #[pallet::storage] - #[pallet::getter(fn total_supply)] pub type TotalSupply = StorageMap<_, Blake2_128Concat, AssetIdOf, BalanceOf, ValueQuery>; /// Total amount of outstanding borrows of the underlying in this market /// CurrencyId -> Balance #[pallet::storage] - #[pallet::getter(fn total_borrows)] pub type TotalBorrows = StorageMap<_, Blake2_128Concat, AssetIdOf, BalanceOf, ValueQuery>; /// Total amount of reserves of the underlying held in this market /// CurrencyId -> Balance #[pallet::storage] - #[pallet::getter(fn total_reserves)] pub type TotalReserves = StorageMap<_, Blake2_128Concat, AssetIdOf, BalanceOf, ValueQuery>; /// Mapping of account addresses to outstanding borrow balances /// CurrencyId -> Owner -> BorrowSnapshot #[pallet::storage] - #[pallet::getter(fn account_borrows)] pub type AccountBorrows = StorageDoubleMap< _, Blake2_128Concat, @@ -317,7 +311,6 @@ pub mod pallet { /// Mapping of account addresses to deposit details /// CollateralType -> Owner -> Deposits #[pallet::storage] - #[pallet::getter(fn account_deposits)] pub type AccountDeposits = StorageDoubleMap< _, Blake2_128Concat, @@ -331,7 +324,6 @@ pub mod pallet { /// Mapping of account addresses to total deposit interest accrual /// CurrencyId -> Owner -> EarnedSnapshot #[pallet::storage] - #[pallet::getter(fn account_earned)] pub type AccountEarned = StorageDoubleMap< _, Blake2_128Concat, @@ -345,31 +337,26 @@ pub mod pallet { /// Accumulator of the total earned interest rate since the opening of the market /// CurrencyId -> u128 #[pallet::storage] - #[pallet::getter(fn borrow_index)] pub type BorrowIndex = StorageMap<_, Blake2_128Concat, AssetIdOf, Rate, ValueQuery>; /// The exchange rate from the underlying to the internal collateral #[pallet::storage] - #[pallet::getter(fn exchange_rate)] pub type ExchangeRate = StorageMap<_, Blake2_128Concat, AssetIdOf, Rate, ValueQuery>; /// Mapping of borrow rate to currency type #[pallet::storage] - #[pallet::getter(fn borrow_rate)] pub type BorrowRate = StorageMap<_, Blake2_128Concat, AssetIdOf, Rate, ValueQuery>; /// Mapping of supply rate to currency type #[pallet::storage] - #[pallet::getter(fn supply_rate)] pub type SupplyRate = StorageMap<_, Blake2_128Concat, AssetIdOf, Rate, ValueQuery>; /// Borrow utilization ratio #[pallet::storage] - #[pallet::getter(fn utilization_ratio)] pub type UtilizationRatio = StorageMap<_, Blake2_128Concat, AssetIdOf, Ratio, ValueQuery>; @@ -387,19 +374,16 @@ pub mod pallet { /// Mapping of token id to supply reward speed #[pallet::storage] - #[pallet::getter(fn reward_supply_speed)] pub type RewardSupplySpeed = StorageMap<_, Blake2_128Concat, AssetIdOf, BalanceOf, ValueQuery>; /// Mapping of token id to borrow reward speed #[pallet::storage] - #[pallet::getter(fn reward_borrow_speed)] pub type RewardBorrowSpeed = StorageMap<_, Blake2_128Concat, AssetIdOf, BalanceOf, ValueQuery>; /// The Reward market supply state for each market #[pallet::storage] - #[pallet::getter(fn reward_supply_state)] pub type RewardSupplyState = StorageMap< _, Blake2_128Concat, @@ -410,7 +394,6 @@ pub mod pallet { /// The Reward market borrow state for each market #[pallet::storage] - #[pallet::getter(fn reward_borrow_state)] pub type RewardBorrowState = StorageMap< _, Blake2_128Concat, @@ -421,7 +404,6 @@ pub mod pallet { /// The Reward index for each market for each supplier as of the last time they accrued Reward #[pallet::storage] - #[pallet::getter(fn reward_supplier_index)] pub type RewardSupplierIndex = StorageDoubleMap< _, Blake2_128Concat, @@ -434,7 +416,6 @@ pub mod pallet { /// The Reward index for each market for each borrower as of the last time they accrued Reward #[pallet::storage] - #[pallet::getter(fn reward_borrower_index)] pub type RewardBorrowerIndex = StorageDoubleMap< _, Blake2_128Concat, @@ -448,7 +429,6 @@ pub mod pallet { /// The reward accrued but not yet transferred to each user. #[pallet::storage] #[pallet::storage_prefix = "RewardAccured"] - #[pallet::getter(fn reward_accrued)] pub type RewardAccrued = StorageMap<_, Blake2_128Concat, T::AccountId, BalanceOf, ValueQuery>; @@ -953,7 +933,7 @@ pub mod pallet { let who = ensure_signed(origin)?; Self::ensure_active_market(asset_id)?; ensure!(AccountDeposits::::contains_key(asset_id, &who), Error::::NoDeposit); - let deposits = Self::account_deposits(asset_id, &who); + let deposits = AccountDeposits::::get(asset_id, &who); if deposits.is_collateral == enable { return Err(Error::::DuplicateOperation.into()); } @@ -981,7 +961,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; ensure!( - !Self::liquidation_free_collaterals().contains(&collateral_asset_id), + !LiquidationFreeCollaterals::::get().contains(&collateral_asset_id), Error::::CollateralReserved ); Self::accrue_interest(liquidation_asset_id)?; @@ -1023,7 +1003,7 @@ pub mod pallet { add_amount, Preservation::Expendable, )?; - let total_reserves = Self::total_reserves(asset_id); + let total_reserves = TotalReserves::::get(asset_id); let total_reserves_new = total_reserves.checked_add(add_amount).ok_or(ArithmeticError::Overflow)?; TotalReserves::::insert(asset_id, total_reserves_new); @@ -1058,7 +1038,7 @@ pub mod pallet { let receiver = T::Lookup::lookup(receiver)?; Self::ensure_active_market(asset_id)?; - let total_reserves = Self::total_reserves(asset_id); + let total_reserves = TotalReserves::::get(asset_id); if reduce_amount > total_reserves { return Err(Error::::InsufficientReserves.into()); } @@ -1168,7 +1148,7 @@ impl Pallet { fn get_lf_base_position(account: &T::AccountId) -> Result { let mut total_asset_value: FixedU128 = FixedU128::zero(); for (asset_id, _market) in Self::active_markets() - .filter(|(asset_id, _)| Self::liquidation_free_collaterals().contains(asset_id)) + .filter(|(asset_id, _)| LiquidationFreeCollaterals::::get().contains(asset_id)) { total_asset_value = total_asset_value .checked_add(&Self::collateral_asset_value(account, asset_id)?) @@ -1182,7 +1162,7 @@ impl Pallet { ) -> Result { let mut total_asset_value: FixedU128 = FixedU128::zero(); for (asset_id, _market) in Self::active_markets() - .filter(|(asset_id, _)| Self::liquidation_free_collaterals().contains(asset_id)) + .filter(|(asset_id, _)| LiquidationFreeCollaterals::::get().contains(asset_id)) { total_asset_value = total_asset_value .checked_add(&Self::liquidation_threshold_asset_value(account, asset_id)?) @@ -1305,7 +1285,7 @@ impl Pallet { if !AccountDeposits::::contains_key(asset_id, supplier) { return Ok(BalanceOf::::zero()); } - let deposits = Self::account_deposits(asset_id, supplier); + let deposits = AccountDeposits::::get(asset_id, supplier); if !deposits.is_collateral { return Ok(BalanceOf::::zero()); } @@ -1337,7 +1317,7 @@ impl Pallet { if !AccountDeposits::::contains_key(asset_id, borrower) { return Ok(FixedU128::zero()); } - let deposits = Self::account_deposits(asset_id, borrower); + let deposits = AccountDeposits::::get(asset_id, borrower); if !deposits.is_collateral { return Ok(FixedU128::zero()); } @@ -1390,7 +1370,7 @@ impl Pallet { redeemer, voucher_amount, ); - let deposit = Self::account_deposits(asset_id, redeemer); + let deposit = AccountDeposits::::get(asset_id, redeemer); if deposit.voucher_balance < voucher_amount { return Err(Error::::InsufficientDeposit.into()); } @@ -1416,7 +1396,7 @@ impl Pallet { Self::ensure_liquidity( redeemer, redeem_effects_value, - Self::liquidation_free_collaterals().contains(&asset_id), + LiquidationFreeCollaterals::::get().contains(&asset_id), )?; Ok(()) @@ -1521,7 +1501,7 @@ impl Pallet { )?; let account_borrows_new = account_borrows.checked_sub(repay_amount).ok_or(ArithmeticError::Underflow)?; - let total_borrows = Self::total_borrows(asset_id); + let total_borrows = TotalBorrows::::get(asset_id); // NOTE : total_borrows use a different way to calculate interest // so when user repays all borrows, total_borrows can be less than account_borrows // which will cause it to fail with `ArithmeticError::Underflow` @@ -1533,7 +1513,7 @@ impl Pallet { borrower, BorrowSnapshot { principal: account_borrows_new, - borrow_index: Self::borrow_index(asset_id), + borrow_index: BorrowIndex::::get(asset_id), }, ); TotalBorrows::::insert(asset_id, total_borrows_new); @@ -1547,13 +1527,13 @@ impl Pallet { who: &T::AccountId, asset_id: AssetIdOf, ) -> Result, DispatchError> { - let snapshot: BorrowSnapshot> = Self::account_borrows(asset_id, who); + let snapshot: BorrowSnapshot> = AccountBorrows::::get(asset_id, who); if snapshot.principal.is_zero() || snapshot.borrow_index.is_zero() { return Ok(Zero::zero()); } // Calculate new borrow balance using the interest index: // recent_borrow_balance = snapshot.principal * borrow_index / snapshot.borrow_index - let recent_borrow_balance = Self::borrow_index(asset_id) + let recent_borrow_balance = BorrowIndex::::get(asset_id) .checked_div(&snapshot.borrow_index) .and_then(|r| r.checked_mul_int(snapshot.principal)) .ok_or(ArithmeticError::Overflow)?; @@ -1756,7 +1736,7 @@ impl Pallet { let account_borrows = Self::current_borrow_balance(borrower, liquidation_asset_id)?; let account_borrows_new = account_borrows.checked_sub(repay_amount).ok_or(ArithmeticError::Underflow)?; - let total_borrows = Self::total_borrows(liquidation_asset_id); + let total_borrows = TotalBorrows::::get(liquidation_asset_id); let total_borrows_new = total_borrows.checked_sub(repay_amount).ok_or(ArithmeticError::Underflow)?; AccountBorrows::::insert( @@ -1764,7 +1744,7 @@ impl Pallet { borrower, BorrowSnapshot { principal: account_borrows_new, - borrow_index: Self::borrow_index(liquidation_asset_id), + borrow_index: BorrowIndex::::get(liquidation_asset_id), }, ); TotalBorrows::::insert(liquidation_asset_id, total_borrows_new); @@ -1858,7 +1838,7 @@ impl Pallet { /// Make sure the borrowing under the borrow cap fn ensure_under_borrow_cap(asset_id: AssetIdOf, amount: BalanceOf) -> DispatchResult { let market = Self::market(asset_id)?; - let total_borrows = Self::total_borrows(asset_id); + let total_borrows = TotalBorrows::::get(asset_id); let new_total_borrows = total_borrows.checked_add(amount).ok_or(ArithmeticError::Overflow)?; ensure!(new_total_borrows <= market.borrow_cap, Error::::BorrowCapacityExceeded); @@ -1869,7 +1849,7 @@ impl Pallet { /// Make sure there is enough cash available in the pool fn ensure_enough_cash(asset_id: AssetIdOf, amount: BalanceOf) -> DispatchResult { let reducible_cash = Self::get_total_cash(asset_id) - .checked_sub(Self::total_reserves(asset_id)) + .checked_sub(TotalReserves::::get(asset_id)) .ok_or(ArithmeticError::Underflow)?; if reducible_cash < amount { return Err(Error::::InsufficientCash.into()); @@ -2142,7 +2122,7 @@ impl LendMarketTrait, AccountIdOf, BalanceOf> for let account_borrows = Self::current_borrow_balance(borrower, asset_id)?; let account_borrows_new = account_borrows.checked_add(amount).ok_or(ArithmeticError::Overflow)?; - let total_borrows = Self::total_borrows(asset_id); + let total_borrows = TotalBorrows::::get(asset_id); let total_borrows_new = total_borrows.checked_add(amount).ok_or(ArithmeticError::Overflow)?; AccountBorrows::::insert( @@ -2150,7 +2130,7 @@ impl LendMarketTrait, AccountIdOf, BalanceOf> for borrower, BorrowSnapshot { principal: account_borrows_new, - borrow_index: Self::borrow_index(asset_id), + borrow_index: BorrowIndex::::get(asset_id), }, ); TotalBorrows::::insert(asset_id, total_borrows_new); @@ -2172,7 +2152,7 @@ impl LendMarketTrait, AccountIdOf, BalanceOf> for ) -> Result<(), DispatchError> { Self::ensure_active_market(asset_id)?; ensure!(AccountDeposits::::contains_key(asset_id, supplier), Error::::NoDeposit); - let mut deposits = Self::account_deposits(asset_id, supplier); + let mut deposits = AccountDeposits::::get(asset_id, supplier); // turn on the collateral button if enable { deposits.is_collateral = true; diff --git a/pallets/lend-market/src/tests.rs b/pallets/lend-market/src/tests.rs index d23eff689..f8e2aec9e 100644 --- a/pallets/lend-market/src/tests.rs +++ b/pallets/lend-market/src/tests.rs @@ -126,13 +126,13 @@ fn lend_market_native_token_works() { // BNC borrow balance: borrow - repay = 500 - 400 = 100 // BNC: cash - deposit + borrow - repay = 1000 - 1000 + 500 - 400 = 100 assert_eq!( - LendMarket::exchange_rate(BNC) - .saturating_mul_int(LendMarket::account_deposits(BNC, DAVE).voucher_balance), + ExchangeRate::::get(BNC) + .saturating_mul_int(AccountDeposits::::get(BNC, DAVE).voucher_balance), unit(1000) ); - let borrow_snapshot = LendMarket::account_borrows(BNC, DAVE); + let borrow_snapshot = AccountBorrows::::get(BNC, DAVE); assert_eq!(borrow_snapshot.principal, unit(100)); - assert_eq!(borrow_snapshot.borrow_index, LendMarket::borrow_index(BNC)); + assert_eq!(borrow_snapshot.borrow_index, BorrowIndex::::get(BNC)); assert_eq!(::Assets::balance(BNC, &DAVE), unit(100),); }) } @@ -161,8 +161,8 @@ fn mint_works() { // DOT collateral: deposit = 100 // DOT: cash - deposit = 1000 - 100 = 900 assert_eq!( - LendMarket::exchange_rate(DOT) - .saturating_mul_int(LendMarket::account_deposits(DOT, ALICE).voucher_balance), + ExchangeRate::::get(DOT) + .saturating_mul_int(AccountDeposits::::get(DOT, ALICE).voucher_balance), unit(100) ); assert_eq!(::Assets::balance(DOT, &ALICE), unit(900),); @@ -356,8 +356,8 @@ fn redeem_works() { // DOT collateral: deposit - redeem = 100 - 20 = 80 // DOT: cash - deposit + redeem = 1000 - 100 + 20 = 920 assert_eq!( - LendMarket::exchange_rate(DOT) - .saturating_mul_int(LendMarket::account_deposits(DOT, ALICE).voucher_balance), + ExchangeRate::::get(DOT) + .saturating_mul_int(AccountDeposits::::get(DOT, ALICE).voucher_balance), unit(80) ); assert_eq!(::Assets::balance(DOT, &ALICE), unit(920),); @@ -511,8 +511,8 @@ fn redeem_all_works() { // DOT: cash - deposit + redeem = 1000 - 100 + 100 = 1000 // DOT collateral: deposit - redeem = 100 - 100 = 0 assert_eq!( - LendMarket::exchange_rate(DOT) - .saturating_mul_int(LendMarket::account_deposits(DOT, ALICE).voucher_balance), + ExchangeRate::::get(DOT) + .saturating_mul_int(AccountDeposits::::get(DOT, ALICE).voucher_balance), 0, ); assert_eq!(::Assets::balance(DOT, &ALICE), unit(1000),); @@ -588,7 +588,7 @@ fn update_liquidation_free_collateral_works() { RuntimeOrigin::root(), vec![PHA] )); - assert_eq!(LendMarket::liquidation_free_collaterals(), vec![PHA]); + assert_eq!(LiquidationFreeCollaterals::::get(), vec![PHA]); }) } @@ -731,13 +731,13 @@ fn borrow_works() { // DOT borrow balance: borrow = 100 // DOT: cash - deposit + borrow = 1000 - 200 + 100 = 900 assert_eq!( - LendMarket::exchange_rate(DOT) - .saturating_mul_int(LendMarket::account_deposits(DOT, ALICE).voucher_balance), + ExchangeRate::::get(DOT) + .saturating_mul_int(AccountDeposits::::get(DOT, ALICE).voucher_balance), unit(200) ); - let borrow_snapshot = LendMarket::account_borrows(DOT, ALICE); + let borrow_snapshot = AccountBorrows::::get(DOT, ALICE); assert_eq!(borrow_snapshot.principal, unit(100)); - assert_eq!(borrow_snapshot.borrow_index, LendMarket::borrow_index(DOT)); + assert_eq!(borrow_snapshot.borrow_index, BorrowIndex::::get(DOT)); assert_eq!(::Assets::balance(DOT, &ALICE), unit(900),); }) } @@ -772,13 +772,13 @@ fn lf_borrow_works() { // DOT borrow balance: borrow = 100 // DOT: cash - deposit + borrow = 1000 + 100 = 1100 assert_eq!( - LendMarket::exchange_rate(PHA) - .saturating_mul_int(LendMarket::account_deposits(PHA, ALICE).voucher_balance), + ExchangeRate::::get(PHA) + .saturating_mul_int(AccountDeposits::::get(PHA, ALICE).voucher_balance), unit(200) ); - let borrow_snapshot = LendMarket::account_borrows(DOT, ALICE); + let borrow_snapshot = AccountBorrows::::get(DOT, ALICE); assert_eq!(borrow_snapshot.principal, unit(100)); - assert_eq!(borrow_snapshot.borrow_index, LendMarket::borrow_index(DOT)); + assert_eq!(borrow_snapshot.borrow_index, BorrowIndex::::get(DOT)); assert_eq!(::Assets::balance(DOT, &ALICE), unit(1100),); }) } @@ -813,13 +813,13 @@ fn repay_borrow_works() { // DOT borrow balance: borrow - repay = 100 - 30 = 70 // DOT: cash - deposit + borrow - repay = 1000 - 200 + 100 - 30 = 870 assert_eq!( - LendMarket::exchange_rate(DOT) - .saturating_mul_int(LendMarket::account_deposits(DOT, ALICE).voucher_balance), + ExchangeRate::::get(DOT) + .saturating_mul_int(AccountDeposits::::get(DOT, ALICE).voucher_balance), unit(200) ); - let borrow_snapshot = LendMarket::account_borrows(DOT, ALICE); + let borrow_snapshot = AccountBorrows::::get(DOT, ALICE); assert_eq!(borrow_snapshot.principal, unit(70)); - assert_eq!(borrow_snapshot.borrow_index, LendMarket::borrow_index(DOT)); + assert_eq!(borrow_snapshot.borrow_index, BorrowIndex::::get(DOT)); assert_eq!(::Assets::balance(DOT, &ALICE), unit(870),); }) } @@ -859,13 +859,13 @@ fn repay_borrow_all_works() { // KSM borrow balance: borrow - repay = 50 - 50 = 0 assert_eq!(::Assets::balance(DOT, &ALICE), unit(800),); assert_eq!( - LendMarket::exchange_rate(DOT) - .saturating_mul_int(LendMarket::account_deposits(DOT, ALICE).voucher_balance), + ExchangeRate::::get(DOT) + .saturating_mul_int(AccountDeposits::::get(DOT, ALICE).voucher_balance), unit(200) ); - let borrow_snapshot = LendMarket::account_borrows(KSM, ALICE); + let borrow_snapshot = AccountBorrows::::get(KSM, ALICE); assert_eq!(borrow_snapshot.principal, 0); - assert_eq!(borrow_snapshot.borrow_index, LendMarket::borrow_index(KSM)); + assert_eq!(borrow_snapshot.borrow_index, BorrowIndex::::get(KSM)); }) } @@ -895,7 +895,7 @@ fn collateral_asset_works() { // Deposit 200 DOT as collateral assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), DOT, 200)); assert_ok!(LendMarket::collateral_asset(RuntimeOrigin::signed(ALICE), DOT, true)); - assert_eq!(LendMarket::account_deposits(DOT, ALICE).is_collateral, true); + assert_eq!(AccountDeposits::::get(DOT, ALICE).is_collateral, true); assert_noop!( LendMarket::collateral_asset(RuntimeOrigin::signed(ALICE), DOT, true), Error::::DuplicateOperation @@ -909,7 +909,7 @@ fn collateral_asset_works() { // Repay all the borrows assert_ok!(LendMarket::repay_borrow_all(RuntimeOrigin::signed(ALICE), DOT)); assert_ok!(LendMarket::collateral_asset(RuntimeOrigin::signed(ALICE), DOT, false)); - assert_eq!(LendMarket::account_deposits(DOT, ALICE).is_collateral, false); + assert_eq!(AccountDeposits::::get(DOT, ALICE).is_collateral, false); assert_noop!( LendMarket::collateral_asset(RuntimeOrigin::signed(ALICE), DOT, false), Error::::DuplicateOperation @@ -970,7 +970,7 @@ fn add_reserves_works() { // Add 100 DOT reserves assert_ok!(LendMarket::add_reserves(RuntimeOrigin::root(), ALICE, DOT, unit(100))); - assert_eq!(LendMarket::total_reserves(DOT), unit(100)); + assert_eq!(TotalReserves::::get(DOT), unit(100)); assert_eq!(::Assets::balance(DOT, &LendMarket::account_id()), unit(100),); assert_eq!(::Assets::balance(DOT, &ALICE), unit(900),); }) @@ -1000,7 +1000,7 @@ fn reduce_reserves_works() { // Reduce 20 DOT reserves assert_ok!(LendMarket::reduce_reserves(RuntimeOrigin::root(), ALICE, DOT, unit(20))); - assert_eq!(LendMarket::total_reserves(DOT), unit(80)); + assert_eq!(TotalReserves::::get(DOT), unit(80)); assert_eq!(::Assets::balance(DOT, &LendMarket::account_id()), unit(80),); assert_eq!(::Assets::balance(DOT, &ALICE), unit(920),); }) @@ -1158,7 +1158,7 @@ fn update_exchange_rate_works() { vec![DOT, BNC, KSM, DOT_U, PHA] )); // Initialize value of exchange rate is 0.02 - assert_eq!(LendMarket::exchange_rate(DOT), Rate::saturating_from_rational(2, 100)); + assert_eq!(ExchangeRate::::get(DOT), Rate::saturating_from_rational(2, 100)); // total_supply = 0 TotalSupply::::insert(DOT, 0); @@ -1403,8 +1403,8 @@ fn update_market_reward_speed_works() { BNC, vec![DOT, BNC, KSM, DOT_U, PHA] )); - assert_eq!(LendMarket::reward_supply_speed(DOT), 0); - assert_eq!(LendMarket::reward_borrow_speed(DOT), 0); + assert_eq!(RewardSupplySpeed::::get(DOT), 0); + assert_eq!(RewardBorrowSpeed::::get(DOT), 0); assert_ok!(LendMarket::update_market_reward_speed( RuntimeOrigin::root(), @@ -1412,8 +1412,8 @@ fn update_market_reward_speed_works() { Some(unit(1)), Some(unit(2)), )); - assert_eq!(LendMarket::reward_supply_speed(DOT), unit(1)); - assert_eq!(LendMarket::reward_borrow_speed(DOT), unit(2)); + assert_eq!(RewardSupplySpeed::::get(DOT), unit(1)); + assert_eq!(RewardBorrowSpeed::::get(DOT), unit(2)); assert_ok!(LendMarket::update_market_reward_speed( RuntimeOrigin::root(), @@ -1421,8 +1421,8 @@ fn update_market_reward_speed_works() { Some(unit(2)), Some(0), )); - assert_eq!(LendMarket::reward_supply_speed(DOT), unit(2)); - assert_eq!(LendMarket::reward_borrow_speed(DOT), unit(0)); + assert_eq!(RewardSupplySpeed::::get(DOT), unit(2)); + assert_eq!(RewardBorrowSpeed::::get(DOT), unit(0)); assert_ok!(LendMarket::update_market_reward_speed( RuntimeOrigin::root(), @@ -1430,8 +1430,8 @@ fn update_market_reward_speed_works() { Some(0), Some(0) )); - assert_eq!(LendMarket::reward_supply_speed(DOT), unit(0)); - assert_eq!(LendMarket::reward_borrow_speed(DOT), unit(0)); + assert_eq!(RewardSupplySpeed::::get(DOT), unit(0)); + assert_eq!(RewardBorrowSpeed::::get(DOT), unit(0)); }) } @@ -1469,17 +1469,17 @@ fn reward_calculation_one_palyer_in_multi_markets_works() { )); // check status - let supply_state = LendMarket::reward_supply_state(DOT); + let supply_state = RewardSupplyState::::get(DOT); assert_eq!(supply_state.block, 10); - assert_eq!(LendMarket::reward_supplier_index(DOT, ALICE), 0); - let borrow_state = LendMarket::reward_borrow_state(DOT); + assert_eq!(RewardSupplierIndex::::get(DOT, ALICE), 0); + let borrow_state = RewardBorrowState::::get(DOT); assert_eq!(borrow_state.block, 10); - assert_eq!(LendMarket::reward_borrower_index(DOT, ALICE), 0); + assert_eq!(RewardBorrowerIndex::::get(DOT, ALICE), 0); // DOT supply:100 DOT supply reward: 0 // DOT borrow:10 DOT borrow reward: 0 // KSM supply:100 KSM supply reward: 0 // KSM borrow:10 KSM borrow reward: 0 - assert_eq!(LendMarket::reward_accrued(ALICE), 0); + assert_eq!(RewardAccrued::::get(ALICE), 0); _run_to_block(20); assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), DOT, unit(100))); @@ -1491,16 +1491,16 @@ fn reward_calculation_one_palyer_in_multi_markets_works() { )); // check status - let supply_state = LendMarket::reward_supply_state(DOT); + let supply_state = RewardSupplyState::::get(DOT); assert_eq!(supply_state.block, 20); - let borrow_state = LendMarket::reward_borrow_state(DOT); + let borrow_state = RewardBorrowState::::get(DOT); assert_eq!(borrow_state.block, 10); // DOT supply:200 DOT supply reward: 10 // DOT borrow:10 DOT borrow reward: 0 // KSM supply:100 KSM supply reward: 0 // KSM borrow:10 KSM borrow reward: 0 // borrow reward not accrued - assert_eq!(LendMarket::reward_accrued(ALICE), unit(10)); + assert_eq!(RewardAccrued::::get(ALICE), unit(10)); _run_to_block(30); assert_ok!(LendMarket::update_market_reward_speed( @@ -1514,15 +1514,15 @@ fn reward_calculation_one_palyer_in_multi_markets_works() { assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), KSM, unit(100))); assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(ALICE), KSM, unit(10))); - let supply_state = LendMarket::reward_supply_state(DOT); + let supply_state = RewardSupplyState::::get(DOT); assert_eq!(supply_state.block, 30); - let borrow_state = LendMarket::reward_borrow_state(DOT); + let borrow_state = RewardBorrowState::::get(DOT); assert_eq!(borrow_state.block, 30); // DOT supply:100 DOT supply reward: 20 // DOT borrow:20 DOT borrow reward: 40 // KSM supply:200 KSM supply reward: 10 // KSM borrow:20 KSM borrow reward: 10 - assert_eq!(almost_equal(LendMarket::reward_accrued(ALICE), unit(80)), true); + assert_eq!(almost_equal(RewardAccrued::::get(ALICE), unit(80)), true); _run_to_block(40); assert_ok!(LendMarket::update_market_reward_speed( @@ -1536,15 +1536,15 @@ fn reward_calculation_one_palyer_in_multi_markets_works() { assert_ok!(LendMarket::redeem(RuntimeOrigin::signed(ALICE), KSM, unit(100))); assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(ALICE), KSM, unit(10))); - let supply_state = LendMarket::reward_supply_state(DOT); + let supply_state = RewardSupplyState::::get(DOT); assert_eq!(supply_state.block, 40); - let borrow_state = LendMarket::reward_borrow_state(DOT); + let borrow_state = RewardBorrowState::::get(DOT); assert_eq!(borrow_state.block, 40); // DOT supply:200 DOT supply reward: 20 // DOT borrow:30 DOT borrow reward: 40 // KSM supply:100 KSM supply reward: 20 // KSM borrow:30 KSM borrow reward: 20 - assert_eq!(almost_equal(LendMarket::reward_accrued(ALICE), unit(100)), true,); + assert_eq!(almost_equal(RewardAccrued::::get(ALICE), unit(100)), true,); _run_to_block(50); assert_ok!(LendMarket::update_market_reward_speed( @@ -1558,15 +1558,15 @@ fn reward_calculation_one_palyer_in_multi_markets_works() { assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), KSM, unit(100))); assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(ALICE), KSM, unit(10))); - let supply_state = LendMarket::reward_supply_state(DOT); + let supply_state = RewardSupplyState::::get(DOT); assert_eq!(supply_state.block, 50); - let borrow_state = LendMarket::reward_borrow_state(DOT); + let borrow_state = RewardBorrowState::::get(DOT); assert_eq!(borrow_state.block, 50); // DOT supply:100 DOT supply reward: 20 // DOT borrow:0 DOT borrow reward: 40 // KSM supply:200 KSM supply reward: 20 // KSM borrow:40 KSM borrow reward: 20 - assert_eq!(almost_equal(LendMarket::reward_accrued(ALICE), unit(100)), true,); + assert_eq!(almost_equal(RewardAccrued::::get(ALICE), unit(100)), true,); _run_to_block(60); assert_ok!(LendMarket::update_market_reward_speed( @@ -1579,15 +1579,15 @@ fn reward_calculation_one_palyer_in_multi_markets_works() { assert_ok!(LendMarket::redeem(RuntimeOrigin::signed(ALICE), KSM, unit(100))); assert_ok!(LendMarket::repay_borrow_all(RuntimeOrigin::signed(ALICE), KSM)); - let supply_state = LendMarket::reward_supply_state(DOT); + let supply_state = RewardSupplyState::::get(DOT); assert_eq!(supply_state.block, 60); - let borrow_state = LendMarket::reward_borrow_state(DOT); + let borrow_state = RewardBorrowState::::get(DOT); assert_eq!(borrow_state.block, 50); // DOT supply:200 DOT supply reward: 30 // DOT borrow:0 DOT borrow reward: 40 // KSM supply:100 KSM supply reward: 20 // KSM borrow:0 KSM borrow reward: 20 - assert_eq!(almost_equal(LendMarket::reward_accrued(ALICE), unit(110)), true,); + assert_eq!(almost_equal(RewardAccrued::::get(ALICE), unit(110)), true,); _run_to_block(70); assert_ok!(LendMarket::update_market_reward_speed( @@ -1605,15 +1605,15 @@ fn reward_calculation_one_palyer_in_multi_markets_works() { assert_ok!(LendMarket::redeem(RuntimeOrigin::signed(ALICE), DOT, unit(100))); assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), KSM, unit(100))); - let supply_state = LendMarket::reward_supply_state(DOT); + let supply_state = RewardSupplyState::::get(DOT); assert_eq!(supply_state.block, 70); - let borrow_state = LendMarket::reward_borrow_state(DOT); + let borrow_state = RewardBorrowState::::get(DOT); assert_eq!(borrow_state.block, 70); // DOT supply:500 DOT supply reward: 40 // DOT borrow:0 DOT borrow reward: 40 // KSM supply:600 KSM supply reward: 30 // KSM borrow:0 KSM borrow reward: 20 - assert_eq!(almost_equal(LendMarket::reward_accrued(ALICE), unit(130)), true); + assert_eq!(almost_equal(RewardAccrued::::get(ALICE), unit(130)), true); _run_to_block(80); assert_ok!(LendMarket::add_reward(RuntimeOrigin::signed(DAVE), unit(200))); @@ -1678,8 +1678,8 @@ fn reward_calculation_multi_player_in_one_market_works() { // Alice borrow:0 borrow reward: 0 // BOB supply:10 supply reward: 0 // BOB borrow:0 borrow reward: 0 - assert_eq!(LendMarket::reward_accrued(ALICE), 0); - assert_eq!(LendMarket::reward_accrued(BOB), 0); + assert_eq!(RewardAccrued::::get(ALICE), 0); + assert_eq!(RewardAccrued::::get(BOB), 0); _run_to_block(20); assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), DOT, unit(70))); @@ -1688,8 +1688,8 @@ fn reward_calculation_multi_player_in_one_market_works() { // Alice borrow:0 borrow reward: 0 // BOB supply:20 supply reward: 5 // BOB borrow:10 borrow reward: 0 - assert_eq!(LendMarket::reward_accrued(ALICE), unit(5)); - assert_eq!(LendMarket::reward_accrued(BOB), unit(5)); + assert_eq!(RewardAccrued::::get(ALICE), unit(5)); + assert_eq!(RewardAccrued::::get(BOB), unit(5)); _run_to_block(30); assert_ok!(LendMarket::redeem(RuntimeOrigin::signed(ALICE), DOT, unit(70))); @@ -1700,8 +1700,8 @@ fn reward_calculation_multi_player_in_one_market_works() { // Alice borrow:1 borrow reward: 0 // BOB supply:10 supply reward: 7 // BOB borrow:1 borrow reward: 0 - assert_eq!(LendMarket::reward_accrued(ALICE), unit(13)); - assert_eq!(LendMarket::reward_accrued(BOB), unit(7)); + assert_eq!(RewardAccrued::::get(ALICE), unit(13)); + assert_eq!(RewardAccrued::::get(BOB), unit(7)); _run_to_block(40); assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), DOT, unit(10))); @@ -1712,8 +1712,8 @@ fn reward_calculation_multi_player_in_one_market_works() { // Alice borrow:2 borrow reward: 5 // BOB supply:20 supply reward: 12 // BOB borrow:0 borrow reward: 5 - assert_eq!(almost_equal(LendMarket::reward_accrued(ALICE), unit(23)), true); - assert_eq!(almost_equal(LendMarket::reward_accrued(BOB), unit(17)), true); + assert_eq!(almost_equal(RewardAccrued::::get(ALICE), unit(23)), true); + assert_eq!(almost_equal(RewardAccrued::::get(BOB), unit(17)), true); _run_to_block(50); assert_ok!(LendMarket::redeem(RuntimeOrigin::signed(ALICE), DOT, unit(10))); @@ -1724,8 +1724,8 @@ fn reward_calculation_multi_player_in_one_market_works() { // Alice borrow:0 borrow reward: 15 // BOB supply:0 supply reward: 17 // BOB borrow:0 borrow reward: 5 - assert_eq!(almost_equal(LendMarket::reward_accrued(ALICE), unit(38)), true); - assert_eq!(almost_equal(LendMarket::reward_accrued(BOB), unit(22)), true); + assert_eq!(almost_equal(RewardAccrued::::get(ALICE), unit(38)), true); + assert_eq!(almost_equal(RewardAccrued::::get(BOB), unit(22)), true); _run_to_block(60); assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), DOT, unit(10))); @@ -1736,8 +1736,8 @@ fn reward_calculation_multi_player_in_one_market_works() { // Alice borrow:0 borrow reward: 15 // BOB supply:0 supply reward: 17 // BOB borrow:0 borrow reward: 5 - assert_eq!(almost_equal(LendMarket::reward_accrued(ALICE), unit(48)), true); - assert_eq!(almost_equal(LendMarket::reward_accrued(BOB), unit(22)), true); + assert_eq!(almost_equal(RewardAccrued::::get(ALICE), unit(48)), true); + assert_eq!(almost_equal(RewardAccrued::::get(BOB), unit(22)), true); _run_to_block(70); assert_ok!(LendMarket::add_reward(RuntimeOrigin::signed(DAVE), unit(200))); @@ -1810,8 +1810,8 @@ fn reward_calculation_after_liquidate_borrow_works() { assert_ok!(LendMarket::distribute_borrower_reward(KSM, &ALICE)); assert_ok!(LendMarket::distribute_borrower_reward(KSM, &BOB)); - assert_eq!(almost_equal(LendMarket::reward_accrued(ALICE), unit(14)), true); - assert_eq!(almost_equal(LendMarket::reward_accrued(BOB), unit(16)), true); + assert_eq!(almost_equal(RewardAccrued::::get(ALICE), unit(14)), true); + assert_eq!(almost_equal(RewardAccrued::::get(BOB), unit(16)), true); MockPriceFeeder::set_price(KSM, 2.into()); // since we set liquidate_threshold more than collateral_factor,with KSM price as 2 alice @@ -1856,11 +1856,11 @@ fn reward_calculation_after_liquidate_borrow_works() { &LendMarket::incentive_reward_account_id().unwrap(), )); - assert_eq!(almost_equal(LendMarket::reward_accrued(ALICE), milli_unit(22375)), true); - assert_eq!(almost_equal(LendMarket::reward_accrued(BOB), micro_unit(37512500)), true); + assert_eq!(almost_equal(RewardAccrued::::get(ALICE), milli_unit(22375)), true); + assert_eq!(almost_equal(RewardAccrued::::get(BOB), micro_unit(37512500)), true); assert_eq!( almost_equal( - LendMarket::reward_accrued(LendMarket::incentive_reward_account_id().unwrap()), + RewardAccrued::::get(LendMarket::incentive_reward_account_id().unwrap()), micro_unit(112500), ), true, diff --git a/pallets/lend-market/src/tests/edge_cases.rs b/pallets/lend-market/src/tests/edge_cases.rs index 5d64d5390..640ff35f9 100644 --- a/pallets/lend-market/src/tests/edge_cases.rs +++ b/pallets/lend-market/src/tests/edge_cases.rs @@ -37,7 +37,7 @@ fn repay_borrow_all_no_underflow() { // FIXME since total_borrows is too small and we accrue internal on it every 100 seconds // accrue_interest fails every time // as you can see the current borrow balance is not equal to total_borrows anymore - assert_eq!(LendMarket::total_borrows(KSM), 10000000); + assert_eq!(TotalBorrows::::get(KSM), 10000000); // Alice repay all borrow balance. total_borrows = total_borrows.saturating_sub(10000005) = // 0. @@ -46,14 +46,14 @@ fn repay_borrow_all_no_underflow() { assert_eq!(::Assets::balance(KSM, &ALICE), unit(800) - 5); assert_eq!( - LendMarket::exchange_rate(DOT) - .saturating_mul_int(LendMarket::account_deposits(KSM, ALICE).voucher_balance), + ExchangeRate::::get(DOT) + .saturating_mul_int(AccountDeposits::::get(KSM, ALICE).voucher_balance), unit(200) ); - let borrow_snapshot = LendMarket::account_borrows(KSM, ALICE); + let borrow_snapshot = AccountBorrows::::get(KSM, ALICE); assert_eq!(borrow_snapshot.principal, 0); - assert_eq!(borrow_snapshot.borrow_index, LendMarket::borrow_index(KSM)); + assert_eq!(borrow_snapshot.borrow_index, BorrowIndex::::get(KSM)); }) } @@ -77,7 +77,7 @@ fn redeem_all_should_be_accurate() { // let exchange_rate greater than 0.02 accrue_interest_per_block(KSM, 6, 2); - assert_eq!(LendMarket::exchange_rate(KSM), Rate::from_inner(20000000036387000)); + assert_eq!(ExchangeRate::::get(KSM), Rate::from_inner(20000000036387000)); assert_ok!(LendMarket::repay_borrow_all(RuntimeOrigin::signed(ALICE), KSM)); // It failed with InsufficientLiquidity before #839 @@ -110,7 +110,7 @@ fn prevent_the_exchange_rate_attack() { 100000000000001 ); assert_eq!( - LendMarket::total_supply(DOT), + TotalSupply::::get(DOT), 1 * 50, // 1 / 0.02 ); TimestampPallet::set_timestamp(12000); diff --git a/pallets/lend-market/src/tests/interest_rate.rs b/pallets/lend-market/src/tests/interest_rate.rs index e3859755d..8bd5a22ba 100644 --- a/pallets/lend-market/src/tests/interest_rate.rs +++ b/pallets/lend-market/src/tests/interest_rate.rs @@ -50,11 +50,11 @@ fn interest_rate_model_works() { let total_cash = million_unit(200) - million_unit(100); let total_supply = - LendMarket::calc_collateral_amount(million_unit(200), LendMarket::exchange_rate(DOT)) + LendMarket::calc_collateral_amount(million_unit(200), ExchangeRate::::get(DOT)) .unwrap(); - assert_eq!(LendMarket::total_supply(DOT), total_supply); + assert_eq!(TotalSupply::::get(DOT), total_supply); - let borrow_snapshot = LendMarket::account_borrows(DOT, ALICE); + let borrow_snapshot = AccountBorrows::::get(DOT, ALICE); assert_eq!(borrow_snapshot.principal, million_unit(100)); assert_eq!(borrow_snapshot.borrow_index, Rate::one()); @@ -74,7 +74,7 @@ fn interest_rate_model_works() { assert_ok!(LendMarket::accrue_interest(DOT)); // utilizationRatio = totalBorrows / (totalCash + totalBorrows) let util_ratio = Ratio::from_rational(total_borrows, total_cash + total_borrows); - assert_eq!(LendMarket::utilization_ratio(DOT), util_ratio); + assert_eq!(UtilizationRatio::::get(DOT), util_ratio); let borrow_rate = (jump_rate - base_rate) * util_ratio.into() / jump_utilization.into() + base_rate; @@ -84,17 +84,17 @@ fn interest_rate_model_works() { .checked_div(SECONDS_PER_YEAR.into()) .unwrap(); total_borrows = interest_accumulated + total_borrows; - assert_eq!(LendMarket::total_borrows(DOT), total_borrows); + assert_eq!(TotalBorrows::::get(DOT), total_borrows); total_reserves = Markets::::get(&DOT) .unwrap() .reserve_factor .mul_floor(interest_accumulated) + total_reserves; - assert_eq!(LendMarket::total_reserves(DOT), total_reserves); + assert_eq!(TotalReserves::::get(DOT), total_reserves); // exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply assert_eq!( - LendMarket::exchange_rate(DOT).into_inner(), + ExchangeRate::::get(DOT).into_inner(), (total_cash + total_borrows - total_reserves) * rate_decimal / total_supply ); let numerator = borrow_index @@ -103,18 +103,18 @@ fn interest_rate_model_works() { .checked_div(&Rate::saturating_from_integer(SECONDS_PER_YEAR)) .unwrap(); borrow_index = numerator + borrow_index; - assert_eq!(LendMarket::borrow_index(DOT), borrow_index); + assert_eq!(BorrowIndex::::get(DOT), borrow_index); } assert_eq!(total_borrows, 100000063926960646826); assert_eq!(total_reserves, 9589044097001); assert_eq!(borrow_index, Rate::from_inner(1000000639269606444)); - assert_eq!(LendMarket::exchange_rate(DOT), Rate::from_inner(20000005433791654)); + assert_eq!(ExchangeRate::::get(DOT), Rate::from_inner(20000005433791654)); // Calculate borrow accrued interest let borrow_principal = (borrow_index / borrow_snapshot.borrow_index) .saturating_mul_int(borrow_snapshot.principal); let supply_interest = - LendMarket::exchange_rate(DOT).saturating_mul_int(total_supply) - million_unit(200); + ExchangeRate::::get(DOT).saturating_mul_int(total_supply) - million_unit(200); assert_eq!(supply_interest, 54337916540000); assert_eq!(borrow_principal, 100000063926960644400); assert_eq!(total_borrows / 10000, borrow_principal / 10000); @@ -143,16 +143,16 @@ fn last_accrued_interest_time_should_be_update_correctly() { BNC, vec![DOT, BNC, KSM, DOT_U, PHA] )); - assert_eq!(LendMarket::borrow_index(DOT), Rate::one()); - assert_eq!(LendMarket::last_accrued_interest_time(DOT), 0); + assert_eq!(BorrowIndex::::get(DOT), Rate::one()); + assert_eq!(LastAccruedInterestTime::::get(DOT), 0); assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), DOT, unit(200))); - assert_eq!(LendMarket::last_accrued_interest_time(DOT), 6); + assert_eq!(LastAccruedInterestTime::::get(DOT), 6); assert_ok!(LendMarket::collateral_asset(RuntimeOrigin::signed(ALICE), DOT, true)); assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(ALICE), DOT, unit(100))); - assert_eq!(LendMarket::borrow_index(DOT), Rate::one()); + assert_eq!(BorrowIndex::::get(DOT), Rate::one()); TimestampPallet::set_timestamp(12000); assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), DOT, unit(100))); - assert_eq!(LendMarket::borrow_index(DOT), Rate::from_inner(1000000013318112633),); + assert_eq!(BorrowIndex::::get(DOT), Rate::from_inner(1000000013318112633),); }) } @@ -177,10 +177,10 @@ fn accrue_interest_works_after_mint() { assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), DOT, unit(200))); assert_ok!(LendMarket::collateral_asset(RuntimeOrigin::signed(ALICE), DOT, true)); assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(ALICE), DOT, unit(100))); - assert_eq!(LendMarket::borrow_index(DOT), Rate::one()); + assert_eq!(BorrowIndex::::get(DOT), Rate::one()); TimestampPallet::set_timestamp(12000); assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), DOT, unit(100))); - assert_eq!(LendMarket::borrow_index(DOT), Rate::from_inner(1000000013318112633),); + assert_eq!(BorrowIndex::::get(DOT), Rate::from_inner(1000000013318112633),); }) } @@ -204,10 +204,10 @@ fn accrue_interest_works_after_borrow() { )); assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), DOT, unit(200))); assert_ok!(LendMarket::collateral_asset(RuntimeOrigin::signed(ALICE), DOT, true)); - assert_eq!(LendMarket::borrow_index(DOT), Rate::one()); + assert_eq!(BorrowIndex::::get(DOT), Rate::one()); TimestampPallet::set_timestamp(12000); assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(ALICE), DOT, unit(100))); - assert_eq!(LendMarket::borrow_index(DOT), Rate::from_inner(1000000003805175038),); + assert_eq!(BorrowIndex::::get(DOT), Rate::from_inner(1000000003805175038),); }) } @@ -232,13 +232,13 @@ fn accrue_interest_works_after_redeem() { assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), DOT, unit(200))); assert_ok!(LendMarket::collateral_asset(RuntimeOrigin::signed(ALICE), DOT, true)); assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(ALICE), DOT, unit(10))); - assert_eq!(LendMarket::borrow_index(DOT), Rate::one()); + assert_eq!(BorrowIndex::::get(DOT), Rate::one()); TimestampPallet::set_timestamp(12000); assert_ok!(LendMarket::redeem(RuntimeOrigin::signed(ALICE), DOT, unit(10))); - assert_eq!(LendMarket::borrow_index(DOT), Rate::from_inner(1000000004756468797),); + assert_eq!(BorrowIndex::::get(DOT), Rate::from_inner(1000000004756468797),); assert_eq!( - LendMarket::exchange_rate(DOT) - .saturating_mul_int(LendMarket::account_deposits(DOT, BOB).voucher_balance), + ExchangeRate::::get(DOT) + .saturating_mul_int(AccountDeposits::::get(DOT, BOB).voucher_balance), 0, ); assert_eq!(::Assets::balance(DOT, &ALICE), 819999999999999); @@ -267,13 +267,13 @@ fn accrue_interest_works_after_redeem_all() { assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), DOT, unit(200))); assert_ok!(LendMarket::collateral_asset(RuntimeOrigin::signed(ALICE), DOT, true)); assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(ALICE), DOT, unit(10))); - assert_eq!(LendMarket::borrow_index(DOT), Rate::one()); + assert_eq!(BorrowIndex::::get(DOT), Rate::one()); TimestampPallet::set_timestamp(12000); assert_ok!(LendMarket::redeem_all(RuntimeOrigin::signed(BOB), DOT)); - assert_eq!(LendMarket::borrow_index(DOT), Rate::from_inner(1000000004669977168),); + assert_eq!(BorrowIndex::::get(DOT), Rate::from_inner(1000000004669977168),); assert_eq!( - LendMarket::exchange_rate(DOT) - .saturating_mul_int(LendMarket::account_deposits(DOT, BOB).voucher_balance), + ExchangeRate::::get(DOT) + .saturating_mul_int(AccountDeposits::::get(DOT, BOB).voucher_balance), 0, ); assert_eq!(::Assets::balance(DOT, &BOB), 1000000000003608); @@ -302,10 +302,10 @@ fn accrue_interest_works_after_repay() { assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), DOT, unit(200))); assert_ok!(LendMarket::collateral_asset(RuntimeOrigin::signed(ALICE), DOT, true)); assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(ALICE), DOT, unit(20))); - assert_eq!(LendMarket::borrow_index(DOT), Rate::one()); + assert_eq!(BorrowIndex::::get(DOT), Rate::one()); TimestampPallet::set_timestamp(12000); assert_ok!(LendMarket::repay_borrow(RuntimeOrigin::signed(ALICE), DOT, unit(10))); - assert_eq!(LendMarket::borrow_index(DOT), Rate::from_inner(1000000005707762557),); + assert_eq!(BorrowIndex::::get(DOT), Rate::from_inner(1000000005707762557),); }) } @@ -331,14 +331,14 @@ fn accrue_interest_works_after_repay_all() { assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), DOT, unit(200))); assert_ok!(LendMarket::collateral_asset(RuntimeOrigin::signed(ALICE), DOT, true)); assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(ALICE), KSM, unit(50))); - assert_eq!(LendMarket::borrow_index(KSM), Rate::one()); + assert_eq!(BorrowIndex::::get(KSM), Rate::one()); TimestampPallet::set_timestamp(12000); assert_ok!(LendMarket::repay_borrow_all(RuntimeOrigin::signed(ALICE), KSM)); - assert_eq!(LendMarket::borrow_index(KSM), Rate::from_inner(1000000008561643835),); + assert_eq!(BorrowIndex::::get(KSM), Rate::from_inner(1000000008561643835),); assert_eq!(::Assets::balance(KSM, &ALICE), 999999999571918); - let borrow_snapshot = LendMarket::account_borrows(KSM, ALICE); + let borrow_snapshot = AccountBorrows::::get(KSM, ALICE); assert_eq!(borrow_snapshot.principal, 0); - assert_eq!(borrow_snapshot.borrow_index, LendMarket::borrow_index(KSM)); + assert_eq!(borrow_snapshot.borrow_index, BorrowIndex::::get(KSM)); }) } @@ -367,8 +367,8 @@ fn accrue_interest_works_after_liquidate_borrow() { // Alice borrows 100 KSM and 50 DOT assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(ALICE), KSM, unit(100))); assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(ALICE), DOT, unit(50))); - assert_eq!(LendMarket::borrow_index(DOT), Rate::one()); - assert_eq!(LendMarket::borrow_index(KSM), Rate::one()); + assert_eq!(BorrowIndex::::get(DOT), Rate::one()); + assert_eq!(BorrowIndex::::get(KSM), Rate::one()); TimestampPallet::set_timestamp(12000); // Adjust KSM price to make shortfall MockPriceFeeder::set_price(KSM, 2.into()); @@ -380,8 +380,8 @@ fn accrue_interest_works_after_liquidate_borrow() { unit(50), DOT )); - assert_eq!(LendMarket::borrow_index(KSM), Rate::from_inner(1000000013318112633),); - assert_eq!(LendMarket::borrow_index(DOT), Rate::from_inner(1000000006976141552),); + assert_eq!(BorrowIndex::::get(KSM), Rate::from_inner(1000000013318112633),); + assert_eq!(BorrowIndex::::get(DOT), Rate::from_inner(1000000006976141552),); }) } @@ -407,13 +407,13 @@ fn different_markets_can_accrue_interest_in_one_block() { assert_ok!(LendMarket::collateral_asset(RuntimeOrigin::signed(ALICE), DOT, true)); assert_ok!(LendMarket::mint(RuntimeOrigin::signed(ALICE), KSM, unit(200))); assert_ok!(LendMarket::collateral_asset(RuntimeOrigin::signed(ALICE), KSM, true)); - assert_eq!(LendMarket::borrow_index(DOT), Rate::one()); - assert_eq!(LendMarket::borrow_index(KSM), Rate::one()); + assert_eq!(BorrowIndex::::get(DOT), Rate::one()); + assert_eq!(BorrowIndex::::get(KSM), Rate::one()); TimestampPallet::set_timestamp(12000); assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(ALICE), DOT, unit(100))); assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(ALICE), KSM, unit(100))); - assert_eq!(LendMarket::borrow_index(DOT), Rate::from_inner(1000000003805175038),); - assert_eq!(LendMarket::borrow_index(KSM), Rate::from_inner(1000000003805175038),); + assert_eq!(BorrowIndex::::get(DOT), Rate::from_inner(1000000003805175038),); + assert_eq!(BorrowIndex::::get(KSM), Rate::from_inner(1000000003805175038),); }) } @@ -439,10 +439,10 @@ fn a_market_can_only_accrue_interest_once_in_a_block() { assert_ok!(LendMarket::collateral_asset(RuntimeOrigin::signed(ALICE), DOT, true)); assert_ok!(LendMarket::mint(RuntimeOrigin::signed(BOB), DOT, unit(200))); assert_ok!(LendMarket::collateral_asset(RuntimeOrigin::signed(BOB), DOT, true)); - assert_eq!(LendMarket::borrow_index(DOT), Rate::one()); + assert_eq!(BorrowIndex::::get(DOT), Rate::one()); TimestampPallet::set_timestamp(12000); assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(ALICE), DOT, unit(100))); assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(BOB), DOT, unit(100))); - assert_eq!(LendMarket::borrow_index(DOT), Rate::from_inner(1000000003805175038),); + assert_eq!(BorrowIndex::::get(DOT), Rate::from_inner(1000000003805175038),); }) } diff --git a/pallets/lend-market/src/tests/lend_tokens.rs b/pallets/lend-market/src/tests/lend_tokens.rs index 036df3b79..f8c33973d 100644 --- a/pallets/lend-market/src/tests/lend_tokens.rs +++ b/pallets/lend-market/src/tests/lend_tokens.rs @@ -55,8 +55,8 @@ fn trait_inspect_methods_works() { assert_ok!(LendMarket::borrow(RuntimeOrigin::signed(DAVE), BNC, unit(25))); assert_eq!( - LendMarket::exchange_rate(BNC) - .saturating_mul_int(LendMarket::account_deposits(BNC, DAVE).voucher_balance), + ExchangeRate::::get(BNC) + .saturating_mul_int(AccountDeposits::::get(BNC, DAVE).voucher_balance), unit(100) ); @@ -156,15 +156,15 @@ fn transfer_lend_token_works() { // DAVE BNC collateral: deposit = 100 // BNC: cash - deposit = 1000 - 100 = 900 assert_eq!( - LendMarket::exchange_rate(BNC) - .saturating_mul_int(LendMarket::account_deposits(BNC, DAVE).voucher_balance), + ExchangeRate::::get(BNC) + .saturating_mul_int(AccountDeposits::::get(BNC, DAVE).voucher_balance), unit(100) ); // ALICE BNC collateral: deposit = 0 assert_eq!( - LendMarket::exchange_rate(BNC) - .saturating_mul_int(LendMarket::account_deposits(BNC, ALICE).voucher_balance), + ExchangeRate::::get(BNC) + .saturating_mul_int(AccountDeposits::::get(BNC, ALICE).voucher_balance), unit(0) ); @@ -173,8 +173,8 @@ fn transfer_lend_token_works() { // DAVE BNC collateral: deposit = 50 assert_eq!( - LendMarket::exchange_rate(BNC) - .saturating_mul_int(LendMarket::account_deposits(BNC, DAVE).voucher_balance), + ExchangeRate::::get(BNC) + .saturating_mul_int(AccountDeposits::::get(BNC, DAVE).voucher_balance), unit(50) ); // DAVE Redeem 51 BNC should cause InsufficientDeposit @@ -185,8 +185,8 @@ fn transfer_lend_token_works() { // ALICE BNC collateral: deposit = 50 assert_eq!( - LendMarket::exchange_rate(BNC) - .saturating_mul_int(LendMarket::account_deposits(BNC, ALICE).voucher_balance), + ExchangeRate::::get(BNC) + .saturating_mul_int(AccountDeposits::::get(BNC, ALICE).voucher_balance), unit(50) ); // ALICE Redeem 50 BNC should be succeeded @@ -227,8 +227,8 @@ fn transfer_lend_tokens_under_collateral_works() { // DAVE Borrow BNC = 0 + 50 - 40 = 10 // DAVE liquidity BNC = 80 * 0.5 - 10 = 30 assert_eq!( - LendMarket::exchange_rate(BNC) - .saturating_mul_int(LendMarket::account_deposits(BNC, DAVE).voucher_balance), + ExchangeRate::::get(BNC) + .saturating_mul_int(AccountDeposits::::get(BNC, DAVE).voucher_balance), unit(80) ); // DAVE Borrow 31 BNC should cause InsufficientLiquidity @@ -240,8 +240,8 @@ fn transfer_lend_tokens_under_collateral_works() { // Assert ALICE Supply BNC 20 assert_eq!( - LendMarket::exchange_rate(BNC) - .saturating_mul_int(LendMarket::account_deposits(BNC, ALICE).voucher_balance), + ExchangeRate::::get(BNC) + .saturating_mul_int(AccountDeposits::::get(BNC, ALICE).voucher_balance), unit(20) ); // ALICE Redeem 20 BNC should be succeeded diff --git a/pallets/lend-market/src/tests/liquidate_borrow.rs b/pallets/lend-market/src/tests/liquidate_borrow.rs index 13a87c561..9e04e4a1e 100644 --- a/pallets/lend-market/src/tests/liquidate_borrow.rs +++ b/pallets/lend-market/src/tests/liquidate_borrow.rs @@ -176,24 +176,24 @@ fn full_workflow_works_as_expected() { // Bob DOT collateral: incentive = 110-(110/1.1*0.03)=107 assert_eq!(::Assets::balance(DOT_U, &ALICE), unit(800),); assert_eq!( - LendMarket::exchange_rate(DOT_U) - .saturating_mul_int(LendMarket::account_deposits(DOT_U, ALICE).voucher_balance), + ExchangeRate::::get(DOT_U) + .saturating_mul_int(AccountDeposits::::get(DOT_U, ALICE).voucher_balance), unit(90), ); assert_eq!(::Assets::balance(KSM, &ALICE), unit(1100),); - assert_eq!(LendMarket::account_borrows(KSM, ALICE).principal, unit(50)); + assert_eq!(AccountBorrows::::get(KSM, ALICE).principal, unit(50)); assert_eq!(::Assets::balance(KSM, &BOB), unit(750)); assert_eq!( - LendMarket::exchange_rate(DOT_U) - .saturating_mul_int(LendMarket::account_deposits(DOT_U, BOB).voucher_balance), + ExchangeRate::::get(DOT_U) + .saturating_mul_int(AccountDeposits::::get(DOT_U, BOB).voucher_balance), unit(107), ); // 3 dollar reserved in our incentive reward account let incentive_reward_account = LendMarket::incentive_reward_account_id().unwrap(); println!("incentive reserve account:{:?}", incentive_reward_account.clone()); assert_eq!( - LendMarket::exchange_rate(DOT_U).saturating_mul_int( - LendMarket::account_deposits(DOT_U, incentive_reward_account.clone()) + ExchangeRate::::get(DOT_U).saturating_mul_int( + AccountDeposits::::get(DOT_U, incentive_reward_account.clone()) .voucher_balance ), unit(3), @@ -208,8 +208,8 @@ fn full_workflow_works_as_expected() { )); // still 1 dollar left in reserve account assert_eq!( - LendMarket::exchange_rate(DOT_U).saturating_mul_int( - LendMarket::account_deposits(DOT_U, incentive_reward_account).voucher_balance + ExchangeRate::::get(DOT_U).saturating_mul_int( + AccountDeposits::::get(DOT_U, incentive_reward_account).voucher_balance ), unit(1), ); diff --git a/pallets/leverage-staking/src/lib.rs b/pallets/leverage-staking/src/lib.rs index 7bff552a3..620718454 100644 --- a/pallets/leverage-staking/src/lib.rs +++ b/pallets/leverage-staking/src/lib.rs @@ -249,7 +249,7 @@ impl Pallet { if !AccountDeposits::::contains_key(asset_id, supplier) { return Ok(BalanceOf::::zero()); } - let deposits = lend_market::Pallet::::account_deposits(asset_id, supplier); + let deposits = AccountDeposits::::get(asset_id, supplier); if deposits.voucher_balance.is_zero() { return Ok(BalanceOf::::zero()); } diff --git a/pallets/leverage-staking/src/mock.rs b/pallets/leverage-staking/src/mock.rs index 55096d593..a4c8fd0d5 100644 --- a/pallets/leverage-staking/src/mock.rs +++ b/pallets/leverage-staking/src/mock.rs @@ -20,8 +20,9 @@ pub use super::*; use crate as leverage_staking; use bifrost_asset_registry::AssetIdMaps; pub use bifrost_primitives::{ - currency::*, Balance, CurrencyId, CurrencyIdMapping, SlpOperator, SlpxOperator, TokenSymbol, *, + currency::*, Balance, CurrencyId, CurrencyIdMapping, SlpOperator, SlpxOperator, TokenSymbol, }; +use bifrost_primitives::{Moment, MoonbeamChainId, Price, PriceDetail, Ratio}; use bifrost_runtime_common::milli; use frame_support::{ derive_impl, ord_parameter_types, parameter_types, @@ -311,16 +312,12 @@ impl bifrost_vtoken_minting::Config for Test { type WeightInfo = (); type OnRedeemSuccess = (); type XcmTransfer = XTokens; - type AstarParachainId = ConstU32<2007>; - type MoonbeamParachainId = ConstU32<2023>; + type MoonbeamChainId = MoonbeamChainId; type BifrostSlpx = SlpxInterface; - type HydradxParachainId = ConstU32<2034>; - type MantaParachainId = ConstU32<2104>; - type InterlayParachainId = ConstU32<2032>; type ChannelCommission = (); type MaxLockRecords = ConstU32<100>; type IncentivePoolAccount = IncentivePoolAccount; - type VeMinting = (); + type BbBNC = (); type AssetIdMaps = AssetIdMaps; } diff --git a/pallets/parachain-staking/src/benchmarks.rs b/pallets/parachain-staking/src/benchmarks.rs index cffff55a1..e5acf2635 100644 --- a/pallets/parachain-staking/src/benchmarks.rs +++ b/pallets/parachain-staking/src/benchmarks.rs @@ -24,8 +24,9 @@ use sp_runtime::{Perbill, Percent}; use sp_std::{collections::btree_map::BTreeMap, vec, vec::Vec}; use crate::{ - AccountIdOf, BalanceOf, Call, CandidateBondLessRequest, Config, DelegationAction, Pallet, - Range, ScheduledRequest, + AccountIdOf, BalanceOf, Call, CandidateBondLessRequest, CandidateInfo, CollatorCommission, + Config, DelegationAction, DelegationScheduledRequests, DelegatorState, InflationConfig, Pallet, + ParachainBondInfo, Range, Round, ScheduledRequest, TotalSelected, }; /// Minimum collator candidate stake @@ -92,9 +93,9 @@ fn create_funded_collator( /// Run to end block and author fn roll_to_and_author(round_delay: u32, author: AccountIdOf) { let total_rounds = round_delay + 1u32; - let round_length: BlockNumberFor = Pallet::::round().length.into(); + let round_length: BlockNumberFor = Round::::get().length.into(); let mut now = >::block_number() + 1u32.into(); - let end = Pallet::::round().first + (round_length * total_rounds.into()); + let end = Round::::get().first + (round_length * total_rounds.into()); while now < end { Pallet::::note_author(author.clone()); >::on_finalize(>::block_number()); @@ -119,7 +120,7 @@ benchmarks! { }; }: _(RawOrigin::Root, stake_range) verify { - assert_eq!(Pallet::::inflation_config().expect, stake_range); + assert_eq!(InflationConfig::::get().expect, stake_range); } set_inflation { @@ -131,20 +132,20 @@ benchmarks! { }: _(RawOrigin::Root, inflation_range) verify { - assert_eq!(Pallet::::inflation_config().annual, inflation_range); + assert_eq!(InflationConfig::::get().annual, inflation_range); } set_parachain_bond_account { let parachain_bond_account: AccountIdOf = account("TEST", 0u32, USER_SEED); }: _(RawOrigin::Root, parachain_bond_account.clone()) verify { - assert_eq!(Pallet::::parachain_bond_info().account, parachain_bond_account); + assert_eq!(ParachainBondInfo::::get().account, parachain_bond_account); } set_parachain_bond_reserve_percent { }: _(RawOrigin::Root, Percent::from_percent(33)) verify { - assert_eq!(Pallet::::parachain_bond_info().percent, Percent::from_percent(33)); + assert_eq!(ParachainBondInfo::::get().percent, Percent::from_percent(33)); } // ROOT DISPATCHABLES @@ -153,17 +154,17 @@ benchmarks! { Pallet::::set_blocks_per_round(RawOrigin::Root.into(), 100u32)?; }: _(RawOrigin::Root, 100u32) verify { - assert_eq!(Pallet::::total_selected(), 100u32); + assert_eq!(TotalSelected::::get(), 100u32); } set_collator_commission {}: _(RawOrigin::Root, Perbill::from_percent(33)) verify { - assert_eq!(Pallet::::collator_commission(), Perbill::from_percent(33)); + assert_eq!(CollatorCommission::::get(), Perbill::from_percent(33)); } set_blocks_per_round {}: _(RawOrigin::Root, 1200u32) verify { - assert_eq!(Pallet::::round().length, 1200u32); + assert_eq!(Round::::get().length, 1200u32); } // USER DISPATCHABLES @@ -216,7 +217,7 @@ benchmarks! { candidate_count += 1u32; }: _(RawOrigin::Signed(caller.clone()), candidate_count) verify { - assert!(Pallet::::candidate_info(&caller).unwrap().is_leaving()); + assert!(CandidateInfo::::get(&caller).unwrap().is_leaving()); } execute_leave_candidates { @@ -271,8 +272,8 @@ benchmarks! { roll_to_and_author::(2, candidate.clone()); }: _(RawOrigin::Signed(candidate.clone()), candidate.clone(), col_del_count) verify { - assert!(Pallet::::candidate_info(&candidate).is_none()); - assert!(Pallet::::candidate_info(&second_candidate).is_some()); + assert!(CandidateInfo::::get(&candidate).is_none()); + assert!(CandidateInfo::::get(&second_candidate).is_some()); for delegator in delegators { assert!(Pallet::::is_delegator(&delegator)); } @@ -308,7 +309,7 @@ benchmarks! { candidate_count -= 1u32; }: _(RawOrigin::Signed(caller.clone()), candidate_count) verify { - assert!(Pallet::::candidate_info(&caller).unwrap().is_active()); + assert!(CandidateInfo::::get(&caller).unwrap().is_active()); } go_offline { @@ -321,7 +322,7 @@ benchmarks! { )?; }: _(RawOrigin::Signed(caller.clone())) verify { - assert!(!Pallet::::candidate_info(&caller).unwrap().is_active()); + assert!(!CandidateInfo::::get(&caller).unwrap().is_active()); } go_online { @@ -335,7 +336,7 @@ benchmarks! { Pallet::::go_offline(RawOrigin::Signed(caller.clone()).into())?; }: _(RawOrigin::Signed(caller.clone())) verify { - assert!(Pallet::::candidate_info(&caller).unwrap().is_active()); + assert!(CandidateInfo::::get(&caller).unwrap().is_active()); } candidate_bond_more { @@ -364,7 +365,7 @@ benchmarks! { )?; }: _(RawOrigin::Signed(caller.clone()), min_candidate_stk) verify { - let state = Pallet::::candidate_info(&caller).expect("request bonded less so exists"); + let state = CandidateInfo::::get(&caller).expect("request bonded less so exists"); assert_eq!( state.request, Some(CandidateBondLessRequest { @@ -416,7 +417,7 @@ benchmarks! { )?; } verify { assert!( - Pallet::::candidate_info(&caller).unwrap().request.is_none() + CandidateInfo::::get(&caller).unwrap().request.is_none() ); } @@ -500,7 +501,7 @@ benchmarks! { }: _(RawOrigin::Signed(caller.clone())) verify { assert!( - Pallet::::delegation_scheduled_requests(&collator) + DelegationScheduledRequests::::get(&collator) .iter() .any(|r| r.delegator == caller && matches!(r.action, DelegationAction::Revoke(_))) ); @@ -550,7 +551,7 @@ benchmarks! { roll_to_and_author::(2, author); }: _(RawOrigin::Signed(caller.clone()), caller.clone(), delegation_count) verify { - assert!(Pallet::::delegator_state(&caller).is_none()); + assert!(DelegatorState::::get(&caller).is_none()); } cancel_leave_delegators { @@ -573,7 +574,7 @@ benchmarks! { Pallet::::schedule_leave_delegators(RawOrigin::Signed(caller.clone()).into())?; }: _(RawOrigin::Signed(caller.clone())) verify { - assert!(Pallet::::delegator_state(&caller).unwrap().is_active()); + assert!(DelegatorState::::get(&caller).unwrap().is_active()); } schedule_revoke_delegation { @@ -596,7 +597,7 @@ benchmarks! { }: _(RawOrigin::Signed(caller.clone()), collator.clone()) verify { assert_eq!( - Pallet::::delegation_scheduled_requests(&collator), + DelegationScheduledRequests::::get(&collator), vec![ScheduledRequest { delegator: caller, when_executable: 3, @@ -647,10 +648,10 @@ benchmarks! { let bond_less = <::MinDelegatorStk as Get>>::get(); }: _(RawOrigin::Signed(caller.clone()), collator.clone(), bond_less) verify { - let state = Pallet::::delegator_state(&caller) + let state = DelegatorState::::get(&caller) .expect("just request bonded less so exists"); assert_eq!( - Pallet::::delegation_scheduled_requests(&collator), + DelegationScheduledRequests::::get(&collator), vec![ScheduledRequest { delegator: caller, when_executable: 3, @@ -755,7 +756,7 @@ benchmarks! { )?; } verify { assert!( - !Pallet::::delegation_scheduled_requests(&collator) + !DelegationScheduledRequests::::get(&collator) .iter() .any(|x| &x.delegator == &caller) ); @@ -791,7 +792,7 @@ benchmarks! { )?; } verify { assert!( - !Pallet::::delegation_scheduled_requests(&collator) + !DelegationScheduledRequests::::get(&collator) .iter() .any(|x| x.delegator == caller) ); @@ -908,12 +909,12 @@ benchmarks! { <::Currency as Currency>>::Balance )> = delegators.iter().map(|x| (x.clone(), T::Currency::free_balance(x))).collect(); // PREPARE RUN_TO_BLOCK LOOP - let before_running_round_index = Pallet::::round().current; - let round_length: BlockNumberFor = Pallet::::round().length.into(); + let before_running_round_index = Round::::get().current; + let round_length: BlockNumberFor = Round::::get().length.into(); let reward_delay = <::RewardPaymentDelay as Get>::get() + 2u32; let mut now = >::block_number() + 1u32.into(); let mut counter = 0usize; - let end = Pallet::::round().first + (round_length * reward_delay.into()); + let end = Round::::get().first + (round_length * reward_delay.into()); // SET collators as authors for blocks from now - end while now < end { let author = collators[counter % collators.len()].clone(); @@ -944,7 +945,7 @@ benchmarks! { assert!(T::Currency::free_balance(&col) > initial); } // Round transitions - assert_eq!(Pallet::::round().current, before_running_round_index + reward_delay); + assert_eq!(Round::::get().current, before_running_round_index + reward_delay); } pay_one_collator_reward { @@ -957,7 +958,7 @@ benchmarks! { AwardedPts, }; - let before_running_round_index = Pallet::::round().current; + let before_running_round_index = Round::::get().current; let initial_stake_amount = min_candidate_stk::() * 1_000_000u32.into(); let mut total_staked = 0u32.into(); @@ -1019,7 +1020,7 @@ benchmarks! { }: { let round_for_payout = 5; // TODO: this is an extra read right here (we should whitelist it?) - let payout_info = Pallet::::delayed_payouts(round_for_payout).expect("payout expected"); + let payout_info = DelayedPayouts::::get(round_for_payout).expect("payout expected"); let result = Pallet::::pay_one_collator_reward(round_for_payout, payout_info); assert!(result.0.is_some()); // TODO: how to keep this in scope so it can be done in verify block? } diff --git a/pallets/parachain-staking/src/inflation.rs b/pallets/parachain-staking/src/inflation.rs index 591062b6e..53c2a465a 100644 --- a/pallets/parachain-staking/src/inflation.rs +++ b/pallets/parachain-staking/src/inflation.rs @@ -25,14 +25,17 @@ use substrate_fixed::{ types::{I32F32, I64F64}, }; -use crate::pallet::{BalanceOf, Config, Pallet}; +use crate::{ + pallet::{BalanceOf, Config}, + Round, +}; const SECONDS_PER_YEAR: u32 = 31557600; const SECONDS_PER_BLOCK: u32 = 12; pub const BLOCKS_PER_YEAR: u32 = SECONDS_PER_YEAR / SECONDS_PER_BLOCK; fn rounds_per_year() -> u32 { - let blocks_per_round = >::round().length; + let blocks_per_round = Round::::get().length; BLOCKS_PER_YEAR / blocks_per_round } diff --git a/pallets/parachain-staking/src/lib.rs b/pallets/parachain-staking/src/lib.rs index aaa077312..3504f24f7 100755 --- a/pallets/parachain-staking/src/lib.rs +++ b/pallets/parachain-staking/src/lib.rs @@ -465,28 +465,23 @@ pub mod pallet { } #[pallet::storage] - #[pallet::getter(fn collator_commission)] /// Commission percent taken off of rewards for all collators pub(crate) type CollatorCommission = StorageValue<_, Perbill, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn total_selected)] /// The total candidates selected every round pub(crate) type TotalSelected = StorageValue<_, u32, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn parachain_bond_info)] /// Parachain bond config info { account, percent_of_inflation } pub(crate) type ParachainBondInfo = StorageValue<_, ParachainBondConfig, BalanceOf>, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn round)] /// Current round index and next round scheduled transition pub type Round = StorageValue<_, RoundInfo>, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn delegator_state)] /// Get delegator state associated with an account if account is delegating else None pub(crate) type DelegatorState = StorageMap< _, @@ -497,7 +492,6 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn candidate_info)] /// Get collator candidate info associated with an account if account is candidate else None pub(crate) type CandidateInfo = StorageMap<_, Twox64Concat, AccountIdOf, CandidateMetadata>, OptionQuery>; @@ -514,7 +508,6 @@ pub mod pallet { /// Stores outstanding delegation requests per collator. #[pallet::storage] - #[pallet::getter(fn delegation_scheduled_requests)] pub(crate) type DelegationScheduledRequests = StorageMap< _, Blake2_128Concat, @@ -524,7 +517,6 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn top_delegations)] /// Top delegations for collator candidate pub(crate) type TopDelegations = StorageMap< _, @@ -535,7 +527,6 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn bottom_delegations)] /// Bottom delegations for collator candidate pub(crate) type BottomDelegations = StorageMap< _, @@ -546,23 +537,19 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn selected_candidates)] /// The collator candidates selected for the current round - type SelectedCandidates = StorageValue<_, Vec>, ValueQuery>; + pub type SelectedCandidates = StorageValue<_, Vec>, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn total)] /// Total capital locked by this staking pallet pub(crate) type Total = StorageValue<_, BalanceOf, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn candidate_pool)] /// The pool of collator candidates, each with their total backing stake pub(crate) type CandidatePool = StorageValue<_, OrderedSet, BalanceOf>>, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn at_stake)] /// Snapshot of collator delegation stake at the start of the round pub type AtStake = StorageDoubleMap< _, @@ -575,28 +562,23 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn delayed_payouts)] /// Delayed payouts pub type DelayedPayouts = StorageMap<_, Twox64Concat, RoundIndex, DelayedPayout>, OptionQuery>; #[pallet::storage] - #[pallet::getter(fn staked)] /// Total counted stake for selected candidates in the round pub type Staked = StorageMap<_, Twox64Concat, RoundIndex, BalanceOf, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn inflation_config)] /// Inflation configuration pub type InflationConfig = StorageValue<_, InflationInfo>, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn points)] /// Total points awarded to collators for block production in the round pub type Points = StorageMap<_, Twox64Concat, RoundIndex, RewardPoint, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn awarded_pts)] /// Points for each collator per round pub type AwardedPts = StorageDoubleMap< _, @@ -1865,7 +1847,7 @@ pub mod pallet { impl Get>> for Pallet { fn get() -> Vec> { - Self::selected_candidates() + SelectedCandidates::::get() } } @@ -1893,7 +1875,7 @@ pub mod pallet { >::block_number(), ); - let collators = Pallet::::selected_candidates().to_vec(); + let collators = SelectedCandidates::::get().to_vec(); if collators.is_empty() { // we never want to pass an empty set of collators. This would brick the chain. log::error!("💥 keeping old session because of empty collator set!"); diff --git a/pallets/parachain-staking/src/migrations.rs b/pallets/parachain-staking/src/migrations.rs index 971a035e0..21d43b070 100644 --- a/pallets/parachain-staking/src/migrations.rs +++ b/pallets/parachain-staking/src/migrations.rs @@ -307,10 +307,9 @@ impl OnRuntimeUpgrade for SplitDelegatorStateIntoDelegationScheduledR // Scheduled decrease amount (bond_less) is correctly migrated let mut actual_delegator_state_entries = 0; for (delegator, state) in >::iter() { - let expected_delegator_decrease_amount: BalanceOf = delegator_state_map + let expected_delegator_decrease_amount: BalanceOf = *delegator_state_map .get(&(&*format!("expected_delegator-{:?}_decrease_amount", state.id)).to_string()) - .expect("must exist") - .clone(); + .expect("must exist"); assert_eq!( expected_delegator_decrease_amount, state.less_total, "decrease amount did not match for delegator {:?}", @@ -443,10 +442,9 @@ impl OnRuntimeUpgrade for PatchIncorrectDelegationSums { Decode::decode(&mut &state[..]).expect("pre_upgrade provides a valid state; qed"); // ensure new total counted = top_delegations.sum() + collator self bond for (account, state) in >::iter() { - let old_count = candidate_total_counted_map + let old_count = *candidate_total_counted_map .get(&(&format!("Candidate{:?}TotalCounted", account)[..]).to_string()) - .expect("qed") - .clone(); + .expect("qed"); let new_count = state.total_counted; let top_delegations_sum = >::get(account) .expect("CandidateInfo exists => TopDelegations exists") diff --git a/pallets/parachain-staking/src/tests.rs b/pallets/parachain-staking/src/tests.rs index 0fdb75254..0ed9682ff 100644 --- a/pallets/parachain-staking/src/tests.rs +++ b/pallets/parachain-staking/src/tests.rs @@ -36,9 +36,11 @@ use crate::{ ExtBuilder, ParachainStaking, RuntimeEvent as MetaEvent, RuntimeOrigin, Test, }, set::OrderedSet, - AtStake, Bond, BottomDelegations, CandidateInfo, CandidateMetadata, CandidatePool, - CapacityStatus, CollatorStatus, DelegationScheduledRequests, Delegations, DelegatorAdded, - DelegatorState, DelegatorStatus, Error, Event, Range, TopDelegations, DELEGATOR_LOCK_ID, + AtStake, AwardedPts, Bond, BottomDelegations, CandidateInfo, CandidateMetadata, CandidatePool, + CapacityStatus, CollatorCommission, CollatorStatus, DelegationScheduledRequests, Delegations, + DelegatorAdded, DelegatorState, DelegatorStatus, Error, Event, InflationConfig, + ParachainBondInfo, Range, Round, SelectedCandidates, TopDelegations, Total, TotalSelected, + DELEGATOR_LOCK_ID, }; // ~~ ROOT ~~ @@ -82,7 +84,7 @@ fn set_total_selected_event_emits_correctly() { #[test] fn set_total_selected_fails_if_above_blocks_per_round() { ExtBuilder::default().build().execute_with(|| { - assert_eq!(ParachainStaking::round().length, 5); // test relies on this + assert_eq!(Round::::get().length, 5); // test relies on this assert_noop!( ParachainStaking::set_total_selected(RuntimeOrigin::root(), 6u32), Error::::RoundLengthMustBeAtLeastTotalSelectedCollators, @@ -130,7 +132,7 @@ fn set_blocks_per_round_passes_if_equal_to_total_selected() { #[test] fn set_blocks_per_round_passes_if_above_total_selected() { ExtBuilder::default().build().execute_with(|| { - assert_eq!(ParachainStaking::round().length, 5); // test relies on this + assert_eq!(Round::::get().length, 5); // test relies on this assert_ok!(ParachainStaking::set_blocks_per_round(RuntimeOrigin::root(), 6u32)); }); } @@ -141,9 +143,9 @@ fn set_total_selected_storage_updates_correctly() { // round length must be >= total_selected, so update that first assert_ok!(ParachainStaking::set_blocks_per_round(RuntimeOrigin::root(), 10u32)); - assert_eq!(ParachainStaking::total_selected(), 5u32); + assert_eq!(TotalSelected::::get(), 5u32); assert_ok!(ParachainStaking::set_total_selected(RuntimeOrigin::root(), 6u32)); - assert_eq!(ParachainStaking::total_selected(), 6u32); + assert_eq!(TotalSelected::::get(), 6u32); }); } @@ -186,12 +188,12 @@ fn set_collator_commission_event_emits_correctly() { #[test] fn set_collator_commission_storage_updates_correctly() { ExtBuilder::default().build().execute_with(|| { - assert_eq!(ParachainStaking::collator_commission(), Perbill::from_percent(20)); + assert_eq!(CollatorCommission::::get(), Perbill::from_percent(20)); assert_ok!(ParachainStaking::set_collator_commission( RuntimeOrigin::root(), Perbill::from_percent(5) )); - assert_eq!(ParachainStaking::collator_commission(), Perbill::from_percent(5)); + assert_eq!(CollatorCommission::::get(), Perbill::from_percent(5)); }); } @@ -229,9 +231,9 @@ fn set_blocks_per_round_event_emits_correctly() { #[test] fn set_blocks_per_round_storage_updates_correctly() { ExtBuilder::default().build().execute_with(|| { - assert_eq!(ParachainStaking::round().length, 5); + assert_eq!(Round::::get().length, 5); assert_ok!(ParachainStaking::set_blocks_per_round(RuntimeOrigin::root(), 6u32)); - assert_eq!(ParachainStaking::round().length, 6); + assert_eq!(Round::::get().length, 6); }); } @@ -354,16 +356,13 @@ fn set_staking_event_emits_event_correctly() { #[test] fn set_staking_updates_storage_correctly() { ExtBuilder::default().build().execute_with(|| { - assert_eq!( - ParachainStaking::inflation_config().expect, - Range { min: 700, ideal: 700, max: 700 } - ); + assert_eq!(InflationConfig::::get().expect, Range { min: 700, ideal: 700, max: 700 }); assert_ok!(ParachainStaking::set_staking_expectations( RuntimeOrigin::root(), Range { min: 3u128, ideal: 4u128, max: 5u128 } )); assert_eq!( - ParachainStaking::inflation_config().expect, + InflationConfig::::get().expect, Range { min: 3u128, ideal: 4u128, max: 5u128 } ); }); @@ -428,7 +427,7 @@ fn set_inflation_storage_updates_correctly() { let (min, ideal, max): (Perbill, Perbill, Perbill) = (Perbill::from_percent(3), Perbill::from_percent(4), Perbill::from_percent(5)); assert_eq!( - ParachainStaking::inflation_config().annual, + InflationConfig::::get().annual, Range { min: Perbill::from_percent(50), ideal: Perbill::from_percent(50), @@ -436,7 +435,7 @@ fn set_inflation_storage_updates_correctly() { } ); assert_eq!( - ParachainStaking::inflation_config().round, + InflationConfig::::get().round, Range { min: Perbill::from_percent(5), ideal: Perbill::from_percent(5), @@ -447,9 +446,9 @@ fn set_inflation_storage_updates_correctly() { RuntimeOrigin::root(), Range { min, ideal, max } ),); - assert_eq!(ParachainStaking::inflation_config().annual, Range { min, ideal, max }); + assert_eq!(InflationConfig::::get().annual, Range { min, ideal, max }); assert_eq!( - ParachainStaking::inflation_config().round, + InflationConfig::::get().round, Range { min: Perbill::from_parts(57), ideal: Perbill::from_parts(75), @@ -508,9 +507,9 @@ fn set_parachain_bond_account_event_emits_correctly() { #[test] fn set_parachain_bond_account_storage_updates_correctly() { ExtBuilder::default().build().execute_with(|| { - assert_eq!(ParachainStaking::parachain_bond_info().account, 0); + assert_eq!(ParachainBondInfo::::get().account, 0); assert_ok!(ParachainStaking::set_parachain_bond_account(RuntimeOrigin::root(), 11)); - assert_eq!(ParachainStaking::parachain_bond_info().account, 11); + assert_eq!(ParachainBondInfo::::get().account, 11); }); } @@ -533,12 +532,12 @@ fn set_parachain_bond_reserve_percent_event_emits_correctly() { #[test] fn set_parachain_bond_reserve_percent_storage_updates_correctly() { ExtBuilder::default().build().execute_with(|| { - assert_eq!(ParachainStaking::parachain_bond_info().percent, Percent::from_percent(30)); + assert_eq!(ParachainBondInfo::::get().percent, Percent::from_percent(30)); assert_ok!(ParachainStaking::set_parachain_bond_reserve_percent( RuntimeOrigin::root(), Percent::from_percent(50) )); - assert_eq!(ParachainStaking::parachain_bond_info().percent, Percent::from_percent(50)); + assert_eq!(ParachainBondInfo::::get().percent, Percent::from_percent(50)); }); } @@ -583,18 +582,18 @@ fn join_candidates_reserves_balance() { #[test] fn join_candidates_increases_total_staked() { ExtBuilder::default().with_balances(vec![(1, 10)]).build().execute_with(|| { - assert_eq!(ParachainStaking::total(), 0); + assert_eq!(Total::::get(), 0); assert_ok!(ParachainStaking::join_candidates(RuntimeOrigin::signed(1), 10u128, 0u32)); - assert_eq!(ParachainStaking::total(), 10); + assert_eq!(Total::::get(), 10); }); } #[test] fn join_candidates_creates_candidate_state() { ExtBuilder::default().with_balances(vec![(1, 10)]).build().execute_with(|| { - assert!(ParachainStaking::candidate_info(1).is_none()); + assert!(CandidateInfo::::get(1).is_none()); assert_ok!(ParachainStaking::join_candidates(RuntimeOrigin::signed(1), 10u128, 0u32)); - let candidate_state = ParachainStaking::candidate_info(1).expect("just joined => exists"); + let candidate_state = CandidateInfo::::get(1).expect("just joined => exists"); assert_eq!(candidate_state.bond, 10u128); }); } @@ -602,9 +601,9 @@ fn join_candidates_creates_candidate_state() { #[test] fn join_candidates_adds_to_candidate_pool() { ExtBuilder::default().with_balances(vec![(1, 10)]).build().execute_with(|| { - assert!(ParachainStaking::candidate_pool().0.is_empty()); + assert!(CandidatePool::::get().0.is_empty()); assert_ok!(ParachainStaking::join_candidates(RuntimeOrigin::signed(1), 10u128, 0u32)); - let candidate_pool = ParachainStaking::candidate_pool(); + let candidate_pool = CandidatePool::::get(); assert_eq!(candidate_pool.0[0].owner, 1); assert_eq!(candidate_pool.0[0].amount, 10); }); @@ -729,9 +728,9 @@ fn leave_candidates_removes_candidate_from_candidate_pool() { .with_candidates(vec![(1, 10)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::candidate_pool().0.len(), 1); + assert_eq!(CandidatePool::::get().0.len(), 1); assert_ok!(ParachainStaking::schedule_leave_candidates(RuntimeOrigin::signed(1), 1u32)); - assert!(ParachainStaking::candidate_pool().0.is_empty()); + assert!(CandidatePool::::get().0.is_empty()); }); } @@ -869,11 +868,11 @@ fn execute_leave_candidates_decreases_total_staked() { .with_candidates(vec![(1, 10)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::total(), 10); + assert_eq!(Total::::get(), 10); assert_ok!(ParachainStaking::schedule_leave_candidates(RuntimeOrigin::signed(1), 1u32)); roll_to(10); assert_ok!(ParachainStaking::execute_leave_candidates(RuntimeOrigin::signed(1), 1, 0)); - assert_eq!(ParachainStaking::total(), 0); + assert_eq!(Total::::get(), 0); }); } @@ -886,12 +885,11 @@ fn execute_leave_candidates_removes_candidate_state() { .execute_with(|| { assert_ok!(ParachainStaking::schedule_leave_candidates(RuntimeOrigin::signed(1), 1u32)); // candidate state is not immediately removed - let candidate_state = - ParachainStaking::candidate_info(1).expect("just left => still exists"); + let candidate_state = CandidateInfo::::get(1).expect("just left => still exists"); assert_eq!(candidate_state.bond, 10u128); roll_to(10); assert_ok!(ParachainStaking::execute_leave_candidates(RuntimeOrigin::signed(1), 1, 0)); - assert!(ParachainStaking::candidate_info(1).is_none()); + assert!(CandidateInfo::::get(1).is_none()); }); } @@ -908,7 +906,7 @@ fn execute_leave_candidates_removes_pending_delegation_requests() { 1, 5 )); - let state = ParachainStaking::delegation_scheduled_requests(&1); + let state = DelegationScheduledRequests::::get(&1); assert_eq!( state, vec![ScheduledRequest { @@ -919,16 +917,13 @@ fn execute_leave_candidates_removes_pending_delegation_requests() { ); assert_ok!(ParachainStaking::schedule_leave_candidates(RuntimeOrigin::signed(1), 1u32)); // candidate state is not immediately removed - let candidate_state = - ParachainStaking::candidate_info(1).expect("just left => still exists"); + let candidate_state = CandidateInfo::::get(1).expect("just left => still exists"); assert_eq!(candidate_state.bond, 10u128); roll_to(10); assert_ok!(ParachainStaking::execute_leave_candidates(RuntimeOrigin::signed(1), 1, 1)); - assert!(ParachainStaking::candidate_info(1).is_none()); + assert!(CandidateInfo::::get(1).is_none()); assert!( - !ParachainStaking::delegation_scheduled_requests(&1) - .iter() - .any(|x| x.delegator == 2), + !DelegationScheduledRequests::::get(&1).iter().any(|x| x.delegator == 2), "delegation request not removed" ); assert!( @@ -986,8 +981,7 @@ fn cancel_leave_candidates_updates_candidate_state() { .execute_with(|| { assert_ok!(ParachainStaking::schedule_leave_candidates(RuntimeOrigin::signed(1), 1u32)); assert_ok!(ParachainStaking::cancel_leave_candidates(RuntimeOrigin::signed(1), 1)); - let candidate = - ParachainStaking::candidate_info(&1).expect("just cancelled leave so exists"); + let candidate = CandidateInfo::::get(&1).expect("just cancelled leave so exists"); assert!(candidate.is_active()); }); } @@ -1001,8 +995,8 @@ fn cancel_leave_candidates_adds_to_candidate_pool() { .execute_with(|| { assert_ok!(ParachainStaking::schedule_leave_candidates(RuntimeOrigin::signed(1), 1u32)); assert_ok!(ParachainStaking::cancel_leave_candidates(RuntimeOrigin::signed(1), 1)); - assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); - assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 10); + assert_eq!(CandidatePool::::get().0[0].owner, 1); + assert_eq!(CandidatePool::::get().0[0].amount, 10); }); } @@ -1029,9 +1023,9 @@ fn go_offline_removes_candidate_from_candidate_pool() { .with_candidates(vec![(1, 20)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::candidate_pool().0.len(), 1); + assert_eq!(CandidatePool::::get().0.len(), 1); assert_ok!(ParachainStaking::go_offline(RuntimeOrigin::signed(1))); - assert!(ParachainStaking::candidate_pool().0.is_empty()); + assert!(CandidatePool::::get().0.is_empty()); }); } @@ -1042,11 +1036,11 @@ fn go_offline_updates_candidate_state_to_idle() { .with_candidates(vec![(1, 20)]) .build() .execute_with(|| { - let candidate_state = ParachainStaking::candidate_info(1).expect("is active candidate"); + let candidate_state = CandidateInfo::::get(1).expect("is active candidate"); assert_eq!(candidate_state.status, CollatorStatus::Active); assert_ok!(ParachainStaking::go_offline(RuntimeOrigin::signed(1))); let candidate_state = - ParachainStaking::candidate_info(1).expect("is candidate, just offline"); + CandidateInfo::::get(1).expect("is candidate, just offline"); assert_eq!(candidate_state.status, CollatorStatus::Idle); }); } @@ -1101,10 +1095,10 @@ fn go_online_adds_to_candidate_pool() { .build() .execute_with(|| { assert_ok!(ParachainStaking::go_offline(RuntimeOrigin::signed(1))); - assert!(ParachainStaking::candidate_pool().0.is_empty()); + assert!(CandidatePool::::get().0.is_empty()); assert_ok!(ParachainStaking::go_online(RuntimeOrigin::signed(1))); - assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); - assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 20); + assert_eq!(CandidatePool::::get().0[0].owner, 1); + assert_eq!(CandidatePool::::get().0[0].amount, 20); }); } @@ -1116,11 +1110,10 @@ fn go_online_storage_updates_candidate_state() { .build() .execute_with(|| { assert_ok!(ParachainStaking::go_offline(RuntimeOrigin::signed(1))); - let candidate_state = - ParachainStaking::candidate_info(1).expect("offline still exists"); + let candidate_state = CandidateInfo::::get(1).expect("offline still exists"); assert_eq!(candidate_state.status, CollatorStatus::Idle); assert_ok!(ParachainStaking::go_online(RuntimeOrigin::signed(1))); - let candidate_state = ParachainStaking::candidate_info(1).expect("online so exists"); + let candidate_state = CandidateInfo::::get(1).expect("online so exists"); assert_eq!(candidate_state.status, CollatorStatus::Active); }); } @@ -1202,10 +1195,10 @@ fn candidate_bond_more_increases_total() { .with_candidates(vec![(1, 20)]) .build() .execute_with(|| { - let mut total = ParachainStaking::total(); + let mut total = Total::::get(); assert_ok!(ParachainStaking::candidate_bond_more(RuntimeOrigin::signed(1), 30)); total += 30; - assert_eq!(ParachainStaking::total(), total); + assert_eq!(Total::::get(), total); }); } @@ -1216,10 +1209,10 @@ fn candidate_bond_more_updates_candidate_state() { .with_candidates(vec![(1, 20)]) .build() .execute_with(|| { - let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); + let candidate_state = CandidateInfo::::get(1).expect("updated => exists"); assert_eq!(candidate_state.bond, 20); assert_ok!(ParachainStaking::candidate_bond_more(RuntimeOrigin::signed(1), 30)); - let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); + let candidate_state = CandidateInfo::::get(1).expect("updated => exists"); assert_eq!(candidate_state.bond, 50); }); } @@ -1231,11 +1224,11 @@ fn candidate_bond_more_updates_candidate_pool() { .with_candidates(vec![(1, 20)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); - assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 20); + assert_eq!(CandidatePool::::get().0[0].owner, 1); + assert_eq!(CandidatePool::::get().0[0].amount, 20); assert_ok!(ParachainStaking::candidate_bond_more(RuntimeOrigin::signed(1), 30)); - assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); - assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 50); + assert_eq!(CandidatePool::::get().0[0].owner, 1); + assert_eq!(CandidatePool::::get().0[0].amount, 50); }); } @@ -1379,7 +1372,7 @@ fn execute_candidate_bond_less_decreases_total() { .with_candidates(vec![(1, 30)]) .build() .execute_with(|| { - let mut total = ParachainStaking::total(); + let mut total = Total::::get(); assert_ok!(ParachainStaking::schedule_candidate_bond_less( RuntimeOrigin::signed(1), 10 @@ -1387,7 +1380,7 @@ fn execute_candidate_bond_less_decreases_total() { roll_to(10); assert_ok!(ParachainStaking::execute_candidate_bond_less(RuntimeOrigin::signed(1), 1)); total -= 10; - assert_eq!(ParachainStaking::total(), total); + assert_eq!(Total::::get(), total); }); } @@ -1398,7 +1391,7 @@ fn execute_candidate_bond_less_updates_candidate_state() { .with_candidates(vec![(1, 30)]) .build() .execute_with(|| { - let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); + let candidate_state = CandidateInfo::::get(1).expect("updated => exists"); assert_eq!(candidate_state.bond, 30); assert_ok!(ParachainStaking::schedule_candidate_bond_less( RuntimeOrigin::signed(1), @@ -1406,7 +1399,7 @@ fn execute_candidate_bond_less_updates_candidate_state() { )); roll_to(10); assert_ok!(ParachainStaking::execute_candidate_bond_less(RuntimeOrigin::signed(1), 1)); - let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); + let candidate_state = CandidateInfo::::get(1).expect("updated => exists"); assert_eq!(candidate_state.bond, 20); }); } @@ -1418,16 +1411,16 @@ fn execute_candidate_bond_less_updates_candidate_pool() { .with_candidates(vec![(1, 30)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); - assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 30); + assert_eq!(CandidatePool::::get().0[0].owner, 1); + assert_eq!(CandidatePool::::get().0[0].amount, 30); assert_ok!(ParachainStaking::schedule_candidate_bond_less( RuntimeOrigin::signed(1), 10 )); roll_to(10); assert_ok!(ParachainStaking::execute_candidate_bond_less(RuntimeOrigin::signed(1), 1)); - assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); - assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 20); + assert_eq!(CandidatePool::::get().0[0].owner, 1); + assert_eq!(CandidatePool::::get().0[0].amount, 20); }); } @@ -1465,7 +1458,7 @@ fn cancel_candidate_bond_less_updates_candidate_state() { 10 )); assert_ok!(ParachainStaking::cancel_candidate_bond_less(RuntimeOrigin::signed(1))); - assert!(ParachainStaking::candidate_info(&1).unwrap().request.is_none()); + assert!(CandidateInfo::::get(&1).unwrap().request.is_none()); }); } @@ -1526,10 +1519,9 @@ fn delegate_updates_delegator_state() { .with_candidates(vec![(1, 30)]) .build() .execute_with(|| { - assert!(ParachainStaking::delegator_state(2).is_none()); + assert!(DelegatorState::::get(2).is_none()); assert_ok!(ParachainStaking::delegate(RuntimeOrigin::signed(2), 1, 10, 0, 0)); - let delegator_state = - ParachainStaking::delegator_state(2).expect("just delegated => exists"); + let delegator_state = DelegatorState::::get(2).expect("just delegated => exists"); assert_eq!(delegator_state.total(), 10); assert_eq!(delegator_state.delegations.0[0].owner, 1); assert_eq!(delegator_state.delegations.0[0].amount, 10); @@ -1543,19 +1535,15 @@ fn delegate_updates_collator_state() { .with_candidates(vec![(1, 30)]) .build() .execute_with(|| { - let candidate_state = - ParachainStaking::candidate_info(1).expect("registered in genesis"); + let candidate_state = CandidateInfo::::get(1).expect("registered in genesis"); assert_eq!(candidate_state.total_counted, 30); - let top_delegations = - ParachainStaking::top_delegations(1).expect("registered in genesis"); + let top_delegations = TopDelegations::::get(1).expect("registered in genesis"); assert!(top_delegations.delegations.is_empty()); assert!(top_delegations.total.is_zero()); assert_ok!(ParachainStaking::delegate(RuntimeOrigin::signed(2), 1, 10, 0, 0)); - let candidate_state = - ParachainStaking::candidate_info(1).expect("just delegated => exists"); + let candidate_state = CandidateInfo::::get(1).expect("just delegated => exists"); assert_eq!(candidate_state.total_counted, 40); - let top_delegations = - ParachainStaking::top_delegations(1).expect("just delegated => exists"); + let top_delegations = TopDelegations::::get(1).expect("just delegated => exists"); assert_eq!(top_delegations.delegations[0].owner, 2); assert_eq!(top_delegations.delegations[0].amount, 10); assert_eq!(top_delegations.total, 10); @@ -1902,11 +1890,11 @@ fn execute_leave_delegators_decreases_total_staked() { .with_delegations(vec![(2, 1, 10)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::total(), 40); + assert_eq!(Total::::get(), 40); assert_ok!(ParachainStaking::schedule_leave_delegators(RuntimeOrigin::signed(2))); roll_to(10); assert_ok!(ParachainStaking::execute_leave_delegators(RuntimeOrigin::signed(2), 2, 1)); - assert_eq!(ParachainStaking::total(), 30); + assert_eq!(Total::::get(), 30); }); } @@ -1918,11 +1906,11 @@ fn execute_leave_delegators_removes_delegator_state() { .with_delegations(vec![(2, 1, 10)]) .build() .execute_with(|| { - assert!(ParachainStaking::delegator_state(2).is_some()); + assert!(DelegatorState::::get(2).is_some()); assert_ok!(ParachainStaking::schedule_leave_delegators(RuntimeOrigin::signed(2))); roll_to(10); assert_ok!(ParachainStaking::execute_leave_delegators(RuntimeOrigin::signed(2), 2, 1)); - assert!(ParachainStaking::delegator_state(2).is_none()); + assert!(DelegatorState::::get(2).is_none()); }); } @@ -1939,7 +1927,7 @@ fn execute_leave_delegators_removes_pending_delegation_requests() { 1, 5 )); - let state = ParachainStaking::delegation_scheduled_requests(&1); + let state = DelegationScheduledRequests::::get(&1); assert_eq!( state, vec![ScheduledRequest { @@ -1951,11 +1939,9 @@ fn execute_leave_delegators_removes_pending_delegation_requests() { assert_ok!(ParachainStaking::schedule_leave_delegators(RuntimeOrigin::signed(2))); roll_to(10); assert_ok!(ParachainStaking::execute_leave_delegators(RuntimeOrigin::signed(2), 2, 1)); - assert!(ParachainStaking::delegator_state(2).is_none()); + assert!(DelegatorState::::get(2).is_none()); assert!( - !ParachainStaking::delegation_scheduled_requests(&1) - .iter() - .any(|x| x.delegator == 2), + !DelegationScheduledRequests::::get(&1).iter().any(|x| x.delegator == 2), "delegation request not removed" ) }); @@ -1971,24 +1957,24 @@ fn execute_leave_delegators_removes_delegations_from_collator_state() { .execute_with(|| { for i in 2..6 { let candidate_state = - ParachainStaking::candidate_info(i).expect("initialized in ext builder"); + CandidateInfo::::get(i).expect("initialized in ext builder"); assert_eq!(candidate_state.total_counted, 30); let top_delegations = - ParachainStaking::top_delegations(i).expect("initialized in ext builder"); + TopDelegations::::get(i).expect("initialized in ext builder"); assert_eq!(top_delegations.delegations[0].owner, 1); assert_eq!(top_delegations.delegations[0].amount, 10); assert_eq!(top_delegations.total, 10); } - assert_eq!(ParachainStaking::delegator_state(1).unwrap().delegations.0.len(), 4usize); + assert_eq!(DelegatorState::::get(1).unwrap().delegations.0.len(), 4usize); assert_ok!(ParachainStaking::schedule_leave_delegators(RuntimeOrigin::signed(1))); roll_to(10); assert_ok!(ParachainStaking::execute_leave_delegators(RuntimeOrigin::signed(1), 1, 10)); for i in 2..6 { let candidate_state = - ParachainStaking::candidate_info(i).expect("initialized in ext builder"); + CandidateInfo::::get(i).expect("initialized in ext builder"); assert_eq!(candidate_state.total_counted, 20); let top_delegations = - ParachainStaking::top_delegations(i).expect("initialized in ext builder"); + TopDelegations::::get(i).expect("initialized in ext builder"); assert!(top_delegations.delegations.is_empty()); } }); @@ -2107,8 +2093,7 @@ fn cancel_leave_delegators_updates_delegator_state() { .execute_with(|| { assert_ok!(ParachainStaking::schedule_leave_delegators(RuntimeOrigin::signed(2))); assert_ok!(ParachainStaking::cancel_leave_delegators(RuntimeOrigin::signed(2))); - let delegator = - ParachainStaking::delegator_state(&2).expect("just cancelled exit so exists"); + let delegator = DelegatorState::::get(&2).expect("just cancelled exit so exists"); assert!(delegator.is_active()); }); } @@ -2260,9 +2245,9 @@ fn delegator_bond_more_increases_total_staked() { .with_delegations(vec![(2, 1, 10)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::total(), 40); + assert_eq!(Total::::get(), 40); assert_ok!(ParachainStaking::delegator_bond_more(RuntimeOrigin::signed(2), 1, 5)); - assert_eq!(ParachainStaking::total(), 45); + assert_eq!(Total::::get(), 45); }); } @@ -2274,9 +2259,9 @@ fn delegator_bond_more_updates_delegator_state() { .with_delegations(vec![(2, 1, 10)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::delegator_state(2).expect("exists").total(), 10); + assert_eq!(DelegatorState::::get(2).expect("exists").total(), 10); assert_ok!(ParachainStaking::delegator_bond_more(RuntimeOrigin::signed(2), 1, 5)); - assert_eq!(ParachainStaking::delegator_state(2).expect("exists").total(), 15); + assert_eq!(DelegatorState::::get(2).expect("exists").total(), 15); }); } @@ -2288,13 +2273,13 @@ fn delegator_bond_more_updates_candidate_state_top_delegations() { .with_delegations(vec![(2, 1, 10)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, 2); - assert_eq!(ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, 10); - assert_eq!(ParachainStaking::top_delegations(1).unwrap().total, 10); + assert_eq!(TopDelegations::::get(1).unwrap().delegations[0].owner, 2); + assert_eq!(TopDelegations::::get(1).unwrap().delegations[0].amount, 10); + assert_eq!(TopDelegations::::get(1).unwrap().total, 10); assert_ok!(ParachainStaking::delegator_bond_more(RuntimeOrigin::signed(2), 1, 5)); - assert_eq!(ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, 2); - assert_eq!(ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, 15); - assert_eq!(ParachainStaking::top_delegations(1).unwrap().total, 15); + assert_eq!(TopDelegations::::get(1).unwrap().delegations[0].owner, 2); + assert_eq!(TopDelegations::::get(1).unwrap().delegations[0].amount, 15); + assert_eq!(TopDelegations::::get(1).unwrap().total, 15); }); } @@ -2306,15 +2291,12 @@ fn delegator_bond_more_updates_candidate_state_bottom_delegations() { .with_delegations(vec![(2, 1, 10), (3, 1, 20), (4, 1, 20), (5, 1, 20), (6, 1, 20)]) .build() .execute_with(|| { + assert_eq!(BottomDelegations::::get(1).expect("exists").delegations[0].owner, 2); assert_eq!( - ParachainStaking::bottom_delegations(1).expect("exists").delegations[0].owner, - 2 - ); - assert_eq!( - ParachainStaking::bottom_delegations(1).expect("exists").delegations[0].amount, + BottomDelegations::::get(1).expect("exists").delegations[0].amount, 10 ); - assert_eq!(ParachainStaking::bottom_delegations(1).unwrap().total, 10); + assert_eq!(BottomDelegations::::get(1).unwrap().total, 10); assert_ok!(ParachainStaking::delegator_bond_more(RuntimeOrigin::signed(2), 1, 5)); assert_last_event!(MetaEvent::ParachainStaking(Event::DelegationIncreased { delegator: 2, @@ -2322,15 +2304,12 @@ fn delegator_bond_more_updates_candidate_state_bottom_delegations() { amount: 5, in_top: false })); + assert_eq!(BottomDelegations::::get(1).expect("exists").delegations[0].owner, 2); assert_eq!( - ParachainStaking::bottom_delegations(1).expect("exists").delegations[0].owner, - 2 - ); - assert_eq!( - ParachainStaking::bottom_delegations(1).expect("exists").delegations[0].amount, + BottomDelegations::::get(1).expect("exists").delegations[0].amount, 15 ); - assert_eq!(ParachainStaking::bottom_delegations(1).unwrap().total, 15); + assert_eq!(BottomDelegations::::get(1).unwrap().total, 15); }); } @@ -2342,9 +2321,9 @@ fn delegator_bond_more_increases_total() { .with_delegations(vec![(2, 1, 10)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::total(), 40); + assert_eq!(Total::::get(), 40); assert_ok!(ParachainStaking::delegator_bond_more(RuntimeOrigin::signed(2), 1, 5)); - assert_eq!(ParachainStaking::total(), 45); + assert_eq!(Total::::get(), 45); }); } @@ -2431,7 +2410,7 @@ fn delegator_bond_less_updates_delegator_state() { 1, 5 )); - let state = ParachainStaking::delegation_scheduled_requests(&1); + let state = DelegationScheduledRequests::::get(&1); assert_eq!( state, vec![ScheduledRequest { @@ -2690,13 +2669,9 @@ fn execute_revoke_delegation_adds_revocation_to_delegator_state() { .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) .build() .execute_with(|| { - assert!(!ParachainStaking::delegation_scheduled_requests(&1) - .iter() - .any(|x| x.delegator == 2)); + assert!(!DelegationScheduledRequests::::get(&1).iter().any(|x| x.delegator == 2)); assert_ok!(ParachainStaking::schedule_revoke_delegation(RuntimeOrigin::signed(2), 1)); - assert!(ParachainStaking::delegation_scheduled_requests(&1) - .iter() - .any(|x| x.delegator == 2)); + assert!(DelegationScheduledRequests::::get(&1).iter().any(|x| x.delegator == 2)); }); } @@ -2715,9 +2690,7 @@ fn execute_revoke_delegation_removes_revocation_from_delegator_state_upon_execut 2, 1 )); - assert!(!ParachainStaking::delegation_scheduled_requests(&1) - .iter() - .any(|x| x.delegator == 2)); + assert!(!DelegationScheduledRequests::::get(&1).iter().any(|x| x.delegator == 2)); }); } @@ -2737,9 +2710,7 @@ fn execute_revoke_delegation_removes_revocation_from_state_for_single_delegation 1 )); assert!( - !ParachainStaking::delegation_scheduled_requests(&1) - .iter() - .any(|x| x.delegator == 2), + !DelegationScheduledRequests::::get(&1).iter().any(|x| x.delegator == 2), "delegation was not removed" ); }); @@ -2753,7 +2724,7 @@ fn execute_revoke_delegation_decreases_total_staked() { .with_delegations(vec![(2, 1, 10)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::total(), 40); + assert_eq!(Total::::get(), 40); assert_ok!(ParachainStaking::schedule_revoke_delegation(RuntimeOrigin::signed(2), 1)); roll_to(10); assert_ok!(ParachainStaking::execute_delegation_request( @@ -2761,7 +2732,7 @@ fn execute_revoke_delegation_decreases_total_staked() { 2, 1 )); - assert_eq!(ParachainStaking::total(), 30); + assert_eq!(Total::::get(), 30); }); } @@ -2773,7 +2744,7 @@ fn execute_revoke_delegation_for_last_delegation_removes_delegator_state() { .with_delegations(vec![(2, 1, 10)]) .build() .execute_with(|| { - assert!(ParachainStaking::delegator_state(2).is_some()); + assert!(DelegatorState::::get(2).is_some()); assert_ok!(ParachainStaking::schedule_revoke_delegation(RuntimeOrigin::signed(2), 1)); roll_to(10); // this will be confusing for people @@ -2783,7 +2754,7 @@ fn execute_revoke_delegation_for_last_delegation_removes_delegator_state() { 2, 1 )); - assert!(ParachainStaking::delegator_state(2).is_none()); + assert!(DelegatorState::::get(2).is_none()); }); } @@ -2795,7 +2766,7 @@ fn execute_revoke_delegation_removes_delegation_from_candidate_state() { .with_delegations(vec![(2, 1, 10)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::candidate_info(1).expect("exists").delegation_count, 1u32); + assert_eq!(CandidateInfo::::get(1).expect("exists").delegation_count, 1u32); assert_ok!(ParachainStaking::schedule_revoke_delegation(RuntimeOrigin::signed(2), 1)); roll_to(10); assert_ok!(ParachainStaking::execute_delegation_request( @@ -2803,10 +2774,7 @@ fn execute_revoke_delegation_removes_delegation_from_candidate_state() { 2, 1 )); - assert!(ParachainStaking::candidate_info(1) - .expect("exists") - .delegation_count - .is_zero()); + assert!(CandidateInfo::::get(1).expect("exists").delegation_count.is_zero()); }); } @@ -2950,7 +2918,7 @@ fn execute_delegator_bond_less_decreases_total_staked() { .with_delegations(vec![(2, 1, 10)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::total(), 40); + assert_eq!(Total::::get(), 40); assert_ok!(ParachainStaking::schedule_delegator_bond_less( RuntimeOrigin::signed(2), 1, @@ -2962,7 +2930,7 @@ fn execute_delegator_bond_less_decreases_total_staked() { 2, 1 )); - assert_eq!(ParachainStaking::total(), 35); + assert_eq!(Total::::get(), 35); }); } @@ -2974,7 +2942,7 @@ fn execute_delegator_bond_less_updates_delegator_state() { .with_delegations(vec![(2, 1, 10)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::delegator_state(2).expect("exists").total(), 10); + assert_eq!(DelegatorState::::get(2).expect("exists").total(), 10); assert_ok!(ParachainStaking::schedule_delegator_bond_less( RuntimeOrigin::signed(2), 1, @@ -2986,7 +2954,7 @@ fn execute_delegator_bond_less_updates_delegator_state() { 2, 1 )); - assert_eq!(ParachainStaking::delegator_state(2).expect("exists").total(), 5); + assert_eq!(DelegatorState::::get(2).expect("exists").total(), 5); }); } @@ -2998,8 +2966,8 @@ fn execute_delegator_bond_less_updates_candidate_state() { .with_delegations(vec![(2, 1, 10)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, 2); - assert_eq!(ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, 10); + assert_eq!(TopDelegations::::get(1).unwrap().delegations[0].owner, 2); + assert_eq!(TopDelegations::::get(1).unwrap().delegations[0].amount, 10); assert_ok!(ParachainStaking::schedule_delegator_bond_less( RuntimeOrigin::signed(2), 1, @@ -3011,8 +2979,8 @@ fn execute_delegator_bond_less_updates_candidate_state() { 2, 1 )); - assert_eq!(ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, 2); - assert_eq!(ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, 5); + assert_eq!(TopDelegations::::get(1).unwrap().delegations[0].owner, 2); + assert_eq!(TopDelegations::::get(1).unwrap().delegations[0].amount, 5); }); } @@ -3024,7 +2992,7 @@ fn execute_delegator_bond_less_decreases_total() { .with_delegations(vec![(2, 1, 10)]) .build() .execute_with(|| { - assert_eq!(ParachainStaking::total(), 40); + assert_eq!(Total::::get(), 40); assert_ok!(ParachainStaking::schedule_delegator_bond_less( RuntimeOrigin::signed(2), 1, @@ -3036,7 +3004,7 @@ fn execute_delegator_bond_less_decreases_total() { 2, 1 )); - assert_eq!(ParachainStaking::total(), 35); + assert_eq!(Total::::get(), 35); }); } @@ -3049,11 +3017,11 @@ fn execute_delegator_bond_less_updates_just_bottom_delegations() { .build() .execute_with(|| { let pre_call_candidate_info = - ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); + CandidateInfo::::get(&1).expect("delegated by all so exists"); let pre_call_top_delegations = - ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); + TopDelegations::::get(&1).expect("delegated by all so exists"); let pre_call_bottom_delegations = - ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); + BottomDelegations::::get(&1).expect("delegated by all so exists"); assert_ok!(ParachainStaking::schedule_delegator_bond_less( RuntimeOrigin::signed(2), 1, @@ -3066,11 +3034,11 @@ fn execute_delegator_bond_less_updates_just_bottom_delegations() { 1 )); let post_call_candidate_info = - ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); + CandidateInfo::::get(&1).expect("delegated by all so exists"); let post_call_top_delegations = - ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); + TopDelegations::::get(&1).expect("delegated by all so exists"); let post_call_bottom_delegations = - ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); + BottomDelegations::::get(&1).expect("delegated by all so exists"); let mut not_equal = false; for Bond { owner, amount } in pre_call_bottom_delegations.delegations { for Bond { owner: post_owner, amount: post_amount } in @@ -3111,11 +3079,11 @@ fn execute_delegator_bond_less_does_not_delete_bottom_delegations() { .build() .execute_with(|| { let pre_call_candidate_info = - ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); + CandidateInfo::::get(&1).expect("delegated by all so exists"); let pre_call_top_delegations = - ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); + TopDelegations::::get(&1).expect("delegated by all so exists"); let pre_call_bottom_delegations = - ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); + BottomDelegations::::get(&1).expect("delegated by all so exists"); assert_ok!(ParachainStaking::schedule_delegator_bond_less( RuntimeOrigin::signed(6), 1, @@ -3128,11 +3096,11 @@ fn execute_delegator_bond_less_does_not_delete_bottom_delegations() { 1 )); let post_call_candidate_info = - ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); + CandidateInfo::::get(&1).expect("delegated by all so exists"); let post_call_top_delegations = - ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); + TopDelegations::::get(&1).expect("delegated by all so exists"); let post_call_bottom_delegations = - ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); + BottomDelegations::::get(&1).expect("delegated by all so exists"); let mut equal = true; for Bond { owner, amount } in pre_call_bottom_delegations.delegations { for Bond { owner: post_owner, amount: post_amount } in @@ -3221,7 +3189,7 @@ fn cancel_revoke_delegation_updates_delegator_state() { .build() .execute_with(|| { assert_ok!(ParachainStaking::schedule_revoke_delegation(RuntimeOrigin::signed(2), 1)); - let state = ParachainStaking::delegation_scheduled_requests(&1); + let state = DelegationScheduledRequests::::get(&1); assert_eq!( state, vec![ScheduledRequest { @@ -3231,17 +3199,15 @@ fn cancel_revoke_delegation_updates_delegator_state() { }], ); assert_eq!( - ParachainStaking::delegator_state(&2) + DelegatorState::::get(&2) .map(|x| x.less_total) .expect("delegator state must exist"), 10 ); assert_ok!(ParachainStaking::cancel_delegation_request(RuntimeOrigin::signed(2), 1)); - assert!(!ParachainStaking::delegation_scheduled_requests(&1) - .iter() - .any(|x| x.delegator == 2)); + assert!(!DelegationScheduledRequests::::get(&1).iter().any(|x| x.delegator == 2)); assert_eq!( - ParachainStaking::delegator_state(&2) + DelegatorState::::get(&2) .map(|x| x.less_total) .expect("delegator state must exist"), 0 @@ -3289,7 +3255,7 @@ fn cancel_delegator_bond_less_updates_delegator_state() { 1, 5 )); - let state = ParachainStaking::delegation_scheduled_requests(&1); + let state = DelegationScheduledRequests::::get(&1); assert_eq!( state, vec![ScheduledRequest { @@ -3299,17 +3265,15 @@ fn cancel_delegator_bond_less_updates_delegator_state() { }], ); assert_eq!( - ParachainStaking::delegator_state(&2) + DelegatorState::::get(&2) .map(|x| x.less_total) .expect("delegator state must exist"), 5 ); assert_ok!(ParachainStaking::cancel_delegation_request(RuntimeOrigin::signed(2), 1)); - assert!(!ParachainStaking::delegation_scheduled_requests(&1) - .iter() - .any(|x| x.delegator == 2)); + assert!(!DelegationScheduledRequests::::get(&1).iter().any(|x| x.delegator == 2)); assert_eq!( - ParachainStaking::delegator_state(&2) + DelegatorState::::get(&2) .map(|x| x.less_total) .expect("delegator state must exist"), 0 @@ -3329,7 +3293,7 @@ fn delegator_schedule_revocation_total() { .execute_with(|| { assert_ok!(ParachainStaking::schedule_revoke_delegation(RuntimeOrigin::signed(2), 1)); assert_eq!( - ParachainStaking::delegator_state(&2) + DelegatorState::::get(&2) .map(|x| x.less_total) .expect("delegator state must exist"), 10 @@ -3341,7 +3305,7 @@ fn delegator_schedule_revocation_total() { 1 )); assert_eq!( - ParachainStaking::delegator_state(&2) + DelegatorState::::get(&2) .map(|x| x.less_total) .expect("delegator state must exist"), 0 @@ -3350,7 +3314,7 @@ fn delegator_schedule_revocation_total() { assert_ok!(ParachainStaking::schedule_revoke_delegation(RuntimeOrigin::signed(2), 3)); assert_ok!(ParachainStaking::schedule_revoke_delegation(RuntimeOrigin::signed(2), 4)); assert_eq!( - ParachainStaking::delegator_state(&2) + DelegatorState::::get(&2) .map(|x| x.less_total) .expect("delegator state must exist"), 20, @@ -3362,7 +3326,7 @@ fn delegator_schedule_revocation_total() { 3 )); assert_eq!( - ParachainStaking::delegator_state(&2) + DelegatorState::::get(&2) .map(|x| x.less_total) .expect("delegator state must exist"), 10, @@ -3373,7 +3337,7 @@ fn delegator_schedule_revocation_total() { 4 )); assert_eq!( - ParachainStaking::delegator_state(&2) + DelegatorState::::get(&2) .map(|x| x.less_total) .expect("delegator state must exist"), 0 @@ -3778,7 +3742,7 @@ fn collator_exit_executes_after_delay() { .execute_with(|| { roll_to(11); assert_ok!(ParachainStaking::schedule_leave_candidates(RuntimeOrigin::signed(2), 2)); - let info = ParachainStaking::candidate_info(&2).unwrap(); + let info = CandidateInfo::::get(&2).unwrap(); assert_eq!(info.status, CollatorStatus::Leaving(5)); roll_to(21); assert_ok!(ParachainStaking::execute_leave_candidates(RuntimeOrigin::signed(2), 2, 2)); @@ -4094,14 +4058,14 @@ fn payout_distribution_to_solo_collators() { expected.append(&mut new2); assert_eq_events!(expected); // check that distributing rewards clears awarded pts - assert!(ParachainStaking::awarded_pts(1, 1).is_zero()); - assert!(ParachainStaking::awarded_pts(4, 1).is_zero()); - assert!(ParachainStaking::awarded_pts(4, 2).is_zero()); - assert!(ParachainStaking::awarded_pts(6, 1).is_zero()); - assert!(ParachainStaking::awarded_pts(6, 2).is_zero()); - assert!(ParachainStaking::awarded_pts(6, 3).is_zero()); - assert!(ParachainStaking::awarded_pts(6, 4).is_zero()); - assert!(ParachainStaking::awarded_pts(6, 5).is_zero()); + assert!(AwardedPts::::get(1, 1).is_zero()); + assert!(AwardedPts::::get(4, 1).is_zero()); + assert!(AwardedPts::::get(4, 2).is_zero()); + assert!(AwardedPts::::get(6, 1).is_zero()); + assert!(AwardedPts::::get(6, 2).is_zero()); + assert!(AwardedPts::::get(6, 3).is_zero()); + assert!(AwardedPts::::get(6, 4).is_zero()); + assert!(AwardedPts::::get(6, 5).is_zero()); }); } @@ -4257,20 +4221,20 @@ fn multiple_delegations() { expected.append(&mut new3); assert_eq_events!(expected); // verify that delegations are removed after collator leaves, not before - assert_eq!(ParachainStaking::delegator_state(7).unwrap().total(), 90); - assert_eq!(ParachainStaking::delegator_state(7).unwrap().delegations.0.len(), 2usize); - assert_eq!(ParachainStaking::delegator_state(6).unwrap().total(), 40); - assert_eq!(ParachainStaking::delegator_state(6).unwrap().delegations.0.len(), 4usize); + assert_eq!(DelegatorState::::get(7).unwrap().total(), 90); + assert_eq!(DelegatorState::::get(7).unwrap().delegations.0.len(), 2usize); + assert_eq!(DelegatorState::::get(6).unwrap().total(), 40); + assert_eq!(DelegatorState::::get(6).unwrap().delegations.0.len(), 4usize); assert_eq!(Balances::locks(&6)[0].amount, 40); assert_eq!(Balances::locks(&7)[0].amount, 90); assert_eq!(ParachainStaking::get_delegator_stakable_free_balance(&6), 60); assert_eq!(ParachainStaking::get_delegator_stakable_free_balance(&7), 10); roll_to(40); assert_ok!(ParachainStaking::execute_leave_candidates(RuntimeOrigin::signed(2), 2, 5)); - assert_eq!(ParachainStaking::delegator_state(7).unwrap().total(), 10); - assert_eq!(ParachainStaking::delegator_state(6).unwrap().total(), 30); - assert_eq!(ParachainStaking::delegator_state(7).unwrap().delegations.0.len(), 1usize); - assert_eq!(ParachainStaking::delegator_state(6).unwrap().delegations.0.len(), 3usize); + assert_eq!(DelegatorState::::get(7).unwrap().total(), 10); + assert_eq!(DelegatorState::::get(6).unwrap().total(), 30); + assert_eq!(DelegatorState::::get(7).unwrap().delegations.0.len(), 1usize); + assert_eq!(DelegatorState::::get(6).unwrap().delegations.0.len(), 3usize); assert_eq!(ParachainStaking::get_delegator_stakable_free_balance(&6), 70); assert_eq!(ParachainStaking::get_delegator_stakable_free_balance(&7), 90); }); @@ -4287,23 +4251,17 @@ fn execute_leave_candidate_removes_delegations() { .build() .execute_with(|| { // Verifies the revocation request is initially empty - assert!(!ParachainStaking::delegation_scheduled_requests(&2) - .iter() - .any(|x| x.delegator == 3)); + assert!(!DelegationScheduledRequests::::get(&2).iter().any(|x| x.delegator == 3)); assert_ok!(ParachainStaking::schedule_leave_candidates(RuntimeOrigin::signed(2), 2)); assert_ok!(ParachainStaking::schedule_revoke_delegation(RuntimeOrigin::signed(3), 2)); // Verifies the revocation request is present - assert!(ParachainStaking::delegation_scheduled_requests(&2) - .iter() - .any(|x| x.delegator == 3)); + assert!(DelegationScheduledRequests::::get(&2).iter().any(|x| x.delegator == 3)); roll_to(16); assert_ok!(ParachainStaking::execute_leave_candidates(RuntimeOrigin::signed(2), 2, 2)); // Verifies the revocation request is again empty - assert!(!ParachainStaking::delegation_scheduled_requests(&2) - .iter() - .any(|x| x.delegator == 3)); + assert!(!DelegationScheduledRequests::::get(&2).iter().any(|x| x.delegator == 3)); }); } @@ -4572,32 +4530,32 @@ fn bottom_delegations_are_empty_when_top_delegations_not_full() { .build() .execute_with(|| { // no top delegators => no bottom delegators - let top_delegations = ParachainStaking::top_delegations(1).unwrap(); - let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); + let top_delegations = TopDelegations::::get(1).unwrap(); + let bottom_delegations = BottomDelegations::::get(1).unwrap(); assert!(top_delegations.delegations.is_empty()); assert!(bottom_delegations.delegations.is_empty()); // 1 delegator => 1 top delegator, 0 bottom delegators assert_ok!(ParachainStaking::delegate(RuntimeOrigin::signed(2), 1, 10, 10, 10)); - let top_delegations = ParachainStaking::top_delegations(1).unwrap(); - let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); + let top_delegations = TopDelegations::::get(1).unwrap(); + let bottom_delegations = BottomDelegations::::get(1).unwrap(); assert_eq!(top_delegations.delegations.len(), 1usize); assert!(bottom_delegations.delegations.is_empty()); // 2 delegators => 2 top delegators, 0 bottom delegators assert_ok!(ParachainStaking::delegate(RuntimeOrigin::signed(3), 1, 10, 10, 10)); - let top_delegations = ParachainStaking::top_delegations(1).unwrap(); - let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); + let top_delegations = TopDelegations::::get(1).unwrap(); + let bottom_delegations = BottomDelegations::::get(1).unwrap(); assert_eq!(top_delegations.delegations.len(), 2usize); assert!(bottom_delegations.delegations.is_empty()); // 3 delegators => 3 top delegators, 0 bottom delegators assert_ok!(ParachainStaking::delegate(RuntimeOrigin::signed(4), 1, 10, 10, 10)); - let top_delegations = ParachainStaking::top_delegations(1).unwrap(); - let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); + let top_delegations = TopDelegations::::get(1).unwrap(); + let bottom_delegations = BottomDelegations::::get(1).unwrap(); assert_eq!(top_delegations.delegations.len(), 3usize); assert!(bottom_delegations.delegations.is_empty()); // 4 delegators => 4 top delegators, 0 bottom delegators assert_ok!(ParachainStaking::delegate(RuntimeOrigin::signed(5), 1, 10, 10, 10)); - let top_delegations = ParachainStaking::top_delegations(1).unwrap(); - let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); + let top_delegations = TopDelegations::::get(1).unwrap(); + let bottom_delegations = BottomDelegations::::get(1).unwrap(); assert_eq!(top_delegations.delegations.len(), 4usize); assert!(bottom_delegations.delegations.is_empty()); }); @@ -4631,7 +4589,7 @@ fn candidate_pool_updates_when_total_counted_changes() { .build() .execute_with(|| { fn is_candidate_pool_bond(account: u64, bond: u128) { - let pool = ParachainStaking::candidate_pool(); + let pool = CandidatePool::::get(); for candidate in pool.0 { if candidate.owner == account { assert_eq!( @@ -4713,7 +4671,7 @@ fn only_top_collators_are_counted() { for i in 3..11 { assert!(ParachainStaking::is_delegator(&i)); } - let collator_state = ParachainStaking::candidate_info(1).unwrap(); + let collator_state = CandidateInfo::::get(1).unwrap(); // 15 + 16 + 17 + 18 + 20 = 86 (top 4 + self bond) assert_eq!(collator_state.total_counted, 86); // bump bottom to the top @@ -4724,7 +4682,7 @@ fn only_top_collators_are_counted() { amount: 8, in_top: true, }); - let collator_state = ParachainStaking::candidate_info(1).unwrap(); + let collator_state = CandidateInfo::::get(1).unwrap(); // 16 + 17 + 18 + 19 + 20 = 90 (top 4 + self bond) assert_eq!(collator_state.total_counted, 90); // bump bottom to the top @@ -4735,7 +4693,7 @@ fn only_top_collators_are_counted() { amount: 8, in_top: true, }); - let collator_state = ParachainStaking::candidate_info(1).unwrap(); + let collator_state = CandidateInfo::::get(1).unwrap(); // 17 + 18 + 19 + 20 + 20 = 94 (top 4 + self bond) assert_eq!(collator_state.total_counted, 94); // bump bottom to the top @@ -4746,7 +4704,7 @@ fn only_top_collators_are_counted() { amount: 8, in_top: true, }); - let collator_state = ParachainStaking::candidate_info(1).unwrap(); + let collator_state = CandidateInfo::::get(1).unwrap(); // 18 + 19 + 20 + 21 + 20 = 98 (top 4 + self bond) assert_eq!(collator_state.total_counted, 98); // bump bottom to the top @@ -4757,7 +4715,7 @@ fn only_top_collators_are_counted() { amount: 8, in_top: true, }); - let collator_state = ParachainStaking::candidate_info(1).unwrap(); + let collator_state = CandidateInfo::::get(1).unwrap(); // 19 + 20 + 21 + 22 + 20 = 102 (top 4 + self bond) assert_eq!(collator_state.total_counted, 102); }); @@ -4782,7 +4740,7 @@ fn delegation_events_convey_correct_position() { .with_delegations(vec![(3, 1, 11), (4, 1, 12), (5, 1, 13), (6, 1, 14)]) .build() .execute_with(|| { - let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + let collator1_state = CandidateInfo::::get(1).unwrap(); // 11 + 12 + 13 + 14 + 20 = 70 (top 4 + self bond) assert_eq!(collator1_state.total_counted, 70); // Top delegations are full, new highest delegation is made @@ -4793,7 +4751,7 @@ fn delegation_events_convey_correct_position() { candidate: 1, delegator_position: DelegatorAdded::AddedToTop { new_total: 74 }, }); - let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + let collator1_state = CandidateInfo::::get(1).unwrap(); // 12 + 13 + 14 + 15 + 20 = 70 (top 4 + self bond) assert_eq!(collator1_state.total_counted, 74); // New delegation is added to the bottom @@ -4804,7 +4762,7 @@ fn delegation_events_convey_correct_position() { candidate: 1, delegator_position: DelegatorAdded::AddedToBottom, }); - let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + let collator1_state = CandidateInfo::::get(1).unwrap(); // 12 + 13 + 14 + 15 + 20 = 70 (top 4 + self bond) assert_eq!(collator1_state.total_counted, 74); // 8 increases delegation to the top @@ -4815,7 +4773,7 @@ fn delegation_events_convey_correct_position() { amount: 3, in_top: true, }); - let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + let collator1_state = CandidateInfo::::get(1).unwrap(); // 13 + 13 + 14 + 15 + 20 = 75 (top 4 + self bond) assert_eq!(collator1_state.total_counted, 75); // 3 increases delegation but stays in bottom @@ -4826,7 +4784,7 @@ fn delegation_events_convey_correct_position() { amount: 1, in_top: false, }); - let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + let collator1_state = CandidateInfo::::get(1).unwrap(); // 13 + 13 + 14 + 15 + 20 = 75 (top 4 + self bond) assert_eq!(collator1_state.total_counted, 75); // 6 decreases delegation but stays in top @@ -4853,7 +4811,7 @@ fn delegation_events_convey_correct_position() { amount: 2, in_top: true, }); - let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + let collator1_state = CandidateInfo::::get(1).unwrap(); // 12 + 13 + 13 + 15 + 20 = 73 (top 4 + self bond)ƒ assert_eq!(collator1_state.total_counted, 73); // 6 decreases delegation and is bumped to bottom @@ -4880,7 +4838,7 @@ fn delegation_events_convey_correct_position() { amount: 1, in_top: false, }); - let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + let collator1_state = CandidateInfo::::get(1).unwrap(); // 12 + 13 + 13 + 15 + 20 = 73 (top 4 + self bond) assert_eq!(collator1_state.total_counted, 73); }); @@ -5407,7 +5365,7 @@ fn patch_incorrect_delegations_sums() { // for i in 3..7 { // assert!(>::get(i).is_none()); // assert_eq!( -// ParachainStaking::delegator_state(i).unwrap().status, +// DelegatorState::::get(i).unwrap().status, // DelegatorStatus::Leaving(3) // ); // } @@ -5459,7 +5417,7 @@ fn patch_incorrect_delegations_sums() { // for i in 3..7 { // assert!(>::get(i).is_none()); // assert_eq!( -// ParachainStaking::delegator_state(i) +// DelegatorState::::get(i) // .unwrap() // .requests // .requests @@ -5544,9 +5502,7 @@ fn delegation_kicked_from_bottom_removes_pending_request() { unstaked_amount: 19, }); // ensure request DNE - assert!(!ParachainStaking::delegation_scheduled_requests(&1) - .iter() - .any(|x| x.delegator == 2)); + assert!(!DelegationScheduledRequests::::get(&1).iter().any(|x| x.delegator == 2)); }); } @@ -5565,8 +5521,8 @@ fn no_selected_candidates_defaults_to_last_round_collators() { 5 )); } - let old_round = ParachainStaking::round().current; - let old_selected_candidates = ParachainStaking::selected_candidates(); + let old_round = Round::::get().current; + let old_selected_candidates = SelectedCandidates::::get(); let mut old_at_stake_snapshots = Vec::new(); for account in old_selected_candidates.clone() { old_at_stake_snapshots.push(>::get(old_round, account)); @@ -5582,9 +5538,9 @@ fn no_selected_candidates_defaults_to_last_round_collators() { } // next round roll_to_round_begin(4); - let new_round = ParachainStaking::round().current; + let new_round = Round::::get().current; // check AtStake matches previous - let new_selected_candidates = ParachainStaking::selected_candidates(); + let new_selected_candidates = SelectedCandidates::::get(); assert_eq!(old_selected_candidates, new_selected_candidates); let mut index = 0usize; for account in new_selected_candidates { @@ -5612,7 +5568,7 @@ fn test_delegator_scheduled_for_revoke_is_rewarded_for_previous_rounds_but_not_f candidate: 1, scheduled_exit: 3, })); - let collator = ParachainStaking::candidate_info(1).expect("candidate must exist"); + let collator = CandidateInfo::::get(1).expect("candidate must exist"); assert_eq!( 1, collator.delegation_count, "collator's delegator count was reduced unexpectedly" @@ -5633,8 +5589,7 @@ fn test_delegator_scheduled_for_revoke_is_rewarded_for_previous_rounds_but_not_f vec![Event::::Rewarded { account: 1, rewards: 4 }], "delegator was rewarded unexpectedly" ); - let collator_snapshot = - ParachainStaking::at_stake(ParachainStaking::round().current, 1); + let collator_snapshot = AtStake::::get(Round::::get().current, 1); assert_eq!( 1, collator_snapshot.delegations.len(), @@ -5665,7 +5620,7 @@ fn test_delegator_scheduled_for_revoke_is_rewarded_when_request_cancelled() { candidate: 1, scheduled_exit: 3, })); - let collator = ParachainStaking::candidate_info(1).expect("candidate must exist"); + let collator = CandidateInfo::::get(1).expect("candidate must exist"); assert_eq!( 1, collator.delegation_count, "collator's delegator count was reduced unexpectedly" @@ -5680,8 +5635,7 @@ fn test_delegator_scheduled_for_revoke_is_rewarded_when_request_cancelled() { vec![Event::::Rewarded { account: 1, rewards: 4 }], "delegator was rewarded unexpectedly", ); - let collator_snapshot = - ParachainStaking::at_stake(ParachainStaking::round().current, 1); + let collator_snapshot = AtStake::::get(Round::::get().current, 1); assert_eq!( 1, collator_snapshot.delegations.len(), @@ -5726,7 +5680,7 @@ fn test_delegator_scheduled_for_bond_decrease_is_rewarded_for_previous_rounds_bu candidate: 1, amount_to_decrease: 10, })); - let collator = ParachainStaking::candidate_info(1).expect("candidate must exist"); + let collator = CandidateInfo::::get(1).expect("candidate must exist"); assert_eq!( 1, collator.delegation_count, "collator's delegator count was reduced unexpectedly" @@ -5750,8 +5704,7 @@ fn test_delegator_scheduled_for_bond_decrease_is_rewarded_for_previous_rounds_bu ], "delegator was rewarded unexpectedly" ); - let collator_snapshot = - ParachainStaking::at_stake(ParachainStaking::round().current, 1); + let collator_snapshot = AtStake::::get(Round::::get().current, 1); assert_eq!( 1, collator_snapshot.delegations.len(), @@ -5786,7 +5739,7 @@ fn test_delegator_scheduled_for_bond_decrease_is_rewarded_when_request_cancelled candidate: 1, amount_to_decrease: 10, })); - let collator = ParachainStaking::candidate_info(1).expect("candidate must exist"); + let collator = CandidateInfo::::get(1).expect("candidate must exist"); assert_eq!( 1, collator.delegation_count, "collator's delegator count was reduced unexpectedly" @@ -5804,8 +5757,7 @@ fn test_delegator_scheduled_for_bond_decrease_is_rewarded_when_request_cancelled ], "delegator was rewarded unexpectedly", ); - let collator_snapshot = - ParachainStaking::at_stake(ParachainStaking::round().current, 1); + let collator_snapshot = AtStake::::get(Round::::get().current, 1); assert_eq!( 1, collator_snapshot.delegations.len(), @@ -5844,7 +5796,7 @@ fn test_delegator_scheduled_for_leave_is_rewarded_for_previous_rounds_but_not_fo delegator: 2, scheduled_exit: 3, })); - let collator = ParachainStaking::candidate_info(1).expect("candidate must exist"); + let collator = CandidateInfo::::get(1).expect("candidate must exist"); assert_eq!( 1, collator.delegation_count, "collator's delegator count was reduced unexpectedly" @@ -5865,8 +5817,7 @@ fn test_delegator_scheduled_for_leave_is_rewarded_for_previous_rounds_but_not_fo vec![Event::::Rewarded { account: 1, rewards: 4 },], "delegator was rewarded unexpectedly" ); - let collator_snapshot = - ParachainStaking::at_stake(ParachainStaking::round().current, 1); + let collator_snapshot = AtStake::::get(Round::::get().current, 1); assert_eq!( 1, collator_snapshot.delegations.len(), @@ -5896,7 +5847,7 @@ fn test_delegator_scheduled_for_leave_is_rewarded_when_request_cancelled() { delegator: 2, scheduled_exit: 3, })); - let collator = ParachainStaking::candidate_info(1).expect("candidate must exist"); + let collator = CandidateInfo::::get(1).expect("candidate must exist"); assert_eq!( 1, collator.delegation_count, "collator's delegator count was reduced unexpectedly" @@ -5911,8 +5862,7 @@ fn test_delegator_scheduled_for_leave_is_rewarded_when_request_cancelled() { vec![Event::::Rewarded { account: 1, rewards: 4 },], "delegator was rewarded unexpectedly", ); - let collator_snapshot = - ParachainStaking::at_stake(ParachainStaking::round().current, 1); + let collator_snapshot = AtStake::::get(Round::::get().current, 1); assert_eq!( 1, collator_snapshot.delegations.len(), @@ -6288,7 +6238,7 @@ mod jit_migrate_reserve_to_locks_tests { .build() .execute_with(|| { // 3 is initially a delegator to 1 - assert!(ParachainStaking::delegator_state(3).is_some()); + assert!(DelegatorState::::get(3).is_some()); assert!(>::get(3)); // unmigrate so that delegator needs JIT diff --git a/pallets/prices/src/lib.rs b/pallets/prices/src/lib.rs index c39db7ad0..105ac1e8a 100644 --- a/pallets/prices/src/lib.rs +++ b/pallets/prices/src/lib.rs @@ -23,7 +23,9 @@ #![cfg_attr(not(feature = "std"), no_std)] use bifrost_asset_registry::AssetMetadata; -use bifrost_primitives::*; +use bifrost_primitives::{ + Balance, CurrencyId, CurrencyIdMapping, Price, PriceDetail, TimeStampedPrice, TokenInfo, +}; use frame_support::{dispatch::DispatchClass, pallet_prelude::*, transactional}; use frame_system::pallet_prelude::*; use log; @@ -97,13 +99,11 @@ pub mod pallet { /// Mapping from currency id to it's emergency price #[pallet::storage] - #[pallet::getter(fn emergency_price)] pub type EmergencyPrice = StorageMap<_, Twox64Concat, CurrencyId, Price, OptionQuery>; /// Mapping from foreign vault token to our's vault token #[pallet::storage] - #[pallet::getter(fn foreign_to_native_asset)] pub type ForeignToNativeAsset = StorageMap<_, Twox64Concat, CurrencyId, CurrencyId, OptionQuery>; @@ -181,7 +181,7 @@ pub mod pallet { impl Pallet { // get emergency price, the timestamp is zero fn get_emergency_price(asset_id: &CurrencyId) -> Option { - Self::emergency_price(asset_id).and_then(|p| { + EmergencyPrice::::get(asset_id).and_then(|p| { let mantissa = Self::get_asset_mantissa(asset_id)?; log::trace!( target: "prices::get_emergency_price", @@ -241,7 +241,7 @@ impl PriceFeeder for Pallet { fn get_normal_price(asset_id: &CurrencyId) -> Option { let decimals = Self::get_asset_mantissa(asset_id)?; - Self::emergency_price(asset_id) + EmergencyPrice::::get(asset_id) .and_then(|p| Some(p.into_inner().saturating_div(decimals))) .or_else(|| { T::Source::get(&asset_id) diff --git a/pallets/prices/src/mock.rs b/pallets/prices/src/mock.rs index c01150e0e..3d6a24755 100644 --- a/pallets/prices/src/mock.rs +++ b/pallets/prices/src/mock.rs @@ -27,6 +27,7 @@ pub use bifrost_primitives::{ currency::{FIL, VFIL}, DOT, KSM, VDOT, }; +use bifrost_primitives::{Moment, ASTR, BNC, DOT_U, GLMR}; use sp_runtime::BuildStorage; pub type AccountId = u128; @@ -192,17 +193,8 @@ impl bifrost_asset_registry::Config for Test { } orml_traits::parameter_type_with_key! { - pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance { - match currency_id { - &CurrencyId::Native(TokenSymbol::BNC) => 0, - &CurrencyId::Token(TokenSymbol::KSM) => 0, - &CurrencyId::VToken(TokenSymbol::KSM) => 0, - &DOT => 0, - &VDOT => 0, - &VBNC => 0, - &CurrencyId::BLP(_) => 0, - _ => 0 - } + pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { + 0 }; } @@ -239,8 +231,8 @@ pub fn new_test_ext() -> sp_io::TestExternalities { bifrost_asset_registry::GenesisConfig:: { currency: vec![ - (CurrencyId::Token(TokenSymbol::KSM), 1, None), - (CurrencyId::Native(TokenSymbol::BNC), 1, None), + (KSM, 1, None), + (BNC, 1, None), (DOT, 1, Some(("_".to_string(), "_".to_string(), 10))), (ASTR, 1, None), (GLMR, 1, None), diff --git a/pallets/prices/src/tests.rs b/pallets/prices/src/tests.rs index 184539442..d81680730 100644 --- a/pallets/prices/src/tests.rs +++ b/pallets/prices/src/tests.rs @@ -15,6 +15,7 @@ //! Unit tests for the prices pallet. use super::*; +use bifrost_primitives::VKSM; use frame_support::{assert_noop, assert_ok}; use mock::{RuntimeEvent, *}; use sp_runtime::{traits::BadOrigin, FixedPointNumber}; diff --git a/pallets/salp/src/benchmarking.rs b/pallets/salp/src/benchmarking.rs index 136f5d2b6..cbb3f249b 100644 --- a/pallets/salp/src/benchmarking.rs +++ b/pallets/salp/src/benchmarking.rs @@ -113,7 +113,7 @@ mod benchmarks { assert_ok!(Salp::::fund_fail(RawOrigin::Root.into(), fund_index)); assert_ok!(Salp::::withdraw(RawOrigin::Root.into(), fund_index)); - let fund = Salp::::funds(fund_index).unwrap(); + let fund = Funds::::get(fund_index).unwrap(); let (_, status) = Salp::::contribution(fund.trie_index, &caller); assert_eq!(status, ContributionStatus::Idle); @@ -187,12 +187,12 @@ mod benchmarks { )); assert_ok!(Salp::::fund_retire(RawOrigin::Root.into(), fund_index)); assert_ok!(Salp::::withdraw(RawOrigin::Root.into(), fund_index)); - assert_eq!(Salp::::redeem_pool(), T::MinContribution::get()); + assert_eq!(RedeemPool::::get(), T::MinContribution::get()); #[extrinsic_call] _(RawOrigin::Signed(caller.clone()), fund_index, contribution); - assert_eq!(Salp::::redeem_pool(), 0_u32.saturated_into()); + assert_eq!(RedeemPool::::get(), 0_u32.saturated_into()); } #[benchmark] @@ -547,7 +547,7 @@ mod benchmarks { )); assert_ok!(Salp::::fund_retire(RawOrigin::Root.into(), fund_index)); assert_ok!(Salp::::withdraw(RawOrigin::Root.into(), fund_index)); - assert_eq!(Salp::::redeem_pool(), T::MinContribution::get()); + assert_eq!(RedeemPool::::get(), T::MinContribution::get()); #[extrinsic_call] _(RawOrigin::Signed(caller.clone()), fund_index); diff --git a/pallets/salp/src/lib.rs b/pallets/salp/src/lib.rs index 82a9749e2..b2fae3ff3 100644 --- a/pallets/salp/src/lib.rs +++ b/pallets/salp/src/lib.rs @@ -317,29 +317,24 @@ pub mod pallet { /// Multisig confirm account #[pallet::storage] - #[pallet::getter(fn multisig_confirm_account)] pub type MultisigConfirmAccount = StorageValue<_, AccountIdOf, OptionQuery>; /// Tracker for the next available fund index #[pallet::storage] - #[pallet::getter(fn current_trie_index)] pub(super) type CurrentTrieIndex = StorageValue<_, TrieIndex, ValueQuery>; /// Tracker for the next nonce index #[pallet::storage] - #[pallet::getter(fn current_nonce)] pub(super) type CurrentNonce = StorageMap<_, Blake2_128Concat, ParaId, Nonce, ValueQuery>; /// Record contribution #[pallet::storage] - #[pallet::getter(fn contributing_value)] pub type QueryIdContributionInfo = StorageMap<_, Blake2_128Concat, QueryId, (ParaId, AccountIdOf, BalanceOf)>; /// Info on all of the funds. #[pallet::storage] - #[pallet::getter(fn funds)] pub(super) type Funds = StorageMap< _, Blake2_128Concat, @@ -350,11 +345,9 @@ pub mod pallet { /// The balance can be redeemed to users. #[pallet::storage] - #[pallet::getter(fn redeem_pool)] pub type RedeemPool = StorageValue<_, BalanceOf, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn failed_funds_to_refund)] pub(super) type FailedFundsToRefund = StorageNMap< _, ( @@ -367,7 +360,6 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn reserve_infos)] pub type ReserveInfos = StorageDoubleMap< _, Twox64Concat, @@ -416,7 +408,7 @@ pub mod pallet { ) -> DispatchResult { T::EnsureConfirmAsGovernance::ensure_origin(origin)?; - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; ensure!(fund.status == FundStatus::Ongoing, Error::::InvalidFundStatus); let fund_new = FundInfo { status: FundStatus::Success, ..fund }; @@ -432,7 +424,7 @@ pub mod pallet { T::EnsureConfirmAsGovernance::ensure_origin(origin)?; // crownload is failed, so enable the withdrawal function of vsToken/vsBond - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; ensure!(fund.status == FundStatus::Ongoing, Error::::InvalidFundStatus); let fund_new = FundInfo { status: FundStatus::Failed, ..fund }; @@ -453,7 +445,7 @@ pub mod pallet { T::EnsureConfirmAsGovernance::ensure_origin(origin)?; // crownload is failed, so enable the withdrawal function of vsToken/vsBond - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; ensure!(fund.status == FundStatus::RefundWithdrew, Error::::InvalidFundStatus); ensure!( fund.first_slot != first_slot || fund.last_slot != last_slot, @@ -512,7 +504,7 @@ pub mod pallet { ) -> DispatchResult { T::EnsureConfirmAsGovernance::ensure_origin(origin)?; - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; ensure!(fund.status == FundStatus::Success, Error::::InvalidFundStatus); let fund_new = FundInfo { status: FundStatus::Retired, ..fund }; @@ -527,7 +519,7 @@ pub mod pallet { pub fn fund_end(origin: OriginFor, #[pallet::compact] index: ParaId) -> DispatchResult { T::EnsureConfirmAsGovernance::ensure_origin(origin)?; - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; ensure!( fund.status == FundStatus::RefundWithdrew || fund.status == FundStatus::RedeemWithdrew, @@ -622,7 +614,7 @@ pub mod pallet { ) -> DispatchResult { T::EnsureConfirmAsGovernance::ensure_origin(origin)?; - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; let status = match fund_status { None => fund.status, @@ -655,7 +647,7 @@ pub mod pallet { ) -> DispatchResult { let who = ensure_signed(origin.clone())?; - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; ensure!(fund.status == FundStatus::Ongoing, Error::::InvalidFundStatus); ensure!(value >= T::MinContribution::get(), Error::::ContributionTooSmall); @@ -708,7 +700,7 @@ pub mod pallet { let (index, contributer, _amount) = QueryIdContributionInfo::::get(query_id) .ok_or(Error::::NotFindContributionValue)?; - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; let can_confirm = fund.status == FundStatus::Ongoing || fund.status == FundStatus::Failed || fund.status == FundStatus::Success; @@ -781,7 +773,7 @@ pub mod pallet { #[pallet::compact] index: ParaId, ) -> DispatchResult { ensure_signed(origin)?; - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; let (contributed, _) = Self::contribution(fund.trie_index, &who); @@ -835,7 +827,7 @@ pub mod pallet { _ => return Err(Error::::NotSupportTokenType.into()), }; - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; let (contributed, _) = Self::contribution(fund.trie_index, &who); @@ -906,7 +898,7 @@ pub mod pallet { ) -> DispatchResult { ensure_signed(origin)?; - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; let mut unlock_count = 0u32; let contributions = Self::contribution_iterator(fund.trie_index); @@ -951,13 +943,14 @@ pub mod pallet { pub fn withdraw(origin: OriginFor, #[pallet::compact] index: ParaId) -> DispatchResult { T::EnsureConfirmAsGovernance::ensure_origin(origin.clone())?; - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; let can = fund.status == FundStatus::Failed || fund.status == FundStatus::Retired; ensure!(can, Error::::InvalidFundStatus); let amount_withdrew = fund.raised; - let total = - Self::redeem_pool().checked_add(&amount_withdrew).ok_or(Error::::Overflow)?; + let total = RedeemPool::::get() + .checked_add(&amount_withdrew) + .ok_or(Error::::Overflow)?; RedeemPool::::set(total); if fund.status == FundStatus::Retired { @@ -996,7 +989,7 @@ pub mod pallet { Error::::InvalidRefund ); ensure!(fund.raised >= value, Error::::NotEnoughBalanceInFund); - ensure!(Self::redeem_pool() >= value, Error::::NotEnoughBalanceInRefundPool); + ensure!(RedeemPool::::get() >= value, Error::::NotEnoughBalanceInRefundPool); let vs_token = T::CurrencyIdConversion::convert_to_vstoken(T::RelayChainToken::get()) .map_err(|_| Error::::NotSupportTokenType)?; @@ -1015,8 +1008,8 @@ pub mod pallet { T::MultiCurrency::withdraw(vs_token, &who, value)?; T::MultiCurrency::withdraw(vs_bond, &who, value)?; - RedeemPool::::set(Self::redeem_pool().saturating_sub(value)); - let mut fund_new = Self::funds(index).ok_or(Error::::InvalidParaId)?; + RedeemPool::::set(RedeemPool::::get().saturating_sub(value)); + let mut fund_new = Funds::::get(index).ok_or(Error::::InvalidParaId)?; fund_new.raised = fund_new.raised.saturating_sub(value); Funds::::insert(index, Some(fund_new)); if fund.status == FundStatus::FailedToContinue { @@ -1054,7 +1047,7 @@ pub mod pallet { ) -> DispatchResult { let who = ensure_signed(origin.clone())?; - let mut fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let mut fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; ensure!(fund.status == FundStatus::RedeemWithdrew, Error::::InvalidFundStatus); ensure!(fund.raised >= value, Error::::NotEnoughBalanceInRedeemPool); @@ -1068,7 +1061,7 @@ pub mod pallet { ) .map_err(|_| Error::::NotSupportTokenType)?; - ensure!(Self::redeem_pool() >= value, Error::::NotEnoughBalanceInRedeemPool); + ensure!(RedeemPool::::get() >= value, Error::::NotEnoughBalanceInRedeemPool); let cur_block = >::block_number(); let expired = Self::is_expired(cur_block, fund.last_slot)?; ensure!(!expired, Error::::VSBondExpired); @@ -1079,7 +1072,7 @@ pub mod pallet { T::MultiCurrency::withdraw(vs_token, &who, value)?; T::MultiCurrency::withdraw(vs_bond, &who, value)?; - RedeemPool::::set(Self::redeem_pool().saturating_sub(value)); + RedeemPool::::set(RedeemPool::::get().saturating_sub(value)); fund.raised = fund.raised.saturating_sub(value); Funds::::insert(index, Some(fund.clone())); @@ -1112,7 +1105,7 @@ pub mod pallet { ) -> DispatchResult { T::EnsureConfirmAsGovernance::ensure_origin(origin)?; - let fund = Self::failed_funds_to_refund((index, first_slot, last_slot)) + let fund = FailedFundsToRefund::::get((index, first_slot, last_slot)) .ok_or(Error::::InvalidRefund)?; ensure!(fund.status == FundStatus::FailedToContinue, Error::::InvalidFundStatus); @@ -1130,7 +1123,7 @@ pub mod pallet { pub fn dissolve(origin: OriginFor, #[pallet::compact] index: ParaId) -> DispatchResult { T::EnsureConfirmAsGovernance::ensure_origin(origin)?; - let mut fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let mut fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; ensure!(fund.status == FundStatus::End, Error::::InvalidFundStatus); let mut refund_count = 0u32; @@ -1217,7 +1210,7 @@ pub mod pallet { let (index, contributer, _amount) = QueryIdContributionInfo::::get(query_id) .ok_or(Error::::NotFindContributionValue)?; - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; let can_confirm = fund.status == FundStatus::Ongoing || fund.status == FundStatus::Failed || fund.status == FundStatus::Success; @@ -1343,7 +1336,7 @@ pub mod pallet { if_mint: bool, ) -> DispatchResult { let who = ensure_signed(origin)?; - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; ensure!( fund.status == FundStatus::Ongoing || fund.status == FundStatus::Success, @@ -1379,7 +1372,7 @@ pub mod pallet { pub fn batch_handle_reserve(origin: OriginFor, index: ParaId) -> DispatchResult { let _who = ensure_signed(origin.clone())?; - let mut fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let mut fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; let vs_token = T::CurrencyIdConversion::convert_to_vstoken(T::RelayChainToken::get()) .map_err(|_| Error::::NotSupportTokenType)?; let vs_bond = T::CurrencyIdConversion::convert_to_vsbond( @@ -1472,7 +1465,7 @@ pub mod pallet { pub fn cancel_reservation(origin: OriginFor, index: ParaId) -> DispatchResult { let who = ensure_signed(origin)?; - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; let vs_token = T::CurrencyIdConversion::convert_to_vstoken(T::RelayChainToken::get()) .map_err(|_| Error::::NotSupportTokenType)?; @@ -1497,7 +1490,7 @@ pub mod pallet { fn on_initialize(n: BlockNumberFor) -> Weight { // Release x% KSM/DOT from redeem-pool to bancor-pool per cycle if n != Zero::zero() && (n % T::ReleaseCycle::get()) == Zero::zero() { - if let Ok(rp_balance) = TryInto::::try_into(Self::redeem_pool()) { + if let Ok(rp_balance) = TryInto::::try_into(RedeemPool::::get()) { // Calculate the release amount let release_amount = T::ReleaseRatio::get() * rp_balance; @@ -1508,7 +1501,7 @@ pub mod pallet { T::BancorPool::add_token(T::RelayChainToken::get(), release_amount) { RedeemPool::::set( - Self::redeem_pool().saturating_sub(release_amount), + RedeemPool::::get().saturating_sub(release_amount), ); } } else { @@ -1557,9 +1550,9 @@ pub mod pallet { first_slot: LeasePeriod, last_slot: LeasePeriod, ) -> Result, LeasePeriod>, Error> { - return match Self::failed_funds_to_refund((index, first_slot, last_slot)) { + return match FailedFundsToRefund::::get((index, first_slot, last_slot)) { Some(fund) => Ok(fund), - _ => match Self::funds(index) { + _ => match Funds::::get(index) { Some(fund) => Ok(fund), _ => Err(Error::::InvalidFundNotExist), }, @@ -1593,7 +1586,7 @@ pub mod pallet { index: ParaId, who: &AccountIdOf, ) -> Result<(BalanceOf, ContributionStatus>), Error> { - let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; + let fund = Funds::::get(index).ok_or(Error::::InvalidParaId)?; let (contributed, status) = Self::contribution(fund.trie_index, who); Ok((contributed, status)) } @@ -1647,7 +1640,7 @@ pub mod pallet { ) -> DispatchResult { ensure!(fund.raised >= value, Error::::NotEnoughBalanceInRedeemPool); - ensure!(Self::redeem_pool() >= value, Error::::NotEnoughBalanceInRedeemPool); + ensure!(RedeemPool::::get() >= value, Error::::NotEnoughBalanceInRedeemPool); let cur_block = >::block_number(); let expired = Self::is_expired(cur_block, fund.last_slot)?; ensure!(!expired, Error::::VSBondExpired); @@ -1658,7 +1651,7 @@ pub mod pallet { T::MultiCurrency::withdraw(vs_token, &who, value)?; T::MultiCurrency::withdraw(vs_bond, &who, value)?; - RedeemPool::::set(Self::redeem_pool().saturating_sub(value)); + RedeemPool::::set(RedeemPool::::get().saturating_sub(value)); fund.raised = fund.raised.saturating_sub(value); Funds::::insert(index, Some(fund.clone())); @@ -1701,7 +1694,7 @@ pub mod pallet { Error::::InvalidRefund ); ensure!(fund.raised >= value, Error::::NotEnoughBalanceInFund); - ensure!(Self::redeem_pool() >= value, Error::::NotEnoughBalanceInRefundPool); + ensure!(RedeemPool::::get() >= value, Error::::NotEnoughBalanceInRefundPool); T::MultiCurrency::ensure_can_withdraw(vs_token, &who, value) .map_err(|_e| Error::::NotEnoughFreeAssetsToRedeem)?; @@ -1711,8 +1704,8 @@ pub mod pallet { T::MultiCurrency::withdraw(vs_token, &who, value)?; T::MultiCurrency::withdraw(vs_bond, &who, value)?; - RedeemPool::::set(Self::redeem_pool().saturating_sub(value)); - let mut fund_new = Self::funds(index).ok_or(Error::::InvalidParaId)?; + RedeemPool::::set(RedeemPool::::get().saturating_sub(value)); + let mut fund_new = Funds::::get(index).ok_or(Error::::InvalidParaId)?; fund_new.raised = fund_new.raised.saturating_sub(value); Funds::::insert(index, Some(fund_new)); if fund.status == FundStatus::FailedToContinue { diff --git a/pallets/salp/src/mock.rs b/pallets/salp/src/mock.rs index 193e905ab..4d1bf1435 100644 --- a/pallets/salp/src/mock.rs +++ b/pallets/salp/src/mock.rs @@ -23,8 +23,8 @@ use crate::*; use bifrost_asset_registry::AssetIdMaps; use bifrost_primitives::{ - Amount, Balance, CurrencyId, CurrencyId::*, DoNothingExecuteXcm, MessageId, ParaId, - SlpOperator, SlpxOperator, TokenSymbol, TokenSymbol::*, VKSM, + Amount, Balance, CurrencyId, CurrencyId::*, MessageId, MockXcmExecutor, ParaId, SlpOperator, + SlpxOperator, TokenSymbol, TokenSymbol::*, VKSM, }; use bifrost_xcm_interface::traits::XcmHelper; use cumulus_primitives_core::ParaId as Pid; @@ -53,6 +53,7 @@ use zenlink_protocol::{ }; use crate as salp; +use bifrost_primitives::MoonbeamChainId; pub(crate) type AccountId = <::Signer as sp_runtime::traits::IdentifyAccount>::AccountId; pub(crate) type Block = frame_system::mocking::MockBlock; @@ -307,9 +308,9 @@ impl EnsureOrigin for EnsureConfirmAsGovernance { pub(crate) static mut MOCK_XCM_RESULT: (bool, bool) = (true, true); // Mock XcmExecutor -pub struct MockXcmExecutor; +pub struct MockSalpXcmExecutor; -impl XcmHelper, crate::BalanceOf> for MockXcmExecutor { +impl XcmHelper, crate::BalanceOf> for MockSalpXcmExecutor { fn contribute( _contributer: AccountId, _index: ParaId, @@ -431,16 +432,12 @@ impl bifrost_vtoken_minting::Config for Test { type WeightInfo = (); type OnRedeemSuccess = (); type XcmTransfer = XTokens; - type AstarParachainId = ConstU32<2007>; - type MoonbeamParachainId = ConstU32<2023>; + type MoonbeamChainId = MoonbeamChainId; type BifrostSlpx = SlpxInterface; - type HydradxParachainId = ConstU32<2034>; - type MantaParachainId = ConstU32<2104>; - type InterlayParachainId = ConstU32<2032>; type ChannelCommission = (); type MaxLockRecords = ConstU32<100>; type IncentivePoolAccount = IncentivePoolAccount; - type VeMinting = (); + type BbBNC = (); type AssetIdMaps = AssetIdMaps; } @@ -465,7 +462,7 @@ impl salp::Config for Test { type VSBondValidPeriod = VSBondValidPeriod; type EnsureConfirmAsGovernance = EnsureConfirmAsGovernance; type WeightInfo = (); - type XcmInterface = MockXcmExecutor; + type XcmInterface = MockSalpXcmExecutor; type TreasuryAccount = TreasuryAccount; type BuybackPalletId = BuybackPalletId; type DexOperator = ZenlinkProtocol; @@ -564,7 +561,7 @@ impl bifrost_xcm_interface::Config for Test { type RelayNetwork = RelayNetwork; type RelaychainCurrencyId = RelayCurrencyId; type ParachainSovereignAccount = TreasuryAccount; - type XcmExecutor = DoNothingExecuteXcm; + type XcmExecutor = MockXcmExecutor; type AccountIdToLocation = BifrostAccountIdToMultiLocation; type SalpHelper = Salp; type ParachainId = ParaInfo; diff --git a/pallets/salp/src/tests.rs b/pallets/salp/src/tests.rs index fc15ce71f..31d5870cf 100644 --- a/pallets/salp/src/tests.rs +++ b/pallets/salp/src/tests.rs @@ -31,8 +31,8 @@ use zenlink_protocol::AssetId; fn create_fund_should_work() { new_test_ext().execute_with(|| { assert_ok!(Salp::create(Some(ALICE).into(), 3_000, 1_000, 1, SlotLength::get())); - assert_ok!(Salp::funds(3_000).ok_or(())); - assert_eq!(Salp::current_trie_index(), 1); + assert_ok!(Funds::::get(3_000).ok_or(())); + assert_eq!(CurrentTrieIndex::::get(), 1); }); } @@ -85,7 +85,7 @@ fn set_fund_success_should_work() { assert_ok!(Salp::fund_success(Some(ALICE).into(), 3_000)); // Check status - let fund = Salp::funds(3_000).unwrap(); + let fund = Funds::::get(3_000).unwrap(); assert_eq!(fund.status, FundStatus::Success); }); } @@ -125,7 +125,7 @@ fn set_fund_fail_should_work() { assert_ok!(Salp::fund_fail(Some(ALICE).into(), 3_000)); // Check status - let fund = Salp::funds(3_000).unwrap(); + let fund = Funds::::get(3_000).unwrap(); assert_eq!(fund.status, FundStatus::Failed); }); } @@ -163,7 +163,7 @@ fn set_fund_retire_should_work() { assert_ok!(Salp::fund_retire(Some(ALICE).into(), 3_000)); // Check status - let fund = Salp::funds(3_000).unwrap(); + let fund = Funds::::get(3_000).unwrap(); assert_eq!(fund.status, FundStatus::Retired); }); } @@ -207,7 +207,7 @@ fn set_fund_end_should_work() { assert_ok!(Salp::fund_end(Some(ALICE).into(), 3_000)); // Check storage - let fund = Salp::funds(3_000).unwrap(); + let fund = Funds::::get(3_000).unwrap(); assert_eq!(fund.status, FundStatus::End); }); } @@ -353,7 +353,7 @@ fn contribute_should_work() { Salp::bind_query_id_and_contribution(0, 3_000, BRUCE, 100); assert_ok!(Salp::confirm_contribute(Some(ALICE).into(), 0, true)); - let fund = Salp::funds(3_000).unwrap(); + let fund = Funds::::get(3_000).unwrap(); let (contributed, status) = Salp::contribution(fund.trie_index, &BRUCE); assert_eq!(fund.raised, 100); assert_eq!(contributed, 100); @@ -386,7 +386,7 @@ fn double_contribute_should_work() { assert_ok!(Salp::confirm_contribute(Some(ALICE).into(), 0, true,)); // Check the contribution - let fund = Salp::funds(3_000).unwrap(); + let fund = Funds::::get(3_000).unwrap(); let (contributed, status) = Salp::contribution(fund.trie_index, &BRUCE); assert_eq!(fund.raised, 200); assert_eq!(contributed, 200); @@ -415,7 +415,7 @@ fn contribute_when_xcm_error_should_work() { Salp::bind_query_id_and_contribution(0, 3_000, BRUCE, 100); assert_ok!(Salp::confirm_contribute(Some(ALICE).into(), 0, false,)); - let fund = Salp::funds(3_000).unwrap(); + let fund = Funds::::get(3_000).unwrap(); let (contributed, status) = Salp::contribution(fund.trie_index, &BRUCE); assert_eq!(fund.raised, 0); assert_eq!(contributed, 0); @@ -449,7 +449,7 @@ fn confirm_contribute_later_should_work() { assert_ok!(Salp::fund_success(Some(ALICE).into(), 3_000)); assert_ok!(Salp::confirm_contribute(Some(ALICE).into(), 0, true,)); - let fund = Salp::funds(3_000).unwrap(); + let fund = Funds::::get(3_000).unwrap(); let (contributed, status) = Salp::contribution(fund.trie_index, &BRUCE); assert_eq!(fund.raised, 100); assert_eq!(contributed, 100); @@ -568,7 +568,7 @@ fn withdraw_should_work() { assert_ok!(Salp::fund_retire(Some(ALICE).into(), 3_000)); assert_ok!(Salp::withdraw(Some(ALICE).into(), 3_000)); - let fund = Salp::funds(3_000).unwrap(); + let fund = Funds::::get(3_000).unwrap(); assert_eq!(fund.status, FundStatus::RedeemWithdrew); assert_ok!(Salp::create(Some(ALICE).into(), 4_000, 1_000, 1, SlotLength::get())); @@ -578,7 +578,7 @@ fn withdraw_should_work() { assert_ok!(Salp::fund_fail(Some(ALICE).into(), 4_000)); assert_ok!(Salp::withdraw(Some(ALICE).into(), 4_000)); - let fund = Salp::funds(4_000).unwrap(); + let fund = Funds::::get(4_000).unwrap(); assert_eq!(fund.status, FundStatus::RefundWithdrew); }); } @@ -594,7 +594,7 @@ fn withdraw_when_xcm_error_should_work() { assert_ok!(Salp::fund_retire(Some(ALICE).into(), 3_000)); assert_ok!(Salp::withdraw(Some(ALICE).into(), 3_000)); - let fund = Salp::funds(3_000).unwrap(); + let fund = Funds::::get(3_000).unwrap(); assert_eq!(fund.status, FundStatus::RedeemWithdrew); assert_ok!(Salp::create(Some(ALICE).into(), 4_000, 1_000, 1, SlotLength::get())); @@ -604,7 +604,7 @@ fn withdraw_when_xcm_error_should_work() { assert_ok!(Salp::fund_fail(Some(ALICE).into(), 4_000)); assert_ok!(Salp::withdraw(Some(ALICE).into(), 4_000)); - let fund = Salp::funds(4_000).unwrap(); + let fund = Funds::::get(4_000).unwrap(); assert_eq!(fund.status, FundStatus::RefundWithdrew); }); } @@ -621,7 +621,7 @@ fn double_withdraw_same_fund_should_fail() { assert_ok!(Salp::withdraw(Some(ALICE).into(), 3_000)); assert_noop!(Salp::withdraw(Some(ALICE).into(), 3_000), Error::::InvalidFundStatus); - let fund = Salp::funds(3_000).unwrap(); + let fund = Funds::::get(3_000).unwrap(); assert_eq!(fund.status, FundStatus::RedeemWithdrew); assert_ok!(Salp::create(Some(ALICE).into(), 4_000, 1_000, 1, SlotLength::get())); @@ -632,7 +632,7 @@ fn double_withdraw_same_fund_should_fail() { assert_ok!(Salp::withdraw(Some(ALICE).into(), 4_000)); assert_noop!(Salp::withdraw(Some(ALICE).into(), 4_000), Error::::InvalidFundStatus); - let fund = Salp::funds(4_000).unwrap(); + let fund = Funds::::get(4_000).unwrap(); assert_eq!(fund.status, FundStatus::RefundWithdrew); }); } @@ -828,7 +828,7 @@ fn dissolve_should_work() { assert_ok!(Salp::dissolve(Some(ALICE).into(), 3_000)); } - assert!(Salp::funds(3_000).is_none()); + assert!(Funds::::get(3_000).is_none()); assert!(Salp::contribution_iterator(0).next().is_none()); }); } @@ -1178,7 +1178,7 @@ fn release_from_redeem_to_bancor_should_work() { fn check_next_trie_index() { new_test_ext().execute_with(|| { for i in 0..100 { - assert_eq!(Salp::current_trie_index(), i); + assert_eq!(CurrentTrieIndex::::get(), i); assert_ok!(Salp::next_trie_index()); } }); @@ -1276,10 +1276,10 @@ fn refund_meanwhile_issue_should_work() { ), true ); - let old_fund = Salp::failed_funds_to_refund((3_000, 1, SlotLength::get())).unwrap(); + let old_fund = FailedFundsToRefund::::get((3_000, 1, SlotLength::get())).unwrap(); assert_eq!(old_fund.first_slot, 1); assert_eq!(old_fund.raised, 100); - let mut new_fund = Salp::funds(3_000).unwrap(); + let mut new_fund = Funds::::get(3_000).unwrap(); assert_eq!(new_fund.first_slot, 2); assert_eq!(new_fund.raised, 100); let vs_bond_new = ::CurrencyIdConversion::convert_to_vsbond( @@ -1292,7 +1292,7 @@ fn refund_meanwhile_issue_should_work() { assert_ok!(Salp::contribute(Some(BRUCE).into(), 3_000, 100)); Salp::bind_query_id_and_contribution(0, 3_000, BRUCE, 100); assert_ok!(Salp::confirm_contribute(Some(ALICE).into(), 0, true,)); - new_fund = Salp::funds(3_000).unwrap(); + new_fund = Funds::::get(3_000).unwrap(); assert_eq!(new_fund.raised, 200); assert_eq!(Tokens::accounts(BRUCE, vs_bond_new).free, 100); // refund from old failed fund should success @@ -1472,7 +1472,7 @@ fn edit_fund_should_work() { Salp::bind_query_id_and_contribution(0, 3_000, BRUCE, 100); assert_ok!(Salp::confirm_contribute(Some(ALICE).into(), 0, true,)); assert_ok!(Salp::fund_fail(Some(ALICE).into(), 3_000)); - let mut fund = Salp::funds(3_000).unwrap(); + let mut fund = Funds::::get(3_000).unwrap(); assert_eq!(fund.raised, 100); assert_ok!(Salp::edit( @@ -1484,7 +1484,7 @@ fn edit_fund_should_work() { SlotLength::get() + 1, Some(FundStatus::Ongoing) )); - fund = Salp::funds(3_000).unwrap(); + fund = Funds::::get(3_000).unwrap(); assert_eq!(fund.raised, 150); assert_eq!(fund.status, FundStatus::Ongoing); }); diff --git a/pallets/slp-v2/Cargo.toml b/pallets/slp-v2/Cargo.toml new file mode 100644 index 000000000..d1879f580 --- /dev/null +++ b/pallets/slp-v2/Cargo.toml @@ -0,0 +1,78 @@ +[package] +name = "bifrost-slp-v2" +authors = ["Liebi Technologies "] +edition = "2021" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +parity-scale-codec = { workspace = true, features = ["derive"] } +scale-info = { workspace = true, features = ["derive"] } +frame-benchmarking = { workspace = true, optional = true } +frame-support = { workspace = true } +frame-system = { workspace = true } +bifrost-primitives = { workspace = true } +xcm = { workspace = true } +pallet-xcm = { workspace = true } +pallet-balances = { workspace = true } +xcm-executor = { workspace = true } +xcm-builder = { workspace = true } +orml-traits = { workspace = true } +polkadot-parachain-primitives = { workspace = true } +sp-core = { workspace = true } +sp-std = { workspace = true } +sp-runtime = { workspace = true } +cumulus-primitives-core = { workspace = true } +bifrost-asset-registry = { workspace = true } + +[dev-dependencies] +hex-literal = { workspace = true } +sp-core = { workspace = true } +sp-io = { workspace = true } +sp-runtime = { workspace = true } +orml-tokens = { workspace = true } +pallet-utility = { workspace = true } +bifrost-vtoken-minting = { workspace = true } +bifrost-currencies = { workspace = true } + +[features] +default = ["std"] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", +] +std = [ + "parity-scale-codec/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "scale-info/std", + "sp-core/std", + "sp-io/std", + "sp-std/std", + "sp-runtime/std", + "bifrost-primitives/std", + "xcm/std", + "xcm-executor/std", + "xcm-builder/std", + "orml-traits/std", + "polkadot-parachain-primitives/std", + "sp-core/std", + "sp-runtime/std", + "pallet-xcm/std", + "cumulus-primitives-core/std", + "pallet-balances/std", + "bifrost-asset-registry/std", +] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", + "sp-runtime/try-runtime", +] +kusama = [] +polkadot = [] diff --git a/pallets/slp-v2/src/astar_dapp_staking/impls.rs b/pallets/slp-v2/src/astar_dapp_staking/impls.rs new file mode 100644 index 000000000..b9f832497 --- /dev/null +++ b/pallets/slp-v2/src/astar_dapp_staking/impls.rs @@ -0,0 +1,232 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use crate::{ + astar_dapp_staking::types::{ + AstarCall, AstarDappStakingPendingStatus, AstarUnlockingRecord, AstarValidator, DappStaking, + }, + common::types::{ + Delegator, DelegatorIndex, Ledger, PendingStatus, StakingProtocol, Validator, XcmTask, + }, + Call, Config, ConfigurationByStakingProtocol, Error, Event, + LedgerByStakingProtocolAndDelegator, Pallet, PendingStatusByQueryId, + ValidatorsByStakingProtocolAndDelegator, +}; +use bifrost_primitives::VtokenMintingOperator; +use frame_support::{dispatch::DispatchResultWithPostInfo, ensure}; +use parity_scale_codec::Encode; +use sp_std::{cmp::Ordering, vec::Vec}; +use xcm::v4::{opaque::Xcm, Location, QueryId}; + +pub const ASTAR_DAPP_STAKING: StakingProtocol = StakingProtocol::AstarDappStaking; + +impl Pallet { + pub fn ensure_validator_exist( + delegator: Delegator, + validator: AstarValidator, + ) -> DispatchResultWithPostInfo { + let validators = + ValidatorsByStakingProtocolAndDelegator::::get(ASTAR_DAPP_STAKING, delegator); + let is_exist = validators.iter().any(|storage_validator| match storage_validator { + Validator::AstarDappStaking(astar_validator) => *astar_validator == validator, + _ => false, + }); + ensure!(is_exist, Error::::ValidatorNotFound); + Ok(().into()) + } + + pub fn do_dapp_staking( + delegator: Delegator, + task: DappStaking, + ) -> DispatchResultWithPostInfo { + let delegator_index = Self::ensure_delegator_exist(&ASTAR_DAPP_STAKING, &delegator)?; + let (call, pending_status) = match task.clone() { + DappStaking::Lock(amount) => ( + AstarCall::::DappStaking(DappStaking::::Lock(amount)).encode(), + Some(PendingStatus::AstarDappStaking(AstarDappStakingPendingStatus::Lock( + delegator.clone(), + amount, + ))), + ), + DappStaking::Unlock(amount) => ( + AstarCall::::DappStaking(DappStaking::::Unlock(amount)).encode(), + Some(PendingStatus::AstarDappStaking(AstarDappStakingPendingStatus::UnLock( + delegator.clone(), + amount, + ))), + ), + DappStaking::ClaimUnlocked => ( + AstarCall::::DappStaking(DappStaking::::ClaimUnlocked).encode(), + Some(PendingStatus::AstarDappStaking( + AstarDappStakingPendingStatus::ClaimUnlocked(delegator.clone()), + )), + ), + DappStaking::Stake(validator, amount) => { + Self::ensure_validator_exist(delegator.clone(), validator.clone())?; + ( + AstarCall::::DappStaking(DappStaking::::Stake( + validator.clone(), + amount, + )) + .encode(), + None, + ) + }, + DappStaking::Unstake(validator, amount) => { + Self::ensure_validator_exist(delegator.clone(), validator.clone())?; + ( + AstarCall::::DappStaking(DappStaking::::Unstake( + validator.clone(), + amount, + )) + .encode(), + None, + ) + }, + DappStaking::ClaimStakerRewards => ( + AstarCall::::DappStaking(DappStaking::::ClaimStakerRewards) + .encode(), + None, + ), + DappStaking::ClaimBonusReward(validator) => { + Self::ensure_validator_exist(delegator.clone(), validator.clone())?; + ( + AstarCall::::DappStaking(DappStaking::::ClaimBonusReward( + validator, + )) + .encode(), + None, + ) + }, + DappStaking::RelockUnlocking => ( + AstarCall::::DappStaking(DappStaking::::RelockUnlocking).encode(), + None, + ), + }; + let (query_id, xcm_message) = + Self::get_query_id_and_xcm_message(call, delegator_index, &pending_status)?; + if let Some(query_id) = query_id { + let pending_status = pending_status.clone().ok_or(Error::::XcmFeeNotFound)?; + PendingStatusByQueryId::::insert(query_id, pending_status.clone()); + } + Self::send_xcm_message(ASTAR_DAPP_STAKING, xcm_message)?; + Self::deposit_event(Event::::SendXcmTask { + query_id, + delegator, + task: XcmTask::AstarDappStaking(task), + pending_status, + dest_location: ASTAR_DAPP_STAKING.info().remote_dest_location, + }); + Ok(().into()) + } + + pub fn get_query_id_and_xcm_message( + call: Vec, + delegator_index: DelegatorIndex, + pending_status: &Option>, + ) -> Result<(Option, Xcm), Error> { + let call = + Self::wrap_utility_as_derivative_call_data(&ASTAR_DAPP_STAKING, delegator_index, call); + let mut query_id = None; + let xcm_message; + if pending_status.is_some() { + let notify_call = + ::RuntimeCall::from(Call::::notify_astar_dapp_staking { + query_id: 0, + response: Default::default(), + }); + xcm_message = Self::wrap_xcm_message_with_notify( + &ASTAR_DAPP_STAKING, + call, + notify_call, + &mut query_id, + )?; + } else { + xcm_message = Self::wrap_xcm_message(&ASTAR_DAPP_STAKING, call)?; + }; + Ok((query_id, xcm_message)) + } + + pub fn do_notify_astar_dapp_staking( + responder: Location, + pending_status: PendingStatus, + ) -> Result<(), Error> { + let delegator = match pending_status.clone() { + PendingStatus::AstarDappStaking(AstarDappStakingPendingStatus::Lock(delegator, _)) => + delegator, + PendingStatus::AstarDappStaking(AstarDappStakingPendingStatus::UnLock( + delegator, + _, + )) => delegator, + PendingStatus::AstarDappStaking(AstarDappStakingPendingStatus::ClaimUnlocked( + delegator, + )) => delegator, + }; + LedgerByStakingProtocolAndDelegator::::mutate( + ASTAR_DAPP_STAKING, + delegator, + |ledger| -> Result<(), Error> { + if let Some(Ledger::AstarDappStaking(mut pending_ledger)) = ledger.clone() { + match pending_status.clone() { + PendingStatus::AstarDappStaking(AstarDappStakingPendingStatus::Lock( + _, + amount, + )) => { + pending_ledger.add_lock_amount(amount); + }, + PendingStatus::AstarDappStaking(AstarDappStakingPendingStatus::UnLock( + _, + amount, + )) => { + pending_ledger.subtract_lock_amount(amount); + let currency_id = ASTAR_DAPP_STAKING.info().currency_id; + let current_time_unit = + T::VtokenMinting::get_ongoing_time_unit(currency_id) + .ok_or(Error::::TimeUnitNotFound)?; + let configuration = + ConfigurationByStakingProtocol::::get(ASTAR_DAPP_STAKING) + .ok_or(Error::::ConfigurationNotFound)?; + let unlock_time = current_time_unit + .add(configuration.unlock_period) + .ok_or(Error::::TimeUnitNotFound)?; + pending_ledger + .unlocking + .try_push(AstarUnlockingRecord { amount, unlock_time }) + .map_err(|_| Error::::UnlockRecordOverflow)?; + }, + PendingStatus::AstarDappStaking( + AstarDappStakingPendingStatus::ClaimUnlocked(_), + ) => { + let currency_id = ASTAR_DAPP_STAKING.info().currency_id; + let current_time_unit = + T::VtokenMinting::get_ongoing_time_unit(currency_id) + .ok_or(Error::::TimeUnitNotFound)?; + pending_ledger.unlocking.retain(|record| { + current_time_unit.cmp(&record.unlock_time) != Ordering::Greater + }); + }, + }; + *ledger = Some(Ledger::AstarDappStaking(pending_ledger)); + }; + Ok(()) + }, + )?; + Self::deposit_event(Event::::NotifyResponseReceived { responder, pending_status }); + Ok(()) + } +} diff --git a/pallets/slp-v2/src/astar_dapp_staking/mod.rs b/pallets/slp-v2/src/astar_dapp_staking/mod.rs new file mode 100644 index 000000000..b00ddda58 --- /dev/null +++ b/pallets/slp-v2/src/astar_dapp_staking/mod.rs @@ -0,0 +1,20 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +pub mod impls; +pub mod types; diff --git a/pallets/slp-v2/src/astar_dapp_staking/types.rs b/pallets/slp-v2/src/astar_dapp_staking/types.rs new file mode 100644 index 000000000..17c5e2a05 --- /dev/null +++ b/pallets/slp-v2/src/astar_dapp_staking/types.rs @@ -0,0 +1,101 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use crate::{common::types::Delegator, Config}; +use bifrost_primitives::{Balance, TimeUnit}; +use frame_support::{ + pallet_prelude::{Decode, Encode, MaxEncodedLen, TypeInfo}, + BoundedVec, +}; +use sp_core::{ConstU32, H160}; +use sp_runtime::Saturating; + +/// Multi-VM pointer to smart contract instance. +#[derive(PartialEq, Eq, Clone, Encode, Decode, Debug, Copy, MaxEncodedLen, TypeInfo)] +pub enum AstarValidator { + /// EVM smart contract instance. + Evm(H160), + /// Wasm smart contract instance. + Wasm(AccountId), +} + +/// Dapp staking extrinsic call. +#[derive(Encode, Decode, MaxEncodedLen, Clone, Copy, Debug, PartialEq, Eq, TypeInfo)] +pub enum DappStaking { + #[codec(index = 7)] + Lock(#[codec(compact)] Balance), + #[codec(index = 8)] + Unlock(#[codec(compact)] Balance), + #[codec(index = 9)] + ClaimUnlocked, + #[codec(index = 10)] + RelockUnlocking, + #[codec(index = 11)] + Stake(AstarValidator, #[codec(compact)] Balance), + #[codec(index = 12)] + Unstake(AstarValidator, #[codec(compact)] Balance), + #[codec(index = 13)] + ClaimStakerRewards, + #[codec(index = 14)] + ClaimBonusReward(AstarValidator), +} + +/// Astar extrinsic call. +#[derive(Encode, Decode, Debug, Clone)] +pub enum AstarCall { + #[codec(index = 34)] + DappStaking(DappStaking), +} + +/// Astar unlocking record. +#[derive(Encode, Decode, MaxEncodedLen, Clone, Debug, PartialEq, Eq, TypeInfo)] +pub struct AstarUnlockingRecord { + pub amount: Balance, + pub unlock_time: TimeUnit, +} + +/// Astar dapp staking ledger. +#[derive(Encode, Decode, MaxEncodedLen, Clone, Debug, Default, PartialEq, Eq, TypeInfo)] +pub struct AstarDappStakingLedger { + /// How much active locked amount an account has. This can be used for staking. + #[codec(compact)] + pub locked: Balance, + /// Vector of all the unlocking chunks. This is also considered _locked_ but cannot be used for + /// staking. + pub unlocking: BoundedVec>, +} + +impl AstarDappStakingLedger { + /// Adds the specified amount to the total locked amount. + pub fn add_lock_amount(&mut self, amount: Balance) { + self.locked.saturating_accrue(amount); + } + + /// Subtracts the specified amount of the total locked amount. + pub fn subtract_lock_amount(&mut self, amount: Balance) { + self.locked.saturating_reduce(amount); + } +} + +/// PendingStatus in slp protocol. +#[derive(Encode, Decode, MaxEncodedLen, Clone, Copy, Debug, PartialEq, Eq, TypeInfo)] +pub enum AstarDappStakingPendingStatus { + Lock(Delegator, Balance), + UnLock(Delegator, Balance), + ClaimUnlocked(Delegator), +} diff --git a/pallets/slp-v2/src/benchmarking.rs b/pallets/slp-v2/src/benchmarking.rs new file mode 100644 index 000000000..92f124653 --- /dev/null +++ b/pallets/slp-v2/src/benchmarking.rs @@ -0,0 +1,236 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg(feature = "runtime-benchmarks")] +use super::*; +use crate::{ + astar_dapp_staking::types::{ + AstarDappStakingLedger, AstarDappStakingPendingStatus, AstarValidator, DappStaking, + }, + common::types::{Ledger, PendingStatus, StakingProtocol, Validator, XcmFee}, + Pallet as SlpV2, +}; +use frame_benchmarking::v2::*; +use frame_support::assert_ok; +use frame_system::RawOrigin; +use sp_core::{crypto::Ss58Codec, H160}; +use sp_runtime::{AccountId32 as AccountId, Permill}; +use xcm::v4::MaybeErrorCode; + +pub const STAKING_PROTOCOL: StakingProtocol = StakingProtocol::AstarDappStaking; + +fn do_set_protocol_configuration() +where + ::AccountId: From, +{ + assert_ok!(SlpV2::::set_protocol_configuration( + RawOrigin::Root.into(), + STAKING_PROTOCOL, + ProtocolConfiguration { + xcm_task_fee: XcmFee { weight: Weight::zero(), fee: 100 }, + protocol_fee_rate: Permill::from_perthousand(100), + unlock_period: TimeUnit::Era(9), + operator: AccountId::from([0u8; 32]).into(), + max_update_token_exchange_rate: Permill::from_perthousand(1), + update_time_unit_interval: 100u32, + update_exchange_rate_interval: 100u32, + } + )); +} + +#[benchmarks(where ::AccountId: From)] +mod benchmarks { + use super::*; + + #[benchmark] + fn add_delegator() { + #[extrinsic_call] + _(RawOrigin::Root, STAKING_PROTOCOL, None); + } + + #[benchmark] + fn remove_delegator() -> Result<(), BenchmarkError> { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o") + .unwrap() + .into(), + ); + assert_ok!(SlpV2::::add_delegator(RawOrigin::Root.into(), STAKING_PROTOCOL, None)); + #[extrinsic_call] + _(RawOrigin::Root, STAKING_PROTOCOL, delegator); + + Ok(()) + } + + #[benchmark] + fn add_validator() -> Result<(), BenchmarkError> { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o") + .unwrap() + .into(), + ); + assert_ok!(SlpV2::::add_delegator(RawOrigin::Root.into(), STAKING_PROTOCOL, None)); + let validator = Validator::AstarDappStaking(AstarValidator::Evm(H160::zero())); + #[extrinsic_call] + _(RawOrigin::Root, STAKING_PROTOCOL, delegator, validator); + Ok(()) + } + + #[benchmark] + fn remove_validator() -> Result<(), BenchmarkError> { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o") + .unwrap() + .into(), + ); + assert_ok!(SlpV2::::add_delegator(RawOrigin::Root.into(), STAKING_PROTOCOL, None)); + let validator = Validator::AstarDappStaking(AstarValidator::Evm(H160::zero())); + assert_ok!(SlpV2::::add_validator( + RawOrigin::Root.into(), + STAKING_PROTOCOL, + delegator.clone(), + validator.clone() + )); + #[extrinsic_call] + _(RawOrigin::Root, STAKING_PROTOCOL, delegator, validator); + Ok(()) + } + + #[benchmark] + fn set_protocol_configuration() -> Result<(), BenchmarkError> { + #[extrinsic_call] + _( + RawOrigin::Root, + STAKING_PROTOCOL, + ProtocolConfiguration { + xcm_task_fee: XcmFee { weight: Weight::zero(), fee: 100 }, + protocol_fee_rate: Permill::from_perthousand(100), + unlock_period: TimeUnit::Era(9), + operator: AccountId::from([0u8; 32]).into(), + max_update_token_exchange_rate: Permill::from_perthousand(1), + update_time_unit_interval: 100u32, + update_exchange_rate_interval: 100u32, + }, + ); + Ok(()) + } + + #[benchmark] + fn set_ledger() -> Result<(), BenchmarkError> { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o") + .unwrap() + .into(), + ); + let ledger = Ledger::AstarDappStaking(AstarDappStakingLedger { + locked: 100, + unlocking: Default::default(), + }); + assert_ok!(SlpV2::::add_delegator(RawOrigin::Root.into(), STAKING_PROTOCOL, None)); + + #[extrinsic_call] + _(RawOrigin::Root, STAKING_PROTOCOL, delegator, ledger); + Ok(()) + } + + #[benchmark] + fn transfer_to() -> Result<(), BenchmarkError> { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o") + .unwrap() + .into(), + ); + assert_ok!(SlpV2::::add_delegator(RawOrigin::Root.into(), STAKING_PROTOCOL, None)); + #[extrinsic_call] + _(RawOrigin::Root, STAKING_PROTOCOL, delegator); + Ok(()) + } + + #[benchmark] + fn transfer_back() -> Result<(), BenchmarkError> { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o") + .unwrap() + .into(), + ); + assert_ok!(SlpV2::::add_delegator(RawOrigin::Root.into(), STAKING_PROTOCOL, None)); + do_set_protocol_configuration::(); + #[extrinsic_call] + _(RawOrigin::Root, STAKING_PROTOCOL, delegator, 1000); + Ok(()) + } + + #[benchmark] + fn update_ongoing_time_unit() -> Result<(), BenchmarkError> { + #[extrinsic_call] + _(RawOrigin::Root, STAKING_PROTOCOL, Some(TimeUnit::Era(1))); + Ok(()) + } + + #[benchmark] + fn update_token_exchange_rate() -> Result<(), BenchmarkError> { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o") + .unwrap() + .into(), + ); + assert_ok!(SlpV2::::add_delegator(RawOrigin::Root.into(), STAKING_PROTOCOL, None)); + #[extrinsic_call] + _(RawOrigin::Root, STAKING_PROTOCOL, delegator, 1000); + Ok(()) + } + + #[benchmark] + fn astar_dapp_staking() -> Result<(), BenchmarkError> { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o") + .unwrap() + .into(), + ); + assert_ok!(SlpV2::::add_delegator(RawOrigin::Root.into(), STAKING_PROTOCOL, None)); + do_set_protocol_configuration::(); + let task = DappStaking::Lock(100); + #[extrinsic_call] + _(RawOrigin::Root, delegator, task); + Ok(()) + } + + #[benchmark] + fn notify_astar_dapp_staking() -> Result<(), BenchmarkError> { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o") + .unwrap() + .into(), + ); + assert_ok!(SlpV2::::add_delegator(RawOrigin::Root.into(), STAKING_PROTOCOL, None)); + do_set_protocol_configuration::(); + + PendingStatusByQueryId::::insert( + 0, + PendingStatus::AstarDappStaking(AstarDappStakingPendingStatus::Lock( + delegator.clone(), + 100, + )), + ); + #[extrinsic_call] + _(RawOrigin::Root, 0, xcm::v4::Response::DispatchResult(MaybeErrorCode::Success)); + Ok(()) + } + + impl_benchmark_test_suite!(SlpV2, crate::mock::new_test_ext(), crate::mock::Test); +} diff --git a/pallets/slp-v2/src/common/impls.rs b/pallets/slp-v2/src/common/impls.rs new file mode 100644 index 000000000..336454874 --- /dev/null +++ b/pallets/slp-v2/src/common/impls.rs @@ -0,0 +1,372 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use crate::{ + common::types::{ + Delegator, DelegatorIndex, StakingProtocol, AS_DERIVATIVE_CALL_INDEX, + LIMITED_RESERVE_TRANSFER_ASSETS_CALL_INDEX, + }, + Config, ConfigurationByStakingProtocol, DelegatorByStakingProtocolAndDelegatorIndex, + DelegatorIndexByStakingProtocolAndDelegator, Error, Event, LedgerByStakingProtocolAndDelegator, + NextDelegatorIndexByStakingProtocol, Pallet, ValidatorsByStakingProtocolAndDelegator, +}; +use bifrost_primitives::{Balance, CurrencyId, VtokenMintingOperator}; +use frame_support::{ + dispatch::{DispatchResultWithPostInfo, GetDispatchInfo, RawOrigin}, + ensure, + traits::{EnsureOrigin, Get}, +}; +use frame_system::pallet_prelude::OriginFor; +use orml_traits::{MultiCurrency, XcmTransfer}; +use parity_scale_codec::{Decode, Encode}; +use sp_core::blake2_256; +use sp_runtime::{ + helpers_128bit::multiply_by_rational_with_rounding, traits::TrailingZeroInput, DispatchError, + Rounding, Saturating, +}; +use sp_std::{vec, vec::Vec}; +use xcm::{ + latest::{OriginKind, QueryId, QueryResponseInfo, WeightLimit, WildAsset}, + prelude::{AccountId32, Fungible, Here, ReportTransactStatus}, + v4::{opaque::Xcm, Asset, AssetFilter, AssetId, Assets, Location, SendXcm}, + DoubleEncoded, VersionedAssets, VersionedLocation, +}; + +impl Pallet { + pub fn do_add_delegator( + staking_protocol: StakingProtocol, + delegator: Option>, + ) -> DispatchResultWithPostInfo { + let mut delegator_index = 0; + NextDelegatorIndexByStakingProtocol::::mutate( + staking_protocol, + |index| -> DispatchResultWithPostInfo { + delegator_index = *index; + *index = index.checked_add(1).ok_or(Error::::DelegatorIndexOverflow)?; + let delegator = + delegator.unwrap_or(staking_protocol.get_delegator::(delegator_index)?); + ensure!( + !DelegatorByStakingProtocolAndDelegatorIndex::::contains_key( + staking_protocol, + delegator_index + ), + Error::::DelegatorAlreadyExists + ); + ensure!( + !DelegatorIndexByStakingProtocolAndDelegator::::contains_key( + staking_protocol, + delegator.clone() + ), + Error::::DelegatorIndexAlreadyExists + ); + DelegatorByStakingProtocolAndDelegatorIndex::::insert( + staking_protocol, + delegator_index, + delegator.clone(), + ); + DelegatorIndexByStakingProtocolAndDelegator::::insert( + staking_protocol, + delegator.clone(), + delegator_index, + ); + LedgerByStakingProtocolAndDelegator::::insert( + staking_protocol, + delegator.clone(), + staking_protocol.get_default_ledger(), + ); + Self::deposit_event(Event::AddDelegator { + staking_protocol, + delegator_index, + delegator, + }); + Ok(().into()) + }, + ) + } + + pub fn do_remove_delegator( + staking_protocol: StakingProtocol, + delegator: Delegator, + ) -> DispatchResultWithPostInfo { + let delegator_index = + DelegatorIndexByStakingProtocolAndDelegator::::take(&staking_protocol, &delegator) + .ok_or(Error::::DelegatorIndexNotFound)?; + DelegatorByStakingProtocolAndDelegatorIndex::::remove( + &staking_protocol, + delegator_index, + ); + ValidatorsByStakingProtocolAndDelegator::::remove(&staking_protocol, &delegator); + LedgerByStakingProtocolAndDelegator::::remove(&staking_protocol, &delegator); + Self::deposit_event(Event::RemoveDelegator { + staking_protocol, + delegator_index, + delegator, + }); + Ok(().into()) + } + + pub fn do_transfer_to( + staking_protocol: StakingProtocol, + delegator: Delegator, + ) -> DispatchResultWithPostInfo { + Self::ensure_delegator_exist(&staking_protocol, &delegator)?; + let currency_id = staking_protocol.info().currency_id; + let dest_beneficiary_location = staking_protocol + .get_dest_beneficiary_location::(delegator.clone()) + .ok_or(Error::::UnsupportedStakingProtocol)?; + let (entrance_account, _) = T::VtokenMinting::get_entrance_and_exit_accounts(); + let entrance_account_free_balance = + T::MultiCurrency::free_balance(currency_id, &entrance_account); + T::XcmTransfer::transfer( + entrance_account.clone(), + currency_id, + entrance_account_free_balance, + dest_beneficiary_location, + WeightLimit::Unlimited, + ) + .map_err(|_| Error::::DerivativeAccountIdFailed)?; + Self::deposit_event(Event::TransferTo { + staking_protocol, + from: entrance_account, + to: delegator, + amount: entrance_account_free_balance, + }); + Ok(().into()) + } + + pub fn do_transfer_back( + staking_protocol: StakingProtocol, + delegator: Delegator, + amount: Balance, + ) -> DispatchResultWithPostInfo { + let delegator_index = Self::ensure_delegator_exist(&staking_protocol, &delegator)?; + let (entrance_account, _) = T::VtokenMinting::get_entrance_and_exit_accounts(); + let transfer_back_call_data = + Self::wrap_polkadot_xcm_limited_reserve_transfer_assets_call_data( + &staking_protocol, + amount, + entrance_account.clone(), + )?; + let utility_as_derivative_call_data = Self::wrap_utility_as_derivative_call_data( + &staking_protocol, + delegator_index, + transfer_back_call_data, + ); + let xcm_message = + Self::wrap_xcm_message(&staking_protocol, utility_as_derivative_call_data)?; + Self::send_xcm_message(staking_protocol, xcm_message)?; + Self::deposit_event(Event::TransferBack { + staking_protocol, + from: delegator, + to: entrance_account, + amount, + }); + Ok(().into()) + } + + /// Implemented by Utility pallet to get derived account id + pub fn derivative_account_id( + account_id: T::AccountId, + delegator_index: DelegatorIndex, + ) -> Result> { + let entropy = (b"modlpy/utilisuba", account_id, delegator_index).using_encoded(blake2_256); + let account_id = Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref())) + .map_err(|_| Error::::DerivativeAccountIdFailed)?; + Ok(account_id) + } + + /// Wrapping any runtime call with as_derivative. + pub fn wrap_utility_as_derivative_call_data( + staking_protocol: &StakingProtocol, + delegator_index: DelegatorIndex, + call: Vec, + ) -> Vec { + let utility_pallet_index = staking_protocol.info().utility_pallet_index; + let mut call_data = utility_pallet_index.encode(); + call_data.extend(AS_DERIVATIVE_CALL_INDEX.encode()); + // derivative index + call_data.extend(delegator_index.encode()); + // runtime call + call_data.extend(call); + call_data + } + + /// Wrapping limited_reserve_transfer_assets + pub fn wrap_polkadot_xcm_limited_reserve_transfer_assets_call_data( + staking_protocol: &StakingProtocol, + amount: Balance, + to: T::AccountId, + ) -> Result, Error> { + let xcm_pallet_index = staking_protocol.info().xcm_pallet_index; + let bifrost_dest_location = staking_protocol.info().bifrost_dest_location; + let account_id = + to.encode().try_into().map_err(|_| Error::::DerivativeAccountIdFailed)?; + let beneficiary = Location::new(0, AccountId32 { network: None, id: account_id }); + let fee_asset_item = 0u32; + let weight_limit = WeightLimit::Unlimited; + + let mut calldata = xcm_pallet_index.encode(); + calldata.extend(LIMITED_RESERVE_TRANSFER_ASSETS_CALL_INDEX.encode()); + // bifrost_dest_location + calldata.extend(VersionedLocation::V4(bifrost_dest_location).encode()); + // beneficiary + calldata.extend(VersionedLocation::V4(beneficiary).encode()); + // native asset + amount + calldata.extend( + VersionedAssets::V4(Assets::from(vec![Asset { + id: AssetId(Location::here()), + fun: Fungible(amount), + }])) + .encode(), + ); + // fee_asset_item + calldata.extend(fee_asset_item.encode()); + // weight_limit + calldata.extend(weight_limit.encode()); + Ok(calldata) + } + + /// Wrapping xcm message + /// withdraw_asset + buy_execution + transact + refund_surplus + deposit_asset + pub fn wrap_xcm_message( + staking_protocol: &StakingProtocol, + call: Vec, + ) -> Result> { + let configuration = ConfigurationByStakingProtocol::::get(staking_protocol) + .ok_or(Error::::ConfigurationNotFound)?; + let fee_location = staking_protocol.info().remote_fee_location; + let refund_beneficiary = staking_protocol.info().remote_refund_beneficiary; + let asset = + Asset { id: AssetId(fee_location), fun: Fungible(configuration.xcm_task_fee.fee) }; + let assets: Assets = Assets::from(asset.clone()); + let require_weight_at_most = configuration.xcm_task_fee.weight; + let call: DoubleEncoded<()> = call.into(); + let asset_filter: AssetFilter = AssetFilter::Wild(WildAsset::All); + Ok(Xcm::builder() + .withdraw_asset(assets) + .buy_execution(asset, WeightLimit::Unlimited) + .transact(OriginKind::SovereignAccount, require_weight_at_most, call) + .refund_surplus() + .deposit_asset(asset_filter, refund_beneficiary) + .build()) + } + + /// Wrapping xcm messages with notify + /// withdraw_asset + buy_execution + transact + report_transact_status + refund_surplus + + /// deposit_asset + pub fn wrap_xcm_message_with_notify( + staking_protocol: &StakingProtocol, + call: Vec, + notify_call: ::RuntimeCall, + mut_query_id: &mut Option, + ) -> Result> { + let notify_call_weight = notify_call.get_dispatch_info().weight; + let now = frame_system::Pallet::::block_number(); + let timeout = now.saturating_add(T::QueryTimeout::get()); + let responder = staking_protocol.info().remote_dest_location; + let query_id = + pallet_xcm::Pallet::::new_notify_query(responder, notify_call, timeout, Here); + *mut_query_id = Some(query_id); + let destination = staking_protocol.info().bifrost_dest_location; + let report_transact_status = ReportTransactStatus(QueryResponseInfo { + destination, + query_id, + max_weight: notify_call_weight, + }); + let mut xcm_message = Self::wrap_xcm_message(&staking_protocol, call)?; + xcm_message.0.insert(3, report_transact_status); + Ok(xcm_message) + } + + pub fn send_xcm_message( + staking_protocol: StakingProtocol, + xcm_message: Xcm, + ) -> Result<(), Error> { + let dest_location = staking_protocol.info().remote_dest_location; + let (ticket, _price) = + T::XcmSender::validate(&mut Some(dest_location), &mut Some(xcm_message)) + .map_err(|_| Error::::ValidatingFailed)?; + T::XcmSender::deliver(ticket).map_err(|_| Error::::DeliveringFailed)?; + Ok(()) + } + + pub fn calculate_vtoken_amount_by_token_amount( + vtoken_currency_id: CurrencyId, + currency_id: CurrencyId, + token_amount: Balance, + ) -> Result> { + let vtoken_total_issuance = T::MultiCurrency::total_issuance(vtoken_currency_id); + let token_pool_amount = T::VtokenMinting::get_token_pool(currency_id); + // vtoken_amount / vtoken_total_issuance = token_amount / token_pool_amount + // vtoken_amount = token_amount * vtoken_total_issuance / token_pool_amount + let vtoken_amount = multiply_by_rational_with_rounding( + token_amount, + vtoken_total_issuance, + token_pool_amount, + Rounding::Down, + ) + .ok_or(Error::::CalculateProtocolFeeFailed)?; + Ok(vtoken_amount) + } + + pub fn ensure_governance_or_xcm_response( + origin: OriginFor, + ) -> Result { + let responder = T::ResponseOrigin::ensure_origin(origin.clone()) + .or_else(|_| T::ControlOrigin::ensure_origin(origin).map(|_| Here.into()))?; + Ok(responder) + } + + pub fn ensure_governance_or_operator( + origin: OriginFor, + staking_protocol: StakingProtocol, + ) -> Result<(), Error> { + match origin.clone().into() { + Ok(RawOrigin::Signed(signer)) => { + match ConfigurationByStakingProtocol::::get(staking_protocol) { + Some(c) => { + ensure!(c.operator == signer, Error::::NotAuthorized); + Ok(()) + }, + None => Err(Error::::NotAuthorized), + } + }, + _ => { + T::ControlOrigin::ensure_origin(origin).map_err(|_| Error::::NotAuthorized)?; + Ok(()) + }, + } + } + + pub fn ensure_delegator_exist( + staking_protocol: &StakingProtocol, + delegator: &Delegator, + ) -> Result> { + let delegator_index = + DelegatorIndexByStakingProtocolAndDelegator::::get(staking_protocol, delegator) + .ok_or(Error::::DelegatorIndexNotFound)?; + ensure!( + DelegatorByStakingProtocolAndDelegatorIndex::::contains_key( + staking_protocol, + delegator_index + ), + Error::::DelegatorNotFound + ); + Ok(delegator_index) + } +} diff --git a/pallets/slp-v2/src/common/mod.rs b/pallets/slp-v2/src/common/mod.rs new file mode 100644 index 000000000..b00ddda58 --- /dev/null +++ b/pallets/slp-v2/src/common/mod.rs @@ -0,0 +1,20 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +pub mod impls; +pub mod types; diff --git a/pallets/slp-v2/src/common/types/kusama.rs b/pallets/slp-v2/src/common/types/kusama.rs new file mode 100644 index 000000000..19aba6a09 --- /dev/null +++ b/pallets/slp-v2/src/common/types/kusama.rs @@ -0,0 +1,138 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use crate::{ + common::types::{Delegator, DelegatorIndex, StakingProtocolInfo}, + Config, Error, +}; +use bifrost_primitives::{ + Balance, BifrostKusamaChainId, MoonbeamChainId, MoonriverChainId, TimeUnit, KSM, MOVR, +}; +use frame_support::traits::Get; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use polkadot_parachain_primitives::primitives::Sibling; +use scale_info::TypeInfo; +use sp_core::H160; +use sp_runtime::traits::AccountIdConversion; +use xcm::{ + prelude::{AccountId32, AccountKey20, PalletInstance, Parachain}, + v4::Location, +}; + +/// Supported staking protocols. +#[derive(Encode, Decode, MaxEncodedLen, Clone, Copy, Debug, PartialEq, Eq, TypeInfo)] +pub enum StakingProtocol { + /// ParachainStaking on Moonriver. + MoonriverParachainStaking, + /// Staking on Kusama + KusamaStaking, +} + +impl StakingProtocol { + pub(crate) fn info(&self) -> StakingProtocolInfo { + match self { + StakingProtocol::MoonriverParachainStaking => StakingProtocolInfo { + utility_pallet_index: 30, + xcm_pallet_index: 103, + currency_id: MOVR, + unlock_period: TimeUnit::Round(28), + remote_fee_location: Location::new(0, [PalletInstance(10)]), + remote_refund_beneficiary: Location::new( + 0, + [AccountKey20 { + network: None, + key: Sibling::from(BifrostKusamaChainId::get()).into_account_truncating(), + }], + ), + remote_dest_location: Location::new(1, [Parachain(MoonbeamChainId::get())]), + bifrost_dest_location: Location::new(1, Parachain(BifrostKusamaChainId::get())), + }, + StakingProtocol::KusamaStaking => StakingProtocolInfo { + utility_pallet_index: 24, + xcm_pallet_index: 99, + currency_id: KSM, + unlock_period: TimeUnit::Era(28), + remote_fee_location: Location::here(), + remote_refund_beneficiary: Location::new( + 0, + [Parachain(BifrostKusamaChainId::get())], + ), + remote_dest_location: Location::parent(), + bifrost_dest_location: Location::new(0, Parachain(BifrostKusamaChainId::get())), + }, + } + } + + pub fn get_dest_beneficiary_location( + &self, + delegator: Delegator, + ) -> Option { + match (self, delegator) { + (StakingProtocol::KusamaStaking, Delegator::Substrate(account_id)) => + account_id.encode().try_into().ok().and_then(|account_id| { + Some(Location::new(1, [AccountId32 { network: None, id: account_id }])) + }), + (StakingProtocol::MoonriverParachainStaking, Delegator::Ethereum(account_id)) => + Some(Location::new( + 1, + [ + Parachain(MoonriverChainId::get()), + AccountKey20 { network: None, key: account_id.to_fixed_bytes() }, + ], + )), + _ => None, + } + } + + pub fn get_delegator( + &self, + _delegator_index: DelegatorIndex, + ) -> Result, Error> { + match &self { + _ => unreachable!(), + } + } + + pub fn get_default_ledger(&self) -> Ledger { + match self { + _ => unreachable!(), + } + } +} + +/// Validator in slp protocol. +#[derive(Encode, Decode, MaxEncodedLen, Clone, Debug, PartialEq, Eq, TypeInfo)] +pub enum Validator { + MoonriverParachainStaking(H160), + KusamaStaking(AccountId), +} + +/// Ledger in slp protocol. +#[derive(Encode, Decode, MaxEncodedLen, Clone, Debug, PartialEq, Eq, TypeInfo)] +pub enum Ledger {} + +#[derive(Encode, Decode, MaxEncodedLen, Clone, Copy, Debug, PartialEq, Eq, TypeInfo)] +pub enum XcmTask { + Todo(AccountId), +} + +/// PendingStatus in slp protocol. +#[derive(Encode, Decode, MaxEncodedLen, Clone, Copy, Debug, PartialEq, Eq, TypeInfo)] +pub enum PendingStatus { + Todo(AccountId), +} diff --git a/pallets/slp-v2/src/common/types/mod.rs b/pallets/slp-v2/src/common/types/mod.rs new file mode 100644 index 000000000..9bff6ae28 --- /dev/null +++ b/pallets/slp-v2/src/common/types/mod.rs @@ -0,0 +1,97 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use bifrost_primitives::{Balance, BlockNumber, CurrencyId, TimeUnit}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; +use sp_core::H160; +use sp_runtime::Permill; +use xcm::v4::{Location, Weight}; + +/// Sovereign addresses generate subaccounts via DelegatorIndex +pub type DelegatorIndex = u16; +/// Pallet index in remote chain. +pub type PalletIndex = u8; +/// As derivative call index +pub const AS_DERIVATIVE_CALL_INDEX: u8 = 1; +/// Reserve transfer assets call index +pub const LIMITED_RESERVE_TRANSFER_ASSETS_CALL_INDEX: u8 = 8; + +/// Configuration of the protocol +#[derive(Encode, Decode, MaxEncodedLen, Default, Clone, Debug, PartialEq, Eq, TypeInfo)] +pub struct ProtocolConfiguration { + /// Xcm fee for the task + pub xcm_task_fee: XcmFee, + /// Protocol fee rate + pub protocol_fee_rate: Permill, + /// Unlock period + pub unlock_period: TimeUnit, + /// Staking Protocol operator + pub operator: AccountId, + /// Max update token exchange rate + pub max_update_token_exchange_rate: Permill, + /// Update time unit interval + pub update_time_unit_interval: BlockNumber, + /// Update exchange rate interval + pub update_exchange_rate_interval: BlockNumber, +} + +/// Staking protocol information +#[derive(Encode, Decode, MaxEncodedLen, Default, Clone, Debug, PartialEq, Eq, TypeInfo)] +pub struct StakingProtocolInfo { + /// Utility pallet index + pub utility_pallet_index: PalletIndex, + /// Xcm pallet index + pub xcm_pallet_index: PalletIndex, + /// Currency Id for Staking Protocol + pub currency_id: CurrencyId, + /// Unlock period + pub unlock_period: TimeUnit, + /// Remote chain supports fee location. + pub remote_fee_location: Location, + /// Remote chain supports refund location. + pub remote_refund_beneficiary: Location, + /// Dest location for remote chain + pub remote_dest_location: Location, + /// Bifrost dest location + pub bifrost_dest_location: Location, +} + +/// Delegator account +#[derive(Encode, Decode, MaxEncodedLen, Clone, Copy, Debug, PartialEq, Eq, TypeInfo)] +pub enum Delegator { + /// Substrate account + Substrate(AccountId), + /// Ethereum address. + Ethereum(H160), +} + +#[derive(Encode, Decode, MaxEncodedLen, Default, Clone, Copy, Debug, PartialEq, Eq, TypeInfo)] +pub struct XcmFee { + pub weight: Weight, + pub fee: Balance, +} + +#[cfg(feature = "kusama")] +pub mod kusama; +#[cfg(feature = "kusama")] +pub use kusama::*; +#[cfg(feature = "polkadot")] +pub mod polkadot; +#[cfg(feature = "polkadot")] +pub use polkadot::*; diff --git a/pallets/slp-v2/src/common/types/polkadot.rs b/pallets/slp-v2/src/common/types/polkadot.rs new file mode 100644 index 000000000..a3120a22b --- /dev/null +++ b/pallets/slp-v2/src/common/types/polkadot.rs @@ -0,0 +1,181 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use crate::{ + astar_dapp_staking::types::{ + AstarDappStakingLedger, AstarDappStakingPendingStatus, AstarValidator, DappStaking, + }, + common::types::{Delegator, DelegatorIndex, StakingProtocolInfo}, + Config, Error, +}; +use bifrost_primitives::{ + AstarChainId, BifrostPolkadotChainId, MoonbeamChainId, TimeUnit, ASTR, DOT, GLMR, +}; +use frame_support::traits::Get; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use polkadot_parachain_primitives::primitives::Sibling; +use scale_info::TypeInfo; +use sp_core::H160; +use sp_runtime::traits::AccountIdConversion; +use xcm::{ + prelude::{AccountId32, AccountKey20, PalletInstance, Parachain}, + v4::Location, +}; + +/// Supported staking protocols. +#[derive(Encode, Decode, MaxEncodedLen, Clone, Copy, Debug, PartialEq, Eq, TypeInfo)] +pub enum StakingProtocol { + /// DappStaking on Astar. + AstarDappStaking, + /// ParachainStaking on Moonbeam. + MoonbeamParachainStaking, + /// Staking on Polkadot + PolkadotStaking, +} + +impl StakingProtocol { + pub(crate) fn info(&self) -> StakingProtocolInfo { + match self { + StakingProtocol::AstarDappStaking => StakingProtocolInfo { + utility_pallet_index: 11, + xcm_pallet_index: 51, + currency_id: ASTR, + unlock_period: TimeUnit::Era(9), + remote_fee_location: Location::here(), + remote_refund_beneficiary: Location::new( + 0, + [AccountId32 { + network: None, + id: Sibling::from(2030).into_account_truncating(), + }], + ), + remote_dest_location: Location::new(1, [Parachain(AstarChainId::get())]), + bifrost_dest_location: Location::new(1, Parachain(BifrostPolkadotChainId::get())), + }, + StakingProtocol::MoonbeamParachainStaking => StakingProtocolInfo { + utility_pallet_index: 30, + xcm_pallet_index: 103, + currency_id: GLMR, + unlock_period: TimeUnit::Round(28), + remote_fee_location: Location::new(0, [PalletInstance(10)]), + remote_refund_beneficiary: Location::new( + 0, + [AccountKey20 { + network: None, + key: Sibling::from(2030).into_account_truncating(), + }], + ), + remote_dest_location: Location::new(1, [Parachain(MoonbeamChainId::get())]), + bifrost_dest_location: Location::new(1, Parachain(BifrostPolkadotChainId::get())), + }, + StakingProtocol::PolkadotStaking => StakingProtocolInfo { + utility_pallet_index: 26, + xcm_pallet_index: 99, + currency_id: DOT, + unlock_period: TimeUnit::Era(28), + remote_fee_location: Location::here(), + remote_refund_beneficiary: Location::new( + 0, + [Parachain(BifrostPolkadotChainId::get())], + ), + remote_dest_location: Location::parent(), + bifrost_dest_location: Location::new(0, Parachain(BifrostPolkadotChainId::get())), + }, + } + } + + pub fn get_dest_beneficiary_location( + &self, + delegator: Delegator, + ) -> Option { + match (self, delegator) { + (StakingProtocol::AstarDappStaking, Delegator::Substrate(account_id)) => + account_id.encode().try_into().ok().and_then(|account_id| { + Some(Location::new( + 1, + [ + Parachain(AstarChainId::get()), + AccountId32 { network: None, id: account_id }, + ], + )) + }), + (StakingProtocol::PolkadotStaking, Delegator::Substrate(account_id)) => + account_id.encode().try_into().ok().and_then(|account_id| { + Some(Location::new(1, [AccountId32 { network: None, id: account_id }])) + }), + (StakingProtocol::MoonbeamParachainStaking, Delegator::Ethereum(account_id)) => + Some(Location::new( + 1, + [ + Parachain(MoonbeamChainId::get()), + AccountKey20 { network: None, key: account_id.to_fixed_bytes() }, + ], + )), + _ => None, + } + } + + pub fn get_delegator( + &self, + delegator_index: DelegatorIndex, + ) -> Result, Error> { + match &self { + StakingProtocol::AstarDappStaking => { + let sub_sibling_account = crate::Pallet::::derivative_account_id( + Sibling::from(T::ParachainId::get()).into_account_truncating(), + delegator_index, + )?; + Ok(Delegator::Substrate(sub_sibling_account)) + }, + _ => Err(Error::::UnsupportedStakingProtocol), + } + } + + pub fn get_default_ledger(&self) -> Ledger { + match self { + StakingProtocol::AstarDappStaking => + Ledger::AstarDappStaking(AstarDappStakingLedger::default()), + _ => unreachable!(), + } + } +} + +/// Validator in slp protocol. +#[derive(Encode, Decode, MaxEncodedLen, Clone, Debug, PartialEq, Eq, TypeInfo)] +pub enum Validator { + AstarDappStaking(AstarValidator), + MoonbeamParachainStaking(H160), + PolkadotStaking(AccountId), +} + +/// Ledger in slp protocol. +#[derive(Encode, Decode, MaxEncodedLen, Clone, Debug, PartialEq, Eq, TypeInfo)] +pub enum Ledger { + AstarDappStaking(AstarDappStakingLedger), +} + +#[derive(Encode, Decode, MaxEncodedLen, Clone, Copy, Debug, PartialEq, Eq, TypeInfo)] +pub enum XcmTask { + AstarDappStaking(DappStaking), +} + +/// PendingStatus in slp protocol. +#[derive(Encode, Decode, MaxEncodedLen, Clone, Copy, Debug, PartialEq, Eq, TypeInfo)] +pub enum PendingStatus { + AstarDappStaking(AstarDappStakingPendingStatus), +} diff --git a/pallets/slp-v2/src/lib.rs b/pallets/slp-v2/src/lib.rs new file mode 100644 index 000000000..ce08dca9a --- /dev/null +++ b/pallets/slp-v2/src/lib.rs @@ -0,0 +1,765 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "polkadot")] +use astar_dapp_staking::types::DappStaking; +use bifrost_primitives::{ + Balance, BlockNumber, CurrencyId, CurrencyIdConversion, TimeUnit, VtokenMintingOperator, +}; +use common::types::{Delegator, DelegatorIndex, ProtocolConfiguration}; +use frame_support::{ + dispatch::{DispatchResultWithPostInfo, GetDispatchInfo}, + pallet_prelude::*, + PalletId, +}; +use frame_system::pallet_prelude::*; +use orml_traits::{MultiCurrency, XcmTransfer}; +use polkadot_parachain_primitives::primitives::Id as ParaId; +use sp_runtime::traits::AccountIdConversion; +pub use weights::WeightInfo; +use xcm::v4::{Location, SendXcm}; + +pub use pallet::*; + +#[cfg(test)] +mod mock; + +#[cfg(feature = "polkadot")] +mod astar_dapp_staking; +mod common; +#[cfg(test)] +mod tests; +pub mod weights; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use crate::common::types::{Ledger, PendingStatus, StakingProtocol, Validator, XcmTask}; + use sp_runtime::{traits::BlockNumberProvider, Permill}; + use xcm::latest::{MaybeErrorCode, QueryId, Response}; + + #[pallet::config] + pub trait Config: frame_system::Config + pallet_xcm::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + type RuntimeOrigin: IsType<::RuntimeOrigin> + + Into::RuntimeOrigin>>; + type RuntimeCall: IsType<::RuntimeCall> + + From> + + GetDispatchInfo; + type ResponseOrigin: EnsureOrigin< + ::RuntimeOrigin, + Success = Location, + >; + type WeightInfo: weights::WeightInfo; + type MultiCurrency: MultiCurrency< + Self::AccountId, + Balance = Balance, + CurrencyId = CurrencyId, + >; + /// The only origin that can modify pallet params + type ControlOrigin: EnsureOrigin<::RuntimeOrigin>; + /// Xcm sender. + type XcmSender: SendXcm; + /// XTokens transfer interface + type XcmTransfer: XcmTransfer; + /// The interface to call VtokenMinting module functions. + type VtokenMinting: VtokenMintingOperator; + /// The currency id conversion. + type CurrencyIdConversion: CurrencyIdConversion; + /// The current block number provider. + type RelaychainBlockNumberProvider: BlockNumberProvider; + /// The query timeout. + #[pallet::constant] + type QueryTimeout: Get>; + /// Commission master Pallet Id to get the commission master account + #[pallet::constant] + type CommissionPalletId: Get; + /// Bifrost parachain id. + #[pallet::constant] + type ParachainId: Get; + /// Maximum validators + #[pallet::constant] + type MaxValidators: Get; + } + + #[pallet::pallet] + pub struct Pallet(_); + + /// Configuration for different staking protocols. + #[pallet::storage] + pub type ConfigurationByStakingProtocol = StorageMap< + _, + Blake2_128Concat, + StakingProtocol, + ProtocolConfiguration, + OptionQuery, + >; + + /// StakingProtocol + DelegatorIndex => Delegator + #[pallet::storage] + pub type DelegatorByStakingProtocolAndDelegatorIndex = StorageDoubleMap< + _, + Blake2_128Concat, + StakingProtocol, + Blake2_128Concat, + DelegatorIndex, + Delegator, + OptionQuery, + >; + + /// StakingProtocol + Delegator => DelegatorIndex + #[pallet::storage] + pub type DelegatorIndexByStakingProtocolAndDelegator = StorageDoubleMap< + _, + Blake2_128Concat, + StakingProtocol, + Blake2_128Concat, + Delegator, + DelegatorIndex, + OptionQuery, + >; + + /// StakingProtocol + DelegatorIndex => Delegator + #[pallet::storage] + pub type LedgerByStakingProtocolAndDelegator = StorageDoubleMap< + _, + Blake2_128Concat, + StakingProtocol, + Blake2_128Concat, + Delegator, + Ledger, + OptionQuery, + >; + + /// Validators for different staking protocols. + #[pallet::storage] + pub type ValidatorsByStakingProtocolAndDelegator = StorageDoubleMap< + _, + Blake2_128Concat, + StakingProtocol, + Blake2_128Concat, + Delegator, + BoundedVec, T::MaxValidators>, + ValueQuery, + >; + + /// Next index of different staking protocols. + #[pallet::storage] + pub type NextDelegatorIndexByStakingProtocol = + StorageMap<_, Blake2_128Concat, StakingProtocol, DelegatorIndex, ValueQuery>; + + /// Pending status for different query id. + #[pallet::storage] + pub type PendingStatusByQueryId = + StorageMap<_, Blake2_128Concat, QueryId, PendingStatus, OptionQuery>; + + /// Last update ongoing time unit block number for different staking protocols. + #[pallet::storage] + pub type LastUpdateOngoingTimeUnitBlockNumber = + StorageMap<_, Blake2_128Concat, StakingProtocol, BlockNumber, ValueQuery>; + + /// Last update token exchange rate block number for different staking protocols. + #[pallet::storage] + pub type LastUpdateTokenExchangeRateBlockNumber = StorageDoubleMap< + _, + Blake2_128Concat, + StakingProtocol, + Blake2_128Concat, + Delegator, + BlockNumber, + ValueQuery, + >; + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// Add a delegator to the staking protocol. + AddDelegator { + /// Slp supports staking protocols. + staking_protocol: StakingProtocol, + /// Delegator index. + delegator_index: DelegatorIndex, + /// Delegator account. + delegator: Delegator, + }, + /// Remove a delegator from the staking protocol. + RemoveDelegator { + /// Slp supports staking protocols. + staking_protocol: StakingProtocol, + /// Delegator index. + delegator_index: DelegatorIndex, + /// Delegator account. + delegator: Delegator, + }, + /// Add a validator to the staking protocol. + AddValidator { + /// Slp supports staking protocols. + staking_protocol: StakingProtocol, + /// Delegator account. + delegator: Delegator, + /// Validator account. + validator: Validator, + }, + /// Remove a validator from the staking protocol. + RemoveValidator { + /// Slp supports staking protocols. + staking_protocol: StakingProtocol, + /// Delegator account. + delegator: Delegator, + /// Validator account. + validator: Validator, + }, + /// Set configuration for a specific staking protocol. + SetConfiguration { + /// Slp supports staking protocols. + staking_protocol: StakingProtocol, + /// The staking protocol configuration. + configuration: ProtocolConfiguration, + }, + /// Set ledger for a specific delegator. + SetLedger { + /// Slp supports staking protocols. + staking_protocol: StakingProtocol, + /// Delegator account. + delegator: Delegator, + /// Ledger. + ledger: Ledger, + }, + /// Send xcm task. + SendXcmTask { + /// Xcm Message Query id. + query_id: Option, + /// Delegator account. + delegator: Delegator, + /// Xcm task. + task: XcmTask, + /// Pending confirmation status. + pending_status: Option>, + /// Destination. + dest_location: Location, + }, + /// Xcm task response received. + NotifyResponseReceived { + /// Xcm responder. + responder: Location, + /// Pending confirmation status. + pending_status: PendingStatus, + }, + /// Time unit updated. + TimeUnitUpdated { + /// Slp supports staking protocols. + staking_protocol: StakingProtocol, + /// Time unit. + time_unit: TimeUnit, + }, + /// Token exchange rate updated. + TokenExchangeRateUpdated { + /// Slp supports staking protocols. + staking_protocol: StakingProtocol, + /// Delegator account. + delegator: Delegator, + /// The type of token that the fee is charged to + protocol_fee_currency_id: CurrencyId, + /// The amount of the fee charged to the protocol + protocol_fee: Balance, + /// Amount of exchange rates updated + amount: Balance, + }, + /// Transfer the staking token to remote chain. + TransferTo { + /// Slp supports staking protocols. + staking_protocol: StakingProtocol, + /// Bifrost Account + from: T::AccountId, + /// Delegator account. + to: Delegator, + /// Amount + amount: Balance, + }, + /// Transfer the staking token back from remote chain. + TransferBack { + /// Slp supports staking protocols. + staking_protocol: StakingProtocol, + /// Delegator account. + from: Delegator, + /// Bifrost Account. + to: T::AccountId, + /// Amount + amount: Balance, + }, + } + + #[pallet::error] + pub enum Error { + /// Delegator index has exceeded the maximum allowed value of 65535. + DelegatorIndexOverflow, + /// The maximum number of validators has been reached. + ValidatorsOverflow, + /// UnlockRecordOverflow + UnlockRecordOverflow, + /// The staking protocol is not supported. + UnsupportedStakingProtocol, + /// The delegator index was not found. + DelegatorIndexNotFound, + /// The Configuration was not found. + ConfigurationNotFound, + /// The delegator was not found. + DelegatorNotFound, + /// The ledger was not found. + LedgerNotFound, + /// The validator was not found. + ValidatorNotFound, + /// Missing XCM fee value. + XcmFeeNotFound, + /// Missing pending status. + PendingStatusNotFound, + /// The specified time unit does not exist. + TimeUnitNotFound, + /// The delegator already exists. + DelegatorAlreadyExists, + /// The delegator index already exists. + DelegatorIndexAlreadyExists, + /// The validator already exists. + ValidatorAlreadyExists, + /// Failed to derive the derivative account ID. + DerivativeAccountIdFailed, + /// Error during validation. + ValidatingFailed, + /// Error during delivery. + DeliveringFailed, + /// calculate protocol fee failed. + CalculateProtocolFeeFailed, + /// IncreaseTokenPoolFailed + IncreaseTokenPoolFailed, + /// The update interval is too short. + UpdateIntervalTooShort, + /// The specified token exchange rate amount is too large. + UpdateTokenExchangeRateAmountTooLarge, + /// Invalid parameter. + InvalidParameter, + /// Not authorized. + NotAuthorized, + } + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + /// Set the XCM fee for a specific XCM task. + /// + /// Can only be called by governance + /// + /// Parameters + /// - `staking_protocol`: Slp supports staking protocols. + /// - `configuration`: The staking protocol configuration. + #[pallet::call_index(0)] + #[pallet::weight(::WeightInfo::set_protocol_configuration())] + pub fn set_protocol_configuration( + origin: OriginFor, + staking_protocol: StakingProtocol, + configuration: ProtocolConfiguration, + ) -> DispatchResultWithPostInfo { + T::ControlOrigin::ensure_origin(origin)?; + ConfigurationByStakingProtocol::::mutate( + staking_protocol, + |storage_configuration| -> DispatchResultWithPostInfo { + ensure!( + Some(configuration.clone()).ne(storage_configuration), + Error::::InvalidParameter + ); + *storage_configuration = Some(configuration.clone()); + Self::deposit_event(Event::SetConfiguration { + staking_protocol, + configuration, + }); + Ok(().into()) + }, + ) + } + + /// Add a delegator to the staking protocol. + /// + /// Can only be called by governance + /// + /// Parameters + /// - `staking_protocol`: Slp supports staking protocols. + /// - `delegator`: If delegator is None, the delegator will be derived from sovereign + /// account. + #[pallet::call_index(1)] + #[pallet::weight(::WeightInfo::add_delegator())] + pub fn add_delegator( + origin: OriginFor, + staking_protocol: StakingProtocol, + delegator: Option>, + ) -> DispatchResultWithPostInfo { + T::ControlOrigin::ensure_origin(origin)?; + Self::do_add_delegator(staking_protocol, delegator) + } + + /// Remove a delegator from the staking protocol. + /// + /// Can only be called by governance + /// + /// Parameters + /// - `staking_protocol`: Slp supports staking protocols. + /// - `delegator`: Delegator that need to be removed. + #[pallet::call_index(2)] + #[pallet::weight(::WeightInfo::remove_delegator())] + pub fn remove_delegator( + origin: OriginFor, + staking_protocol: StakingProtocol, + delegator: Delegator, + ) -> DispatchResultWithPostInfo { + T::ControlOrigin::ensure_origin(origin)?; + Self::do_remove_delegator(staking_protocol, delegator) + } + + /// Add a validator to the staking protocol. + /// + /// Can only be called by governance + /// + /// Parameters + /// - `staking_protocol`: Slp supports staking protocols. + /// - `delegator`: Select the delegator which is existed. + /// - `validator`: Validator that need to be added. + #[pallet::call_index(3)] + #[pallet::weight(::WeightInfo::add_validator())] + pub fn add_validator( + origin: OriginFor, + staking_protocol: StakingProtocol, + delegator: Delegator, + validator: Validator, + ) -> DispatchResultWithPostInfo { + T::ControlOrigin::ensure_origin(origin)?; + Self::ensure_delegator_exist(&staking_protocol, &delegator)?; + ValidatorsByStakingProtocolAndDelegator::::mutate( + staking_protocol, + delegator.clone(), + |validators| -> DispatchResultWithPostInfo { + ensure!(!validators.contains(&validator), Error::::ValidatorAlreadyExists); + validators + .try_push(validator.clone()) + .map_err(|_| Error::::ValidatorsOverflow)?; + Self::deposit_event(Event::::AddValidator { + staking_protocol, + delegator, + validator, + }); + Ok(().into()) + }, + ) + } + + /// Remove a validator from the staking protocol. + /// + /// Can only be called by governance + /// + /// Parameters + /// - `staking_protocol`: Slp supports staking protocols. + /// - `delegator`: Select the delegator which is existed. + /// - `validator`: Validator that need to be removed. + #[pallet::call_index(4)] + #[pallet::weight(::WeightInfo::remove_validator())] + pub fn remove_validator( + origin: OriginFor, + staking_protocol: StakingProtocol, + delegator: Delegator, + validator: Validator, + ) -> DispatchResultWithPostInfo { + T::ControlOrigin::ensure_origin(origin)?; + Self::ensure_delegator_exist(&staking_protocol, &delegator)?; + ValidatorsByStakingProtocolAndDelegator::::mutate( + staking_protocol, + delegator.clone(), + |validators| -> DispatchResultWithPostInfo { + ensure!(validators.contains(&validator), Error::::ValidatorNotFound); + validators.retain(|v| *v != validator); + Self::deposit_event(Event::::RemoveValidator { + staking_protocol, + delegator, + validator, + }); + Ok(().into()) + }, + ) + } + + /// Set the update token exchange rate limit for a specific staking protocol. + /// + /// Can only be called by governance. + /// + /// Parameters + /// - `staking_protocol`: Slp supports staking protocols. + /// - `delegator`: Select the delegator which is existed. + /// - `ledger`: Ledger that need to be set. + #[pallet::call_index(5)] + #[pallet::weight(::WeightInfo::set_ledger())] + pub fn set_ledger( + origin: OriginFor, + staking_protocol: StakingProtocol, + delegator: Delegator, + ledger: Ledger, + ) -> DispatchResultWithPostInfo { + T::ControlOrigin::ensure_origin(origin)?; + Self::ensure_delegator_exist(&staking_protocol, &delegator)?; + LedgerByStakingProtocolAndDelegator::::mutate( + staking_protocol, + delegator.clone(), + |storage_ledger| -> DispatchResultWithPostInfo { + ensure!(Some(ledger.clone()).ne(storage_ledger), Error::::InvalidParameter); + *storage_ledger = Some(ledger.clone()); + Self::deposit_event(Event::SetLedger { staking_protocol, delegator, ledger }); + Ok(().into()) + }, + ) + } + + /// Transfer the staking token to remote chain. + /// Transfer the free balance of the Entrance Account to the selected delegator. + /// + /// Can be called by governance or staking protocol operator. + /// + /// Parameters + /// - `staking_protocol`: Slp supports staking protocols. + /// - `delegator`: Select the delegator which is existed. + #[pallet::call_index(6)] + #[pallet::weight(::WeightInfo::transfer_to())] + pub fn transfer_to( + origin: OriginFor, + staking_protocol: StakingProtocol, + delegator: Delegator, + ) -> DispatchResultWithPostInfo { + Self::ensure_governance_or_operator(origin, staking_protocol)?; + Self::do_transfer_to(staking_protocol, delegator) + } + + /// Transfer the staking token back from remote chain. + /// Transfer the amount of tokens from the selected delegator back to the entrance account. + /// + /// Can be called by governance or staking protocol operator. + /// + /// Parameters + /// - `staking_protocol`: Slp supports staking protocols. + /// - `delegator`: Select the delegator which is existed. + /// - `amount`: The amount of tokens to transfer back. + #[pallet::call_index(7)] + #[pallet::weight(::WeightInfo::transfer_back())] + pub fn transfer_back( + origin: OriginFor, + staking_protocol: StakingProtocol, + delegator: Delegator, + amount: Balance, + ) -> DispatchResultWithPostInfo { + Self::ensure_governance_or_operator(origin, staking_protocol)?; + Self::do_transfer_back(staking_protocol, delegator, amount) + } + + /// Update the ongoing time unit for a specific staking protocol. + /// Update frequency controlled by update_time_unit_interval. + /// Less than update_time_unit_interval will report an error. + /// + /// Can be called by governance or staking protocol operator. + /// + /// Parameters + /// - `staking_protocol`: Slp supports staking protocols. + /// - `time_uint_option`: If time_uint is None, the ongoing time unit will be increased by + /// one. Otherwise, the ongoing time unit will be updated to the specified time unit. + #[pallet::call_index(8)] + #[pallet::weight(::WeightInfo::update_ongoing_time_unit())] + pub fn update_ongoing_time_unit( + origin: OriginFor, + staking_protocol: StakingProtocol, + time_uint_option: Option, + ) -> DispatchResultWithPostInfo { + Self::ensure_governance_or_operator(origin, staking_protocol)?; + let current_block_number = T::RelaychainBlockNumberProvider::current_block_number(); + let update_interval = match ConfigurationByStakingProtocol::::get(staking_protocol) { + Some(configuration) => configuration.update_time_unit_interval, + None => 0, + }; + let last_update_block_number = + LastUpdateOngoingTimeUnitBlockNumber::::get(staking_protocol); + ensure!( + current_block_number >= last_update_block_number + update_interval, + Error::::UpdateIntervalTooShort + ); + + let currency_id = staking_protocol.info().currency_id; + + let time_unit = match time_uint_option { + Some(time_unit) => time_unit, + None => { + let current_time_unit = T::VtokenMinting::get_ongoing_time_unit(currency_id) + .ok_or(Error::::TimeUnitNotFound)?; + current_time_unit.add_one() + }, + }; + T::VtokenMinting::update_ongoing_time_unit(currency_id, time_unit.clone())?; + LastUpdateOngoingTimeUnitBlockNumber::::insert( + staking_protocol, + current_block_number, + ); + Self::deposit_event(Event::::TimeUnitUpdated { staking_protocol, time_unit }); + Ok(().into()) + } + + /// Update the token exchange rate for a specific staking protocol. + /// Update frequency controlled by update_exchange_rate_interval. + /// Amount max update for token pool * max_update_token_exchange_rate. + /// + /// Can be called by governance or staking protocol operator. + /// + /// Parameters + /// - `staking_protocol`: Slp supports staking protocols. + /// - `delegator`: Select the delegator which is existed. + /// - `amount`: The amount of tokens to update the token exchange rate. + #[pallet::call_index(9)] + #[pallet::weight(::WeightInfo::update_token_exchange_rate())] + pub fn update_token_exchange_rate( + origin: OriginFor, + staking_protocol: StakingProtocol, + delegator: Delegator, + amount: Balance, + ) -> DispatchResultWithPostInfo { + Self::ensure_governance_or_operator(origin, staking_protocol)?; + let currency_id = staking_protocol.info().currency_id; + + // Check the update token exchange rate limit. + let (update_interval, max_update_permill, protocol_fee_rate) = + match ConfigurationByStakingProtocol::::get(staking_protocol) { + Some(configuration) => ( + configuration.update_exchange_rate_interval, + configuration.max_update_token_exchange_rate, + configuration.protocol_fee_rate, + ), + None => (0, Permill::zero(), Permill::zero()), + }; + let current_block_number = T::RelaychainBlockNumberProvider::current_block_number(); + let last_update_block_number = LastUpdateTokenExchangeRateBlockNumber::::get( + staking_protocol, + delegator.clone(), + ); + ensure!( + current_block_number >= last_update_block_number + update_interval, + Error::::UpdateIntervalTooShort + ); + let pool_token_amount = T::VtokenMinting::get_token_pool(currency_id); + let max_amount = max_update_permill.mul_floor(pool_token_amount); + ensure!( + amount <= max_amount || max_amount == 0, + Error::::UpdateTokenExchangeRateAmountTooLarge + ); + + // Charge the protocol fee. + let mut protocol_fee = protocol_fee_rate.mul_floor(amount); + let protocol_fee_currency_id = T::CurrencyIdConversion::convert_to_vtoken(currency_id) + .map_err(|_| Error::::DerivativeAccountIdFailed)?; + if protocol_fee != 0 { + protocol_fee = Self::calculate_vtoken_amount_by_token_amount( + protocol_fee_currency_id, + currency_id, + protocol_fee, + )?; + let protocol_fee_receiver = T::CommissionPalletId::get().into_account_truncating(); + T::MultiCurrency::deposit( + protocol_fee_currency_id, + &protocol_fee_receiver, + protocol_fee, + )?; + } + + // Update the token exchange rate. + T::VtokenMinting::increase_token_pool(currency_id, amount) + .map_err(|_| Error::::IncreaseTokenPoolFailed)?; + LedgerByStakingProtocolAndDelegator::::mutate( + staking_protocol, + delegator.clone(), + |ledger| match ledger { + #[cfg(feature = "polkadot")] + Some(Ledger::AstarDappStaking(astar_dapp_staking_ledger)) => { + astar_dapp_staking_ledger.add_lock_amount(amount); + Ok(()) + }, + _ => Err(Error::::LedgerNotFound), + }, + )?; + + LastUpdateTokenExchangeRateBlockNumber::::insert( + staking_protocol, + delegator.clone(), + current_block_number, + ); + Self::deposit_event(Event::::TokenExchangeRateUpdated { + staking_protocol, + delegator, + protocol_fee_currency_id, + protocol_fee, + amount, + }); + Ok(().into()) + } + + /// Manipulate a delegator to perform Dapp staking related operations. + /// + /// Can be called by governance or staking protocol operator. + /// + /// Parameters + /// - `staking_protocol`: Slp supports staking protocols. + /// - `delegator`: Select the delegator which is existed. + /// - `task`: The Dapp staking task. + #[cfg(feature = "polkadot")] + #[pallet::call_index(10)] + #[pallet::weight(::WeightInfo::astar_dapp_staking())] + pub fn astar_dapp_staking( + origin: OriginFor, + delegator: Delegator, + task: DappStaking, + ) -> DispatchResultWithPostInfo { + Self::ensure_governance_or_operator(origin, StakingProtocol::AstarDappStaking)?; + Self::do_dapp_staking(delegator, task) + } + + /// Processing Xcm message execution results. + /// + /// Can be called by governance or xcm origin. + #[cfg(feature = "polkadot")] + #[pallet::call_index(11)] + #[pallet::weight(::WeightInfo::notify_astar_dapp_staking())] + pub fn notify_astar_dapp_staking( + origin: OriginFor, + query_id: QueryId, + response: Response, + ) -> DispatchResultWithPostInfo { + let responder = Self::ensure_governance_or_xcm_response(origin)?; + let pending_status = PendingStatusByQueryId::::get(query_id) + .ok_or(Error::::PendingStatusNotFound)?; + if Response::DispatchResult(MaybeErrorCode::Success) == response { + Self::do_notify_astar_dapp_staking(responder, pending_status)?; + } else { + PendingStatusByQueryId::::remove(query_id); + } + Ok(().into()) + } + } +} diff --git a/pallets/slp-v2/src/mock.rs b/pallets/slp-v2/src/mock.rs new file mode 100644 index 000000000..8104a81e8 --- /dev/null +++ b/pallets/slp-v2/src/mock.rs @@ -0,0 +1,319 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use crate as slp_v2; +use bifrost_asset_registry::AssetIdMaps; +use bifrost_primitives::{ + Amount, Balance, BlockNumber, CurrencyId, MockXcmRouter, MockXcmTransfer, SlpOperator, + SlpxOperator, BNC, DOT, +}; +use frame_support::{ + derive_impl, + pallet_prelude::{ConstU32, Get}, + parameter_types, + traits::{Everything, Nothing}, + PalletId, +}; +use frame_system as system; +use frame_system::EnsureRoot; +use hex_literal::hex; +use pallet_xcm::EnsureResponse; +use polkadot_parachain_primitives::primitives::Id as ParaId; +use sp_core::{crypto::AccountId32, ConstU64}; +use sp_runtime::{ + traits::{BlockNumberProvider, IdentityLookup}, + BuildStorage, +}; +use xcm::{ + prelude::Parachain, + v4::{InteriorLocation, Weight}, +}; +use xcm_builder::{FixedWeightBounds, FrameTransactionalProcessor}; +use xcm_executor::XcmExecutor; + +pub type AccountId = AccountId32; +type Block = frame_system::mocking::MockBlock; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system, + AssetRegistry: bifrost_asset_registry, + Currencies: bifrost_currencies, + VtokenMinting: bifrost_vtoken_minting, + Balances: pallet_balances, + Tokens: orml_tokens, + PolkadotXcm: pallet_xcm, + SlpV2: slp_v2, + } +); + +parameter_types! { + pub const SS58Prefix: u8 = 6; +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] +impl system::Config for Test { + type Block = Block; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type AccountData = pallet_balances::AccountData; +} + +parameter_types! { + pub const ExistentialDeposit: Balance = 1; +} + +impl pallet_balances::Config for Test { + type AccountStore = frame_system::Pallet; + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); + type RuntimeHoldReason = RuntimeHoldReason; + type RuntimeFreezeReason = RuntimeFreezeReason; + type FreezeIdentifier = (); + type MaxFreezes = ConstU32<0>; +} + +impl bifrost_asset_registry::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type RegisterOrigin = EnsureRoot; + type WeightInfo = (); +} + +orml_traits::parameter_type_with_key! { + pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { + 0 + }; +} + +impl orml_tokens::Config for Test { + type Amount = Amount; + type Balance = Balance; + type CurrencyId = CurrencyId; + type DustRemovalWhitelist = Nothing; + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposits = ExistentialDeposits; + type MaxLocks = ConstU32<50>; + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); + type CurrencyHooks = (); +} + +parameter_types! { + pub const GetNativeCurrencyId: CurrencyId = BNC; +} + +pub type AdaptedBasicCurrency = + bifrost_currencies::BasicCurrencyAdapter; + +impl bifrost_currencies::Config for Test { + type GetNativeCurrencyId = GetNativeCurrencyId; + type MultiCurrency = Tokens; + type NativeCurrency = AdaptedBasicCurrency; + type WeightInfo = (); +} + +parameter_types! { + // One XCM operation is 200_000_000 XcmWeight, cross-chain transfer ~= 2x of transfer = 3_000_000_000 + pub UnitWeightCost: Weight = Weight::from_parts(200_000_000, 0); + pub const MaxInstructions: u32 = 100; + pub UniversalLocation: InteriorLocation = Parachain(2030).into(); + pub CommissionPalletId: PalletId = PalletId(*b"bf/comms"); +} + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type AssetClaims = PolkadotXcm; + type AssetTransactor = (); + type AssetTrap = PolkadotXcm; + type Barrier = (); + type RuntimeCall = RuntimeCall; + type IsReserve = (); + type IsTeleporter = (); + type UniversalLocation = UniversalLocation; + type OriginConverter = (); + type ResponseHandler = PolkadotXcm; + type SubscriptionService = PolkadotXcm; + type Trader = (); + type Weigher = FixedWeightBounds; + type XcmSender = (); + type PalletInstancesInfo = AllPalletsWithSystem; + type MaxAssetsIntoHolding = ConstU32<64>; + type FeeManager = (); + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; + type AssetLocker = (); + type AssetExchanger = (); + type Aliasers = Nothing; + type TransactionalProcessor = FrameTransactionalProcessor; + type HrmpNewChannelOpenRequestHandler = (); + type HrmpChannelAcceptedHandler = (); + type HrmpChannelClosingHandler = (); + type XcmRecorder = (); +} + +impl pallet_xcm::Config for Test { + type RuntimeEvent = RuntimeEvent; + type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; + type UniversalLocation = UniversalLocation; + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + type Weigher = FixedWeightBounds; + type XcmExecuteFilter = Nothing; + type XcmExecutor = XcmExecutor; + type XcmReserveTransferFilter = Everything; + type XcmRouter = MockXcmRouter; + type XcmTeleportFilter = Nothing; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = ConstU32<2>; + type Currency = Balances; + type CurrencyMatcher = (); + type TrustedLockers = (); + type SovereignAccountOf = (); + type MaxLockers = ConstU32<8>; + type WeightInfo = pallet_xcm::TestWeightInfo; + type AdminOrigin = EnsureRoot; + type MaxRemoteLockConsumers = ConstU32<0>; + type RemoteLockConsumerIdentifier = (); +} + +pub struct ParachainId; +impl Get for ParachainId { + fn get() -> ParaId { + 2030.into() + } +} + +// Pallet vtoken-minting configuration +parameter_types! { + pub const MaximumUnlockIdOfUser: u32 = 10; + pub const MaximumUnlockIdOfTimeUnit: u32 = 50; + pub BifrostEntranceAccount: PalletId = PalletId(*b"bf/vtkin"); + pub BifrostExitAccount: PalletId = PalletId(*b"bf/vtout"); + pub BifrostFeeAccount: AccountId = hex!["e4da05f08e89bf6c43260d96f26fffcfc7deae5b465da08669a9d008e64c2c63"].into(); + pub const RelayCurrencyId: CurrencyId = DOT; + pub IncentivePoolAccount: PalletId = PalletId(*b"bf/inpoo"); +} + +pub struct SlpxInterface; +impl SlpxOperator for SlpxInterface { + fn get_moonbeam_transfer_to_fee() -> Balance { + Default::default() + } +} + +pub struct MockSlp; +impl SlpOperator for MockSlp { + fn all_delegation_requests_occupied(_currency_id: CurrencyId) -> bool { + true + } +} + +impl bifrost_vtoken_minting::Config for Test { + type RuntimeEvent = RuntimeEvent; + type MultiCurrency = Currencies; + type ControlOrigin = EnsureRoot; + type MaximumUnlockIdOfUser = MaximumUnlockIdOfUser; + type MaximumUnlockIdOfTimeUnit = MaximumUnlockIdOfTimeUnit; + type EntranceAccount = BifrostEntranceAccount; + type ExitAccount = BifrostExitAccount; + type FeeAccount = BifrostFeeAccount; + type RedeemFeeAccount = BifrostFeeAccount; + type RelayChainToken = RelayCurrencyId; + type CurrencyIdConversion = AssetIdMaps; + type CurrencyIdRegister = AssetIdMaps; + type BifrostSlp = MockSlp; + type BifrostSlpx = SlpxInterface; + type WeightInfo = (); + type OnRedeemSuccess = (); + type XcmTransfer = MockXcmTransfer; + type MoonbeamChainId = ConstU32<2023>; + type ChannelCommission = (); + type MaxLockRecords = ConstU32<100>; + type IncentivePoolAccount = IncentivePoolAccount; + type BbBNC = (); + type AssetIdMaps = AssetIdMaps; +} + +parameter_types! { + pub static RelaychainBlockNumber: BlockNumber = 1; + +} + +pub struct RelaychainDataProvider; + +impl RelaychainDataProvider { + pub fn set_block_number(block: BlockNumber) { + RelaychainBlockNumber::set(block); + } +} + +impl BlockNumberProvider for RelaychainDataProvider { + type BlockNumber = BlockNumber; + + fn current_block_number() -> Self::BlockNumber { + RelaychainBlockNumber::get() + } +} + +impl slp_v2::Config for Test { + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type XcmSender = MockXcmRouter; + type WeightInfo = (); + type MultiCurrency = Tokens; + type ControlOrigin = EnsureRoot; + type ParachainId = ParachainId; + type ResponseOrigin = EnsureResponse; + type QueryTimeout = ConstU64<100>; + type VtokenMinting = VtokenMinting; + type XcmTransfer = MockXcmTransfer; + type CurrencyIdConversion = AssetIdMaps; + type CommissionPalletId = CommissionPalletId; + type RelaychainBlockNumberProvider = RelaychainDataProvider; + type MaxValidators = ConstU32<256>; +} + +// Build genesis storage according to the mock runtime. +pub fn new_test_ext() -> sp_io::TestExternalities { + let t = system::GenesisConfig::::default().build_storage().unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +pub(crate) fn last_event() -> RuntimeEvent { + system::Pallet::::events().pop().expect("Event expected").event +} + +pub(crate) fn expect_event>(e: E) { + assert_eq!(last_event(), e.into()); +} diff --git a/pallets/slp-v2/src/tests.rs b/pallets/slp-v2/src/tests.rs new file mode 100644 index 000000000..d2649ecf2 --- /dev/null +++ b/pallets/slp-v2/src/tests.rs @@ -0,0 +1,938 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use crate::{ + astar_dapp_staking::types::{ + AstarDappStakingLedger, AstarDappStakingPendingStatus, AstarUnlockingRecord, + AstarValidator, DappStaking, + }, + common::types::{ + Delegator, Ledger, PendingStatus, ProtocolConfiguration, StakingProtocol, Validator, + XcmFee, XcmTask, + }, + mock::*, + DelegatorByStakingProtocolAndDelegatorIndex, DelegatorIndexByStakingProtocolAndDelegator, + Error as SlpV2Error, Event as SlpV2Event, LastUpdateOngoingTimeUnitBlockNumber, + LedgerByStakingProtocolAndDelegator, NextDelegatorIndexByStakingProtocol, + ValidatorsByStakingProtocolAndDelegator, +}; +use bifrost_primitives::{TimeUnit, VtokenMintingOperator, VASTR}; +use cumulus_primitives_core::Weight; +use frame_support::{assert_noop, assert_ok, traits::fungibles::Mutate}; +use orml_traits::MultiCurrency; +use pallet_xcm::Origin as XcmOrigin; +use polkadot_parachain_primitives::primitives::Sibling; +use sp_core::{bytes::to_hex, crypto::Ss58Codec, H160}; +use sp_runtime::{ + helpers_128bit::multiply_by_rational_with_rounding, traits::AccountIdConversion, BoundedVec, + Permill, Rounding, +}; +use xcm::{ + latest::{MaybeErrorCode, Parent, Response}, + prelude::{AccountId32, Parachain}, + v4::Location, +}; + +pub const STAKING_PROTOCOL: StakingProtocol = StakingProtocol::AstarDappStaking; + +pub const CONFIGURATION: ProtocolConfiguration = ProtocolConfiguration { + xcm_task_fee: XcmFee { weight: Weight::zero(), fee: 100 }, + protocol_fee_rate: Permill::from_perthousand(100), + unlock_period: TimeUnit::Era(9), + operator: AccountId::new([0u8; 32]), + max_update_token_exchange_rate: Permill::from_perthousand(1), + update_time_unit_interval: 100u32, + update_exchange_rate_interval: 100u32, +}; + +fn set_protocol_configuration() { + assert_ok!(SlpV2::set_protocol_configuration( + RuntimeOrigin::root(), + STAKING_PROTOCOL, + CONFIGURATION + )); +} + +#[test] +fn derivative_account_id_should_work() { + new_test_ext().execute_with(|| { + let sbling2030: AccountId = Sibling::from(2030).into_account_truncating(); + let sub_0_sbling2030 = SlpV2::derivative_account_id(sbling2030.clone(), 0).unwrap(); + let sub_1_sbling2030 = SlpV2::derivative_account_id(sbling2030.clone(), 1).unwrap(); + let sub_2_sbling2030 = SlpV2::derivative_account_id(sbling2030.clone(), 2).unwrap(); + + assert_eq!( + sub_0_sbling2030, + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap() + ); + assert_eq!( + sub_1_sbling2030, + AccountId::from_ss58check("XF713iFjaLwTxvVQv3YJdKhFY4EYpcVh6GzAWR7Lj5aoNHZ").unwrap() + ); + assert_eq!( + sub_2_sbling2030, + AccountId::from_ss58check("YeKP2BdVpFrXbbqkoVhDFZP9u3nUuop7fpMppQczQXBLhD1").unwrap() + ) + }) +} + +#[test] +fn set_configuration_should_work() { + new_test_ext().execute_with(|| { + set_protocol_configuration(); + expect_event(SlpV2Event::SetConfiguration { + staking_protocol: STAKING_PROTOCOL, + configuration: CONFIGURATION, + }); + }) +} + +#[test] +fn add_delegator_should_work() { + new_test_ext().execute_with(|| { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + let delegator_index = 0; + + assert_ok!(SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None)); + expect_event(SlpV2Event::AddDelegator { + staking_protocol: STAKING_PROTOCOL, + delegator_index, + delegator: delegator.clone(), + }); + assert_eq!( + DelegatorByStakingProtocolAndDelegatorIndex::::get( + STAKING_PROTOCOL, + delegator_index + ), + Some(delegator.clone()) + ); + assert_eq!( + DelegatorIndexByStakingProtocolAndDelegator::::get( + STAKING_PROTOCOL, + delegator.clone() + ), + Some(delegator_index) + ); + assert_eq!(NextDelegatorIndexByStakingProtocol::::get(STAKING_PROTOCOL), 1); + assert_eq!( + LedgerByStakingProtocolAndDelegator::::get(STAKING_PROTOCOL, delegator), + Some(Ledger::AstarDappStaking(AstarDappStakingLedger { + locked: 0, + unlocking: Default::default() + })) + ); + }); +} + +#[test] +fn repeat_add_delegator_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(SlpV2::add_delegator( + RuntimeOrigin::root(), + StakingProtocol::AstarDappStaking, + None + )); + + let delegator = Delegator::Substrate( + AccountId::from_ss58check("XF713iFjaLwTxvVQv3YJdKhFY4EYpcVh6GzAWR7Lj5aoNHZ").unwrap(), + ); + let delegator_index = 1; + + assert_ok!(SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None)); + expect_event(SlpV2Event::AddDelegator { + staking_protocol: STAKING_PROTOCOL, + delegator_index, + delegator: delegator.clone(), + }); + assert_eq!( + DelegatorByStakingProtocolAndDelegatorIndex::::get( + STAKING_PROTOCOL, + delegator_index + ), + Some(delegator.clone()) + ); + assert_eq!( + DelegatorIndexByStakingProtocolAndDelegator::::get( + STAKING_PROTOCOL, + delegator.clone() + ), + Some(delegator_index) + ); + assert_eq!(NextDelegatorIndexByStakingProtocol::::get(STAKING_PROTOCOL), 2); + assert_eq!( + LedgerByStakingProtocolAndDelegator::::get(STAKING_PROTOCOL, delegator), + Some(Ledger::AstarDappStaking(AstarDappStakingLedger { + locked: 0, + unlocking: Default::default() + })) + ); + }); +} + +#[test] +fn add_delegator_delegator_index_over_flow() { + new_test_ext().execute_with(|| { + NextDelegatorIndexByStakingProtocol::::insert(STAKING_PROTOCOL, 65535); + assert_noop!( + SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None), + SlpV2Error::::DelegatorIndexOverflow + ); + }); +} + +#[test] +fn add_delegator_delegator_already_exists() { + new_test_ext().execute_with(|| { + let delegator_0 = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + + DelegatorByStakingProtocolAndDelegatorIndex::::insert( + STAKING_PROTOCOL, + 0, + delegator_0, + ); + assert_noop!( + SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None), + SlpV2Error::::DelegatorAlreadyExists + ); + }); +} + +#[test] +fn add_delegator_delegator_index_already_exists() { + new_test_ext().execute_with(|| { + let delegator_0 = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + + DelegatorIndexByStakingProtocolAndDelegator::::insert( + STAKING_PROTOCOL, + delegator_0, + 0, + ); + assert_noop!( + SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None), + SlpV2Error::::DelegatorIndexAlreadyExists + ); + }); +} + +#[test] +fn remove_delegator_should_work() { + new_test_ext().execute_with(|| { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + let delegator_index = 0; + assert_ok!(SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None)); + assert_ok!(SlpV2::remove_delegator( + RuntimeOrigin::root(), + STAKING_PROTOCOL, + delegator.clone() + )); + expect_event(SlpV2Event::RemoveDelegator { + staking_protocol: STAKING_PROTOCOL, + delegator_index, + delegator: delegator.clone(), + }); + assert_eq!( + DelegatorByStakingProtocolAndDelegatorIndex::::get( + STAKING_PROTOCOL, + delegator_index + ), + None + ); + assert_eq!( + DelegatorIndexByStakingProtocolAndDelegator::::get( + STAKING_PROTOCOL, + delegator.clone() + ), + None + ); + assert_eq!(NextDelegatorIndexByStakingProtocol::::get(STAKING_PROTOCOL), 1); + assert_eq!( + ValidatorsByStakingProtocolAndDelegator::::get(STAKING_PROTOCOL, delegator) + .to_vec(), + vec![] + ); + }); +} + +#[test] +fn remove_delegator_delegator_index_not_found() { + new_test_ext().execute_with(|| { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + assert_noop!( + SlpV2::remove_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, delegator.clone()), + SlpV2Error::::DelegatorIndexNotFound + ); + }); +} + +#[test] +fn add_validator_should_work() { + new_test_ext().execute_with(|| { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + let validator = Validator::AstarDappStaking(AstarValidator::Evm(H160::default())); + + assert_ok!(SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None)); + + assert_ok!(SlpV2::add_validator( + RuntimeOrigin::root(), + STAKING_PROTOCOL, + delegator.clone(), + validator.clone() + )); + expect_event(SlpV2Event::AddValidator { + staking_protocol: STAKING_PROTOCOL, + delegator: delegator.clone(), + validator: validator.clone(), + }); + assert_eq!( + ValidatorsByStakingProtocolAndDelegator::::get(STAKING_PROTOCOL, delegator) + .to_vec(), + vec![validator] + ); + }); +} + +#[test] +fn repeat_add_validator_should_work() { + new_test_ext().execute_with(|| { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + let validator1 = Validator::AstarDappStaking(AstarValidator::Evm(H160::default())); + let validator2 = Validator::AstarDappStaking(AstarValidator::Wasm( + AccountId::from_ss58check("YeKP2BdVpFrXbbqkoVhDFZP9u3nUuop7fpMppQczQXBLhD1").unwrap(), + )); + + assert_ok!(SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None)); + + assert_ok!(SlpV2::add_validator( + RuntimeOrigin::root(), + STAKING_PROTOCOL, + delegator.clone(), + validator1.clone() + )); + assert_ok!(SlpV2::add_validator( + RuntimeOrigin::root(), + STAKING_PROTOCOL, + delegator.clone(), + validator2.clone() + )); + + expect_event(SlpV2Event::AddValidator { + staking_protocol: STAKING_PROTOCOL, + delegator: delegator.clone(), + validator: validator2.clone(), + }); + assert_eq!( + ValidatorsByStakingProtocolAndDelegator::::get( + STAKING_PROTOCOL, + delegator.clone() + ) + .to_vec(), + vec![validator1, validator2] + ); + }); +} + +#[test] +fn remove_validator_should_work() { + new_test_ext().execute_with(|| { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + let validator = Validator::AstarDappStaking(AstarValidator::Evm(H160::default())); + + assert_ok!(SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None)); + + assert_ok!(SlpV2::add_validator( + RuntimeOrigin::root(), + STAKING_PROTOCOL, + delegator.clone(), + validator.clone() + )); + assert_ok!(SlpV2::remove_validator( + RuntimeOrigin::root(), + STAKING_PROTOCOL, + delegator.clone(), + validator.clone() + )); + expect_event(SlpV2Event::RemoveValidator { + staking_protocol: STAKING_PROTOCOL, + delegator: delegator.clone(), + validator: validator.clone(), + }); + assert_eq!( + ValidatorsByStakingProtocolAndDelegator::::get( + STAKING_PROTOCOL, + delegator.clone() + ) + .to_vec(), + vec![] + ); + }); +} + +#[test] +fn astar_dapp_staking_lock() { + new_test_ext().execute_with(|| { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + let task = DappStaking::Lock(100); + let pending_status = PendingStatus::AstarDappStaking(AstarDappStakingPendingStatus::Lock( + delegator.clone(), + 100, + )); + let dest_location = STAKING_PROTOCOL.info().remote_dest_location; + + set_protocol_configuration(); + assert_ok!(SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None)); + + assert_ok!(SlpV2::astar_dapp_staking( + RuntimeOrigin::root(), + delegator.clone(), + task.clone() + )); + expect_event(SlpV2Event::SendXcmTask { + query_id: Some(0), + delegator: delegator.clone(), + task: XcmTask::AstarDappStaking(task), + pending_status: Some(pending_status), + dest_location, + }); + assert_ok!(SlpV2::notify_astar_dapp_staking( + XcmOrigin::Response(Parent.into()).into(), + 0, + Response::DispatchResult(MaybeErrorCode::Success) + )); + + let ledger = + LedgerByStakingProtocolAndDelegator::::get(STAKING_PROTOCOL, delegator).unwrap(); + assert_eq!( + ledger, + Ledger::AstarDappStaking(AstarDappStakingLedger { + locked: 100, + unlocking: Default::default() + }) + ) + }) +} + +#[test] +fn repeat_astar_dapp_staking_lock() { + new_test_ext().execute_with(|| { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + let task1 = DappStaking::Lock(100); + let task2 = DappStaking::Lock(200); + let query_id_0 = 0; + let query_id_1 = 1; + let pending_status = PendingStatus::AstarDappStaking(AstarDappStakingPendingStatus::Lock( + delegator.clone(), + 200, + )); + let dest_location = STAKING_PROTOCOL.info().remote_dest_location; + set_protocol_configuration(); + + assert_ok!(SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None)); + + assert_ok!(SlpV2::astar_dapp_staking(RuntimeOrigin::root(), delegator.clone(), task1)); + assert_ok!(SlpV2::notify_astar_dapp_staking( + XcmOrigin::Response(Parent.into()).into(), + query_id_0, + Response::DispatchResult(MaybeErrorCode::Success) + )); + + assert_ok!(SlpV2::astar_dapp_staking( + RuntimeOrigin::root(), + delegator.clone(), + task2.clone() + )); + expect_event(SlpV2Event::SendXcmTask { + query_id: Some(query_id_1), + delegator: delegator.clone(), + task: XcmTask::AstarDappStaking(task2), + pending_status: Some(pending_status), + dest_location, + }); + assert_ok!(SlpV2::notify_astar_dapp_staking( + XcmOrigin::Response(Parent.into()).into(), + query_id_1, + Response::DispatchResult(MaybeErrorCode::Success) + )); + + let ledger = + LedgerByStakingProtocolAndDelegator::::get(STAKING_PROTOCOL, delegator).unwrap(); + assert_eq!( + ledger, + Ledger::AstarDappStaking(AstarDappStakingLedger { + locked: 300, + unlocking: Default::default() + }) + ) + }) +} + +#[test] +fn astar_dapp_staking_unlock() { + new_test_ext().execute_with(|| { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + let task = DappStaking::Lock(100); + + assert_ok!(SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None)); + set_protocol_configuration(); + + assert_ok!(SlpV2::astar_dapp_staking(RuntimeOrigin::root(), delegator.clone(), task)); + assert_ok!(SlpV2::notify_astar_dapp_staking( + XcmOrigin::Response(Parent.into()).into(), + 0, + Response::DispatchResult(MaybeErrorCode::Success) + )); + + let task = DappStaking::Unlock(50); + RelaychainBlockNumber::set(100); + assert_ok!(SlpV2::update_ongoing_time_unit( + RuntimeOrigin::root(), + STAKING_PROTOCOL, + Some(TimeUnit::Era(1)) + )); + assert_ok!(SlpV2::astar_dapp_staking(RuntimeOrigin::root(), delegator.clone(), task)); + assert_ok!(SlpV2::notify_astar_dapp_staking( + XcmOrigin::Response(Parent.into()).into(), + 1, + Response::DispatchResult(MaybeErrorCode::Success) + )); + + let ledger = + LedgerByStakingProtocolAndDelegator::::get(STAKING_PROTOCOL, delegator).unwrap(); + assert_eq!( + ledger, + Ledger::AstarDappStaking(AstarDappStakingLedger { + locked: 50, + unlocking: BoundedVec::try_from(vec![AstarUnlockingRecord { + amount: 50, + unlock_time: TimeUnit::Era(10) + }]) + .unwrap() + }) + ) + }) +} + +#[test] +fn astar_dapp_staking_stake() { + new_test_ext().execute_with(|| { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + let validator = Validator::AstarDappStaking(AstarValidator::Evm(H160::default())); + let task = DappStaking::Stake(AstarValidator::Evm(H160::default()), 100); + let query_id = None; + let pending_status = None; + let dest_location = STAKING_PROTOCOL.info().remote_dest_location; + + assert_ok!(SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None)); + assert_ok!(SlpV2::add_validator( + RuntimeOrigin::root(), + STAKING_PROTOCOL, + delegator.clone(), + validator.clone() + )); + set_protocol_configuration(); + + assert_ok!(SlpV2::astar_dapp_staking( + RuntimeOrigin::root(), + delegator.clone(), + task.clone() + )); + expect_event(SlpV2Event::SendXcmTask { + query_id, + delegator, + task: XcmTask::AstarDappStaking(task.clone()), + pending_status, + dest_location, + }) + }) +} + +#[test] +fn astar_dapp_staking_unstake() { + new_test_ext().execute_with(|| { + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + let validator = Validator::AstarDappStaking(AstarValidator::Evm(H160::default())); + let task = DappStaking::Unstake(AstarValidator::Evm(H160::default()), 100); + let query_id = None; + let pending_status = None; + let dest_location = STAKING_PROTOCOL.info().remote_dest_location; + + assert_ok!(SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None)); + assert_ok!(SlpV2::add_validator( + RuntimeOrigin::root(), + STAKING_PROTOCOL, + delegator.clone(), + validator.clone() + )); + set_protocol_configuration(); + + assert_ok!(SlpV2::astar_dapp_staking( + RuntimeOrigin::root(), + delegator.clone(), + task.clone() + )); + expect_event(SlpV2Event::SendXcmTask { + query_id, + delegator, + task: XcmTask::AstarDappStaking(task.clone()), + pending_status, + dest_location, + }) + }) +} + +#[test] +fn staking_protocol_get_dest_beneficiary_location() { + new_test_ext().execute_with(|| { + let staking_protocol = StakingProtocol::AstarDappStaking; + let account_id = + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(); + let delegator = Delegator::Substrate(account_id.clone()); + assert_eq!( + staking_protocol.get_dest_beneficiary_location::(delegator), + Some(Location::new( + 1, + [Parachain(2006), AccountId32 { network: None, id: account_id.into() }] + )) + ); + }) +} + +#[test] +fn astar_polkadot_xcm_call() { + new_test_ext().execute_with(|| { + let (to, _) = VtokenMinting::get_entrance_and_exit_accounts(); + let calldata = SlpV2::wrap_polkadot_xcm_limited_reserve_transfer_assets_call_data( + &StakingProtocol::AstarDappStaking, + 100, + to.clone() + ) + .unwrap(); + + assert_eq!(to_hex(&calldata, false), "0x330804010100b91f04000101006d6f646c62662f76746b696e0000000000000000000000000000000000000000040400000091010000000000"); + + let call_data = SlpV2::wrap_polkadot_xcm_limited_reserve_transfer_assets_call_data( + &StakingProtocol::PolkadotStaking, + 100, + to + ) + .unwrap(); + assert_eq!(to_hex(&call_data, false), "0x630804000100b91f04000101006d6f646c62662f76746b696e0000000000000000000000000000000000000000040400000091010000000000"); + }) +} + +#[test] +fn set_ledger_should_work() { + new_test_ext().execute_with(|| { + let staking_protocol = StakingProtocol::AstarDappStaking; + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + let ledger = Ledger::AstarDappStaking(AstarDappStakingLedger { + locked: 100, + unlocking: Default::default(), + }); + assert_ok!(SlpV2::add_delegator(RuntimeOrigin::root(), staking_protocol, None)); + assert_ok!(SlpV2::set_ledger( + RuntimeOrigin::root(), + staking_protocol, + delegator.clone(), + ledger.clone() + )); + + expect_event(SlpV2Event::SetLedger { + staking_protocol, + delegator: delegator.clone(), + ledger: ledger.clone(), + }); + assert_eq!( + LedgerByStakingProtocolAndDelegator::::get(staking_protocol, delegator.clone()), + Some(ledger) + ); + }) +} + +#[test] +fn set_ledger_error() { + new_test_ext().execute_with(|| { + let staking_protocol = StakingProtocol::AstarDappStaking; + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + let ledger = Ledger::AstarDappStaking(AstarDappStakingLedger { + locked: 100, + unlocking: Default::default(), + }); + assert_noop!( + SlpV2::set_ledger( + RuntimeOrigin::root(), + staking_protocol, + delegator.clone(), + ledger.clone() + ), + SlpV2Error::::DelegatorIndexNotFound + ); + + assert_ok!(SlpV2::add_delegator(RuntimeOrigin::root(), staking_protocol, None)); + assert_ok!(SlpV2::set_ledger( + RuntimeOrigin::root(), + staking_protocol, + delegator.clone(), + ledger.clone() + )); + + assert_noop!( + SlpV2::set_ledger( + RuntimeOrigin::root(), + staking_protocol, + delegator.clone(), + ledger.clone() + ), + SlpV2Error::::InvalidParameter + ); + }) +} + +#[test] +fn update_ongoing_time_unit_should_work() { + new_test_ext().execute_with(|| { + let staking_protocol = StakingProtocol::AstarDappStaking; + let currency_id = staking_protocol.info().currency_id; + set_protocol_configuration(); + RelaychainDataProvider::set_block_number(100); + assert_ok!(SlpV2::update_ongoing_time_unit( + RuntimeOrigin::root(), + staking_protocol, + Some(TimeUnit::Era(1)) + )); + expect_event(SlpV2Event::TimeUnitUpdated { staking_protocol, time_unit: TimeUnit::Era(1) }); + assert_eq!(VtokenMinting::get_ongoing_time_unit(currency_id), Some(TimeUnit::Era(1))); + assert_eq!(LastUpdateOngoingTimeUnitBlockNumber::::get(staking_protocol), 100); + + RelaychainDataProvider::set_block_number(200); + + assert_ok!(SlpV2::update_ongoing_time_unit(RuntimeOrigin::root(), staking_protocol, None)); + expect_event(SlpV2Event::TimeUnitUpdated { staking_protocol, time_unit: TimeUnit::Era(2) }); + assert_eq!(VtokenMinting::get_ongoing_time_unit(currency_id), Some(TimeUnit::Era(2))); + assert_eq!(LastUpdateOngoingTimeUnitBlockNumber::::get(staking_protocol), 200); + }); +} + +#[test] +fn update_ongoing_time_unit_update_interval_too_short() { + new_test_ext().execute_with(|| { + let staking_protocol = StakingProtocol::AstarDappStaking; + set_protocol_configuration(); + + // current relaychain block number 1 < update_interval 100 + last update block number 0 => + // Error + assert_noop!( + SlpV2::update_ongoing_time_unit( + RuntimeOrigin::root(), + staking_protocol, + Some(TimeUnit::Era(1)) + ), + SlpV2Error::::UpdateIntervalTooShort + ); + + RelaychainDataProvider::set_block_number(100); + // current relaychain block number 100 = update_interval 100 + last update block number 0 => + // Ok + assert_noop!( + SlpV2::update_ongoing_time_unit(RuntimeOrigin::root(), staking_protocol, None), + SlpV2Error::::TimeUnitNotFound + ); + + assert_ok!(SlpV2::update_ongoing_time_unit( + RuntimeOrigin::root(), + staking_protocol, + Some(TimeUnit::Era(1)) + )); + + RelaychainDataProvider::set_block_number(199); + // current relaychain block number 199 < update_interval 100 + last update block number 100 + // => Error + assert_noop!( + SlpV2::update_ongoing_time_unit(RuntimeOrigin::root(), staking_protocol, None), + SlpV2Error::::UpdateIntervalTooShort + ); + RelaychainDataProvider::set_block_number(200); + // current relaychain block number 200 = update_interval 100 + last update block number 100 + // => Ok + assert_ok!(SlpV2::update_ongoing_time_unit(RuntimeOrigin::root(), staking_protocol, None)); + }); +} + +#[test] +fn update_token_exchange_rate_should_work() { + new_test_ext().execute_with(|| { + let staking_protocol = StakingProtocol::AstarDappStaking; + let currency_id = staking_protocol.info().currency_id; + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + let amount = 10_059_807_133_828_175_000_000u128; + let token_pool = 24_597_119_664_064_597_684_680_531u128; + let vtoken_total_issuance = 21_728_134_208_272_171_009_169_962u128; + + assert_ok!(SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None)); + Currencies::set_balance(VASTR, &AccountId::from([0u8; 32]), vtoken_total_issuance); + assert_eq!(Currencies::total_issuance(VASTR), vtoken_total_issuance); + assert_ok!(VtokenMinting::increase_token_pool(currency_id, token_pool)); + + set_protocol_configuration(); + assert_eq!(VtokenMinting::get_token_pool(currency_id), token_pool); + + RelaychainDataProvider::set_block_number(100); + + // Set protocol fee rate is 10% + let protocol_fee_rate = Permill::from_perthousand(100); + assert_ok!(SlpV2::update_token_exchange_rate( + RuntimeOrigin::root(), + staking_protocol, + delegator.clone(), + amount + )); + // The protocol_fee is 888.644046532367789159 VASTR. + let protocol_fee = multiply_by_rational_with_rounding( + protocol_fee_rate * amount, + vtoken_total_issuance, + token_pool, + Rounding::Down, + ) + .unwrap(); + expect_event(SlpV2Event::TokenExchangeRateUpdated { + staking_protocol, + delegator: delegator.clone(), + protocol_fee_currency_id: VASTR, + protocol_fee, + amount, + }); + let vtoken_total_issuance = vtoken_total_issuance + protocol_fee; + let token_pool = token_pool + amount; + assert_eq!(VtokenMinting::get_token_pool(currency_id), token_pool); + assert_eq!(Currencies::total_issuance(VASTR), vtoken_total_issuance); + assert_eq!( + Currencies::free_balance(VASTR, &CommissionPalletId::get().into_account_truncating()), + protocol_fee + ); + + RelaychainDataProvider::set_block_number(200); + // current relaychain block number 300 = update_interval 100 + last update block number 200 + // => Ok + assert_ok!(SlpV2::update_token_exchange_rate( + RuntimeOrigin::root(), + staking_protocol, + delegator.clone(), + amount + )); + + // The protocol_fee is 888.317083868634496826 VASTR. + let protocol_fee_1 = multiply_by_rational_with_rounding( + protocol_fee_rate * amount, + vtoken_total_issuance, + token_pool, + Rounding::Down, + ) + .unwrap(); + expect_event(SlpV2Event::TokenExchangeRateUpdated { + staking_protocol, + delegator: delegator.clone(), + protocol_fee_currency_id: VASTR, + protocol_fee: protocol_fee_1, + amount, + }); + let vtoken_total_issuance = vtoken_total_issuance + protocol_fee_1; + let token_pool = token_pool + amount; + assert_eq!(VtokenMinting::get_token_pool(currency_id), token_pool); + assert_eq!(Currencies::total_issuance(VASTR), vtoken_total_issuance); + assert_eq!( + Currencies::free_balance(VASTR, &CommissionPalletId::get().into_account_truncating()), + protocol_fee + protocol_fee_1 + ); + }) +} + +#[test] +fn update_token_exchange_rate_limt_error() { + new_test_ext().execute_with(|| { + let staking_protocol = StakingProtocol::AstarDappStaking; + let currency_id = staking_protocol.info().currency_id; + let delegator = Delegator::Substrate( + AccountId::from_ss58check("YLF9AnL6V1vQRfuiB832NXNGZYCPAWkKLLkh7cf3KwXhB9o").unwrap(), + ); + let amount = 1000u128; + let token_pool = 12000u128; + let vtoken_total_issuance = 10000u128; + + assert_ok!(SlpV2::add_delegator(RuntimeOrigin::root(), STAKING_PROTOCOL, None)); + Currencies::set_balance(VASTR, &AccountId::from([0u8; 32]), vtoken_total_issuance); + assert_ok!(VtokenMinting::increase_token_pool(currency_id, token_pool)); + + set_protocol_configuration(); + + // current relaychain block number 1 < update_interval 100 + last update block number 0 => + // Error + assert_noop!( + SlpV2::update_token_exchange_rate( + RuntimeOrigin::root(), + staking_protocol, + delegator.clone(), + amount + ), + SlpV2Error::::UpdateIntervalTooShort + ); + + RelaychainDataProvider::set_block_number(101); + // current relaychain block number 101 < update_interval 100 + last update block number 0 => + // Ok amount 13 < max_update_amount 12 => Error + assert_noop!( + SlpV2::update_token_exchange_rate( + RuntimeOrigin::root(), + staking_protocol, + delegator.clone(), + amount + ), + SlpV2Error::::UpdateTokenExchangeRateAmountTooLarge + ); + }) +} diff --git a/pallets/slp-v2/src/weights.rs b/pallets/slp-v2/src/weights.rs new file mode 100644 index 000000000..5ca1dccd7 --- /dev/null +++ b/pallets/slp-v2/src/weights.rs @@ -0,0 +1,366 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Autogenerated weights for bifrost_slp_v2 +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-09-11, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! HOSTNAME: `bifrost-jenkins`, CPU: `Intel(R) Xeon(R) CPU E5-26xx v4` +//! WASM-EXECUTION: Compiled, CHAIN: Some("bifrost-polkadot-local"), DB CACHE: 1024 + +// Executed Command: +// ./target/release/bifrost +// benchmark +// pallet +// --chain=bifrost-polkadot-local +// --steps=50 +// --repeat=20 +// --pallet=bifrost_slp_v2 +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --header=./HEADER-GPL3 +// --output=./weight.rs +// --template +// ./weight-template/pallet-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for bifrost_slp_v2. +pub trait WeightInfo { + fn add_delegator() -> Weight; + fn remove_delegator() -> Weight; + fn add_validator() -> Weight; + fn remove_validator() -> Weight; + fn set_protocol_configuration() -> Weight; + fn set_ledger() -> Weight; + fn transfer_to() -> Weight; + fn transfer_back() -> Weight; + fn update_ongoing_time_unit() -> Weight; + fn update_token_exchange_rate() -> Weight; + fn astar_dapp_staking() -> Weight; + fn notify_astar_dapp_staking() -> Weight; +} + +// For backwards compatibility and tests +impl WeightInfo for () { + /// Storage: `SlpV2::NextDelegatorIndexByStakingProtocol` (r:1 w:1) + /// Proof: `SlpV2::NextDelegatorIndexByStakingProtocol` (`max_values`: None, `max_size`: Some(19), added: 2494, mode: `MaxEncodedLen`) + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:1 w:1) + /// Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:1) + /// Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `System::Number` (r:1 w:0) + /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::ExecutionPhase` (r:1 w:0) + /// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + /// Storage: `System::EventCount` (r:1 w:1) + /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Events` (r:1 w:1) + /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SlpV2::LedgerByStakingProtocolAndDelegator` (r:0 w:1) + /// Proof: `SlpV2::LedgerByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(252), added: 2727, mode: `MaxEncodedLen`) + fn add_delegator() -> Weight { + // Proof Size summary in bytes: + // Measured: `341` + // Estimated: `3533` + // Minimum execution time: 59_092_000 picoseconds. + Weight::from_parts(60_502_000, 3533) + .saturating_add(RocksDbWeight::get().reads(8_u64)) + .saturating_add(RocksDbWeight::get().writes(6_u64)) + } + /// Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:1) + /// Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `System::Number` (r:1 w:0) + /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::ExecutionPhase` (r:1 w:0) + /// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + /// Storage: `System::EventCount` (r:1 w:1) + /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Events` (r:1 w:1) + /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SlpV2::LedgerByStakingProtocolAndDelegator` (r:0 w:1) + /// Proof: `SlpV2::LedgerByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(252), added: 2727, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:0 w:1) + /// Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::ValidatorsByStakingProtocolAndDelegator` (r:0 w:1) + /// Proof: `SlpV2::ValidatorsByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(8772), added: 11247, mode: `MaxEncodedLen`) + fn remove_delegator() -> Weight { + // Proof Size summary in bytes: + // Measured: `432` + // Estimated: `3533` + // Minimum execution time: 48_567_000 picoseconds. + Weight::from_parts(49_673_000, 3533) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(6_u64)) + } + /// Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:0) + /// Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:1 w:0) + /// Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::ValidatorsByStakingProtocolAndDelegator` (r:1 w:1) + /// Proof: `SlpV2::ValidatorsByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(8772), added: 11247, mode: `MaxEncodedLen`) + /// Storage: `System::Number` (r:1 w:0) + /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::ExecutionPhase` (r:1 w:0) + /// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + /// Storage: `System::EventCount` (r:1 w:1) + /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Events` (r:1 w:1) + /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn add_validator() -> Weight { + // Proof Size summary in bytes: + // Measured: `487` + // Estimated: `12237` + // Minimum execution time: 51_665_000 picoseconds. + Weight::from_parts(52_597_000, 12237) + .saturating_add(RocksDbWeight::get().reads(7_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:0) + /// Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:1 w:0) + /// Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::ValidatorsByStakingProtocolAndDelegator` (r:1 w:1) + /// Proof: `SlpV2::ValidatorsByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(8772), added: 11247, mode: `MaxEncodedLen`) + /// Storage: `System::Number` (r:1 w:0) + /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::ExecutionPhase` (r:1 w:0) + /// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + /// Storage: `System::EventCount` (r:1 w:1) + /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Events` (r:1 w:1) + /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn remove_validator() -> Weight { + // Proof Size summary in bytes: + // Measured: `598` + // Estimated: `12237` + // Minimum execution time: 53_942_000 picoseconds. + Weight::from_parts(55_252_000, 12237) + .saturating_add(RocksDbWeight::get().reads(7_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: `SlpV2::ConfigurationByStakingProtocol` (r:1 w:1) + /// Proof: `SlpV2::ConfigurationByStakingProtocol` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + /// Storage: `System::Number` (r:1 w:0) + /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::ExecutionPhase` (r:1 w:0) + /// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + /// Storage: `System::EventCount` (r:1 w:1) + /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Events` (r:1 w:1) + /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_protocol_configuration() -> Weight { + // Proof Size summary in bytes: + // Measured: `238` + // Estimated: `3567` + // Minimum execution time: 32_670_000 picoseconds. + Weight::from_parts(33_460_000, 3567) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:0) + /// Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:1 w:0) + /// Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::LedgerByStakingProtocolAndDelegator` (r:1 w:1) + /// Proof: `SlpV2::LedgerByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(252), added: 2727, mode: `MaxEncodedLen`) + /// Storage: `System::Number` (r:1 w:0) + /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::ExecutionPhase` (r:1 w:0) + /// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + /// Storage: `System::EventCount` (r:1 w:1) + /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Events` (r:1 w:1) + /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_ledger() -> Weight { + // Proof Size summary in bytes: + // Measured: `545` + // Estimated: `3717` + // Minimum execution time: 52_407_000 picoseconds. + Weight::from_parts(53_463_000, 3717) + .saturating_add(RocksDbWeight::get().reads(7_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:0) + /// Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:1 w:0) + /// Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `Tokens::Accounts` (r:1 w:0) + /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(118), added: 2593, mode: `MaxEncodedLen`) + /// Storage: `System::Number` (r:1 w:0) + /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::ExecutionPhase` (r:1 w:0) + /// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + /// Storage: `System::EventCount` (r:1 w:1) + /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Events` (r:1 w:1) + /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn transfer_to() -> Weight { + // Proof Size summary in bytes: + // Measured: `942` + // Estimated: `3583` + // Minimum execution time: 56_532_000 picoseconds. + Weight::from_parts(57_959_000, 3583) + .saturating_add(RocksDbWeight::get().reads(7_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:0) + /// Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:1 w:0) + /// Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::ConfigurationByStakingProtocol` (r:1 w:0) + /// Proof: `SlpV2::ConfigurationByStakingProtocol` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + /// Storage: `System::Number` (r:1 w:0) + /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::ExecutionPhase` (r:1 w:0) + /// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + /// Storage: `System::EventCount` (r:1 w:1) + /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Events` (r:1 w:1) + /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn transfer_back() -> Weight { + // Proof Size summary in bytes: + // Measured: `596` + // Estimated: `3567` + // Minimum execution time: 62_312_000 picoseconds. + Weight::from_parts(65_024_000, 3567) + .saturating_add(RocksDbWeight::get().reads(7_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) + /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::LastRelayChainBlockNumber` (r:1 w:0) + /// Proof: `ParachainSystem::LastRelayChainBlockNumber` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SlpV2::ConfigurationByStakingProtocol` (r:1 w:0) + /// Proof: `SlpV2::ConfigurationByStakingProtocol` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::LastUpdateOngoingTimeUnitBlockNumber` (r:1 w:1) + /// Proof: `SlpV2::LastUpdateOngoingTimeUnitBlockNumber` (`max_values`: None, `max_size`: Some(21), added: 2496, mode: `MaxEncodedLen`) + /// Storage: `VtokenMinting::OngoingTimeUnit` (r:1 w:1) + /// Proof: `VtokenMinting::OngoingTimeUnit` (`max_values`: None, `max_size`: Some(27), added: 2502, mode: `MaxEncodedLen`) + /// Storage: `System::Number` (r:1 w:0) + /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::ExecutionPhase` (r:1 w:0) + /// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + /// Storage: `System::EventCount` (r:1 w:1) + /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Events` (r:1 w:1) + /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn update_ongoing_time_unit() -> Weight { + // Proof Size summary in bytes: + // Measured: `560` + // Estimated: `3567` + // Minimum execution time: 52_270_000 picoseconds. + Weight::from_parts(53_152_000, 3567) + .saturating_add(RocksDbWeight::get().reads(9_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + } + /// Storage: `SlpV2::ConfigurationByStakingProtocol` (r:1 w:0) + /// Proof: `SlpV2::ConfigurationByStakingProtocol` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) + /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::LastRelayChainBlockNumber` (r:1 w:0) + /// Proof: `ParachainSystem::LastRelayChainBlockNumber` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SlpV2::LastUpdateTokenExchangeRateBlockNumber` (r:1 w:1) + /// Proof: `SlpV2::LastUpdateTokenExchangeRateBlockNumber` (`max_values`: None, `max_size`: Some(70), added: 2545, mode: `MaxEncodedLen`) + /// Storage: `VtokenMinting::TokenPool` (r:1 w:1) + /// Proof: `VtokenMinting::TokenPool` (`max_values`: None, `max_size`: Some(38), added: 2513, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::LedgerByStakingProtocolAndDelegator` (r:1 w:1) + /// Proof: `SlpV2::LedgerByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(252), added: 2727, mode: `MaxEncodedLen`) + /// Storage: `System::Number` (r:1 w:0) + /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::ExecutionPhase` (r:1 w:0) + /// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + /// Storage: `System::EventCount` (r:1 w:1) + /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Events` (r:1 w:1) + /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn update_token_exchange_rate() -> Weight { + // Proof Size summary in bytes: + // Measured: `755` + // Estimated: `3717` + // Minimum execution time: 67_792_000 picoseconds. + Weight::from_parts(69_546_000, 3717) + .saturating_add(RocksDbWeight::get().reads(10_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) + } + /// Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:0) + /// Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:1 w:0) + /// Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `System::Number` (r:1 w:0) + /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) + /// Proof: `PolkadotXcm::QueryCounter` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SlpV2::ConfigurationByStakingProtocol` (r:1 w:0) + /// Proof: `SlpV2::ConfigurationByStakingProtocol` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + /// Storage: `System::ExecutionPhase` (r:1 w:0) + /// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + /// Storage: `System::EventCount` (r:1 w:1) + /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Events` (r:1 w:1) + /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SlpV2::PendingStatusByQueryId` (r:0 w:1) + /// Proof: `SlpV2::PendingStatusByQueryId` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Storage: `PolkadotXcm::Queries` (r:0 w:1) + /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn astar_dapp_staking() -> Weight { + // Proof Size summary in bytes: + // Measured: `836` + // Estimated: `3567` + // Minimum execution time: 80_609_000 picoseconds. + Weight::from_parts(81_635_000, 3567) + .saturating_add(RocksDbWeight::get().reads(8_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) + } + /// Storage: `SlpV2::PendingStatusByQueryId` (r:1 w:0) + /// Proof: `SlpV2::PendingStatusByQueryId` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Storage: `SlpV2::LedgerByStakingProtocolAndDelegator` (r:1 w:1) + /// Proof: `SlpV2::LedgerByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(252), added: 2727, mode: `MaxEncodedLen`) + /// Storage: `System::Number` (r:1 w:0) + /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::ExecutionPhase` (r:1 w:0) + /// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + /// Storage: `System::EventCount` (r:1 w:1) + /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Events` (r:1 w:1) + /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn notify_astar_dapp_staking() -> Weight { + // Proof Size summary in bytes: + // Measured: `567` + // Estimated: `3717` + // Minimum execution time: 45_781_000 picoseconds. + Weight::from_parts(46_813_000, 3717) + .saturating_add(RocksDbWeight::get().reads(6_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } +} \ No newline at end of file diff --git a/pallets/slp/src/agents/filecoin_agent/agent.rs b/pallets/slp/src/agents/filecoin_agent/agent.rs index c3c9b3ff6..22c90e1e6 100644 --- a/pallets/slp/src/agents/filecoin_agent/agent.rs +++ b/pallets/slp/src/agents/filecoin_agent/agent.rs @@ -20,8 +20,8 @@ use crate::{ primitives::{FilecoinLedger, Ledger}, traits::StakingAgent, AccountIdOf, BalanceOf, BoundedVec, Config, DelegatorLatestTuneRecord, DelegatorLedgers, - LedgerUpdateEntry, MinimumsAndMaximums, Pallet, TimeUnit, Validators, ValidatorsByDelegator, - ValidatorsByDelegatorUpdateEntry, + HostingFees, LedgerUpdateEntry, MinimumsAndMaximums, Pallet, TimeUnit, Validators, + ValidatorsByDelegator, ValidatorsByDelegatorUpdateEntry, }; use bifrost_primitives::{CurrencyId, VtokenMintingOperator}; use core::marker::PhantomData; @@ -447,7 +447,7 @@ impl // issue the increased interest amount to the entrance account // Get charged fee value let (fee_permill, _beneficiary) = - Pallet::::get_hosting_fee(currency_id).ok_or(Error::::InvalidHostingFee)?; + HostingFees::::get(currency_id).ok_or(Error::::InvalidHostingFee)?; let fee_to_charge = fee_permill.mul_floor(token_amount); let amount_to_increase = token_amount.checked_sub(&fee_to_charge).ok_or(Error::::UnderFlow)?; diff --git a/pallets/slp/src/agents/utils.rs b/pallets/slp/src/agents/utils.rs index 228d362f4..c2cb60474 100644 --- a/pallets/slp/src/agents/utils.rs +++ b/pallets/slp/src/agents/utils.rs @@ -16,8 +16,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . use crate::{ - blake2_256, pallet::Error, AccountIdOf, Config, Decode, LedgerUpdateEntry, MinimumsAndMaximums, - Pallet, TrailingZeroInput, Validators, ValidatorsByDelegatorUpdateEntry, ASTR, DOT, GLMR, H160, + blake2_256, pallet::Error, AccountIdOf, Config, Decode, DelegatorLedgerXcmUpdateQueue, + LedgerUpdateEntry, MinimumsAndMaximums, Pallet, TrailingZeroInput, Validators, + ValidatorsByDelegatorUpdateEntry, ValidatorsByDelegatorXcmUpdateQueue, ASTR, DOT, GLMR, H160, KSM, MANTA, MOVR, PHA, }; use bifrost_primitives::CurrencyId; @@ -211,7 +212,7 @@ impl Pallet { // See if the query exists. If it exists, call corresponding chain storage update // function. let (entry, timeout) = - Self::get_delegator_ledger_update_entry(query_id).ok_or(Error::::QueryNotExist)?; + DelegatorLedgerXcmUpdateQueue::::get(query_id).ok_or(Error::::QueryNotExist)?; let now = frame_system::Pallet::::block_number(); let mut updated = true; @@ -244,7 +245,7 @@ impl Pallet { ) -> Result> { // See if the query exists. If it exists, call corresponding chain storage update // function. - let (entry, timeout) = Self::get_validators_by_delegator_update_entry(query_id) + let (entry, timeout) = ValidatorsByDelegatorXcmUpdateQueue::::get(query_id) .ok_or(Error::::QueryNotExist)?; let now = frame_system::Pallet::::block_number(); @@ -274,7 +275,7 @@ impl Pallet { // See if the query exists. If it exists, call corresponding chain storage update // function. let (entry, _) = - Self::get_delegator_ledger_update_entry(query_id).ok_or(Error::::QueryNotExist)?; + DelegatorLedgerXcmUpdateQueue::::get(query_id).ok_or(Error::::QueryNotExist)?; let currency_id = match entry { LedgerUpdateEntry::Substrate(substrate_entry) => Some(substrate_entry.currency_id), LedgerUpdateEntry::ParachainStaking(moonbeam_entry) => Some(moonbeam_entry.currency_id), @@ -293,7 +294,7 @@ impl Pallet { ) -> Result<(), Error> { // See if the query exists. If it exists, call corresponding chain storage update // function. - let (entry, _) = Self::get_validators_by_delegator_update_entry(query_id) + let (entry, _) = ValidatorsByDelegatorXcmUpdateQueue::::get(query_id) .ok_or(Error::::QueryNotExist)?; let currency_id = match entry { ValidatorsByDelegatorUpdateEntry::Substrate(substrate_entry) => diff --git a/pallets/slp/src/lib.rs b/pallets/slp/src/lib.rs index 260ee7850..d4a5fd67a 100644 --- a/pallets/slp/src/lib.rs +++ b/pallets/slp/src/lib.rs @@ -537,25 +537,21 @@ pub mod pallet { /// One operate origin(can be a multisig account) for a currency. An operating origins are /// normal account in Bifrost chain. #[pallet::storage] - #[pallet::getter(fn get_operate_origin)] pub type OperateOrigins = StorageMap<_, Blake2_128Concat, CurrencyId, AccountIdOf>; /// Origins and Amounts for the staking operating account fee supplement. An operating account /// is identified in MultiLocation format. #[pallet::storage] - #[pallet::getter(fn get_fee_source)] pub type FeeSources = StorageMap<_, Blake2_128Concat, CurrencyId, (MultiLocation, BalanceOf)>; /// Hosting fee percentage and beneficiary account for different chains #[pallet::storage] - #[pallet::getter(fn get_hosting_fee)] pub type HostingFees = StorageMap<_, Blake2_128Concat, CurrencyId, (Permill, MultiLocation)>; /// Delegators in service. A delegator is identified in MultiLocation format. /// Currency Id + Sub-account index => MultiLocation #[pallet::storage] - #[pallet::getter(fn get_delegator_multilocation_by_index)] pub type DelegatorsIndex2Multilocation = StorageDoubleMap< _, Blake2_128Concat, @@ -568,7 +564,6 @@ pub mod pallet { /// Delegators in service. Currency Id + MultiLocation => Sub-account index #[pallet::storage] - #[pallet::getter(fn get_delegator_index_by_multilocation)] pub type DelegatorsMultilocation2Index = StorageDoubleMap< _, Blake2_128Concat, @@ -581,18 +576,15 @@ pub mod pallet { /// Next index of different currency delegators. #[pallet::storage] - #[pallet::getter(fn get_delegator_next_index)] pub type DelegatorNextIndex = StorageMap<_, Blake2_128Concat, CurrencyId, u16, ValueQuery>; /// (VWL) Validator in service. A validator is identified in MultiLocation format. #[pallet::storage] - #[pallet::getter(fn get_validators)] pub type Validators = StorageMap<_, Blake2_128Concat, CurrencyId, BoundedVec>; /// (VBL) Validator Boost List -> (validator multilocation, due block number) #[pallet::storage] - #[pallet::getter(fn get_validator_boost_list)] pub type ValidatorBoostList = StorageMap< _, Blake2_128Concat, @@ -602,7 +594,6 @@ pub mod pallet { /// Validators for each delegator. CurrencyId + Delegator => Vec #[pallet::storage] - #[pallet::getter(fn get_validators_by_delegator)] pub type ValidatorsByDelegator = StorageDoubleMap< _, Blake2_128Concat, @@ -614,7 +605,6 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn get_validators_by_delegator_update_entry)] pub type ValidatorsByDelegatorXcmUpdateQueue = StorageMap< _, Blake2_128Concat, @@ -624,7 +614,6 @@ pub mod pallet { /// Delegator ledgers. A delegator is identified in MultiLocation format. #[pallet::storage] - #[pallet::getter(fn get_delegator_ledger)] pub type DelegatorLedgers = StorageDoubleMap< _, Blake2_128Concat, @@ -636,7 +625,6 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn get_delegator_ledger_update_entry)] pub type DelegatorLedgerXcmUpdateQueue = StorageMap< _, Blake2_128Concat, @@ -646,19 +634,16 @@ pub mod pallet { /// Minimum and Maximum constraints for different chains. #[pallet::storage] - #[pallet::getter(fn get_minimums_maximums)] pub type MinimumsAndMaximums = StorageMap<_, Blake2_128Concat, CurrencyId, MinimumsMaximums>>; /// TimeUnit delay params for different chains. #[pallet::storage] - #[pallet::getter(fn get_currency_delays)] pub type CurrencyDelays = StorageMap<_, Blake2_128Concat, CurrencyId, Delays>; /// A delegator's tuning record of exchange rate for the current time unit. /// Currency Id + Delegator Id => latest tuned TimeUnit #[pallet::storage] - #[pallet::getter(fn get_delegator_latest_tune_record)] pub type DelegatorLatestTuneRecord = StorageDoubleMap< _, Blake2_128Concat, @@ -672,7 +657,6 @@ pub mod pallet { /// Currency's tuning record of exchange rate for the current time unit. /// Currency Id => (latest tuned TimeUnit, number of tuning times) #[pallet::storage] - #[pallet::getter(fn get_currency_latest_tune_record)] pub type CurrencyLatestTuneRecord = StorageMap<_, Blake2_128Concat, CurrencyId, (TimeUnit, u32), OptionQuery>; @@ -680,28 +664,23 @@ pub mod pallet { /// rate for a single time unit, and how much at most each time can tune the /// exchange rate #[pallet::storage] - #[pallet::getter(fn get_currency_tune_exchange_rate_limit)] pub type CurrencyTuneExchangeRateLimit = StorageMap<_, Blake2_128Concat, CurrencyId, (u32, Permill)>; /// reflect if all delegations are on a decrease/revoke status. If yes, then new user redeeming /// is unaccepted. #[pallet::storage] - #[pallet::getter(fn get_all_delegations_occupied_status)] pub type DelegationsOccupied = StorageMap<_, Blake2_128Concat, CurrencyId, bool>; #[pallet::storage] - #[pallet::getter(fn get_last_time_updated_ongoing_time_unit)] pub type LastTimeUpdatedOngoingTimeUnit = StorageMap<_, Blake2_128Concat, CurrencyId, BlockNumberFor>; #[pallet::storage] - #[pallet::getter(fn get_ongoing_time_unit_update_interval)] pub type OngoingTimeUnitUpdateInterval = StorageMap<_, Blake2_128Concat, CurrencyId, BlockNumberFor>; #[pallet::storage] - #[pallet::getter(fn get_supplement_fee_account_wihtelist)] pub type SupplementFeeAccountWhitelist = StorageMap<_, Blake2_128Concat, CurrencyId, Vec<(MultiLocation, Hash)>>; @@ -1271,7 +1250,7 @@ pub mod pallet { ensure!(value > Zero::zero(), Error::::AmountZero); // Ensure the value is valid. - let (limit_num, max_permill) = Self::get_currency_tune_exchange_rate_limit(currency_id) + let (limit_num, max_permill) = CurrencyTuneExchangeRateLimit::::get(currency_id) .ok_or(Error::::TuneExchangeRateLimitNotSet)?; // Get pool token value let pool_token = T::VtokenMinting::get_token_pool(currency_id); @@ -1290,9 +1269,8 @@ pub mod pallet { } // Get CurrencyLatestTuneRecord for the currencyId. - let (latest_time_unit, tune_num) = - Self::get_currency_latest_tune_record(currency_id) - .ok_or(Error::::CurrencyLatestTuneRecordNotExist)?; + let (latest_time_unit, tune_num) = CurrencyLatestTuneRecord::::get(currency_id) + .ok_or(Error::::CurrencyLatestTuneRecordNotExist)?; // See if exceeds tuning limit. // If it has been tuned in the current time unit, ensure this tuning is within limit. @@ -1306,7 +1284,7 @@ pub mod pallet { // Get charged fee value let (fee_permill, beneficiary) = - Self::get_hosting_fee(currency_id).ok_or(Error::::InvalidHostingFee)?; + HostingFees::::get(currency_id).ok_or(Error::::InvalidHostingFee)?; let fee_to_charge = fee_permill.mul_floor(value); // Should first charge fee, and then tune exchange rate. Otherwise, the rate will be @@ -1940,7 +1918,7 @@ pub mod pallet { // Add the boost list to the validator set let mut validator_vec; - if let Some(validator_set) = Self::get_validators(currency_id) { + if let Some(validator_set) = Validators::::get(currency_id) { validator_vec = validator_set.to_vec(); } else { validator_vec = vec![]; @@ -2036,7 +2014,7 @@ pub mod pallet { due_block_number, }); - let validator_set_op = Self::get_validators(currency_id); + let validator_set_op = Validators::::get(currency_id); let mut validator_vec; // Add the newly added validator to the validator set @@ -2282,14 +2260,14 @@ impl>> token: CurrencyIdOf, derivative_index: DerivativeIndex, ) -> bool { - Pallet::::get_delegator_multilocation_by_index(token, derivative_index).is_some() + DelegatorsIndex2Multilocation::::get(token, derivative_index).is_some() } fn get_multilocation( token: CurrencyIdOf, derivative_index: DerivativeIndex, ) -> Option { - Pallet::::get_delegator_multilocation_by_index(token, derivative_index) + DelegatorsIndex2Multilocation::::get(token, derivative_index) } fn get_stake_info( @@ -2297,7 +2275,7 @@ impl>> derivative_index: DerivativeIndex, ) -> Option<(BalanceOf, BalanceOf)> { Self::get_multilocation(token, derivative_index).and_then(|location| { - Pallet::::get_delegator_ledger(token, location).and_then(|ledger| match ledger { + DelegatorLedgers::::get(token, location).and_then(|ledger| match ledger { Ledger::Substrate(l) if F::contains(&token) => Some((l.total, l.active)), _ => None, }) diff --git a/pallets/slp/src/mocks/mock.rs b/pallets/slp/src/mocks/mock.rs index 5d4836d0d..a5f893b27 100644 --- a/pallets/slp/src/mocks/mock.rs +++ b/pallets/slp/src/mocks/mock.rs @@ -25,7 +25,7 @@ use crate::{Config, DispatchResult, QueryResponseManager, XcmDestWeightAndFeeHan use bifrost_asset_registry::AssetIdMaps; use bifrost_primitives::{ currency::{BNC, KSM}, - Amount, Balance, CurrencyId, SlpxOperator, TokenSymbol, XcmOperationType, + Amount, Balance, CurrencyId, MoonbeamChainId, SlpxOperator, TokenSymbol, XcmOperationType, }; pub use cumulus_primitives_core::ParaId; use frame_support::{ @@ -209,15 +209,11 @@ impl bifrost_vtoken_minting::Config for Runtime { type WeightInfo = (); type OnRedeemSuccess = (); type XcmTransfer = XTokens; - type AstarParachainId = ConstU32<2007>; - type MoonbeamParachainId = ConstU32<2023>; - type HydradxParachainId = ConstU32<2034>; - type MantaParachainId = ConstU32<2104>; - type InterlayParachainId = ConstU32<2032>; + type MoonbeamChainId = MoonbeamChainId; type ChannelCommission = (); type MaxLockRecords = ConstU32<100>; type IncentivePoolAccount = IncentivePoolAccount; - type VeMinting = (); + type BbBNC = (); type AssetIdMaps = AssetIdMaps; } @@ -342,7 +338,7 @@ impl Convert<(u16, CurrencyId), MultiLocation> for SubAccountIndexMultiLocationC // Other sibling chains use the Bifrost para account with "sibl" _ => { // get parachain id - if let Some(location) = BifrostCurrencyIdConvert::convert(currency_id) { + if let Some(location) = CurrencyIdConvert::convert(currency_id) { if let Some(Parachain(para_id)) = location.interior().first() { MultiLocation::new( 1, @@ -411,8 +407,8 @@ impl QueryResponseManager for () { } } -pub struct BifrostCurrencyIdConvert; -impl Convert> for BifrostCurrencyIdConvert { +pub struct CurrencyIdConvert; +impl Convert> for CurrencyIdConvert { fn convert(id: CurrencyId) -> Option { use CurrencyId::*; use TokenSymbol::*; diff --git a/pallets/slp/src/mocks/mock_kusama.rs b/pallets/slp/src/mocks/mock_kusama.rs index 8c54946b3..6aeafbf7c 100644 --- a/pallets/slp/src/mocks/mock_kusama.rs +++ b/pallets/slp/src/mocks/mock_kusama.rs @@ -25,8 +25,8 @@ use crate::{Config, DispatchResult, QueryResponseManager}; use bifrost_asset_registry::AssetIdMaps; use bifrost_primitives::{ currency::{BNC, KSM, MANTA}, - Amount, Balance, CurrencyId, DoNothingExecuteXcm, DoNothingRouter, SlpxOperator, TokenSymbol, - XcmDestWeightAndFeeHandler, XcmOperationType, + Amount, Balance, CurrencyId, MockXcmExecutor, MockXcmRouter, MoonbeamChainId, SlpxOperator, + TokenSymbol, XcmDestWeightAndFeeHandler, XcmOperationType, }; pub use cumulus_primitives_core::ParaId; use frame_support::{ @@ -218,11 +218,11 @@ impl orml_xtokens::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type CurrencyId = CurrencyId; - type CurrencyIdConvert = BifrostCurrencyIdConvert; + type CurrencyIdConvert = CurrencyIdConvert; type AccountIdToLocation = (); type UniversalLocation = UniversalLocation; type SelfLocation = SelfRelativeLocation; - type XcmExecutor = DoNothingExecuteXcm; + type XcmExecutor = MockXcmExecutor; type Weigher = FixedWeightBounds; type BaseXcmWeight = BaseXcmWeight; type MaxAssetsForTransfer = MaxAssetsForTransfer; @@ -267,15 +267,11 @@ impl bifrost_vtoken_minting::Config for Runtime { type WeightInfo = (); type OnRedeemSuccess = (); type XcmTransfer = XTokens; - type AstarParachainId = ConstU32<2007>; - type MoonbeamParachainId = ConstU32<2023>; - type HydradxParachainId = ConstU32<2034>; - type MantaParachainId = ConstU32<2104>; - type InterlayParachainId = ConstU32<2032>; + type MoonbeamChainId = MoonbeamChainId; type ChannelCommission = (); type MaxLockRecords = ConstU32<100>; type IncentivePoolAccount = IncentivePoolAccount; - type VeMinting = (); + type BbBNC = (); type AssetIdMaps = AssetIdMaps; } @@ -399,7 +395,7 @@ impl Convert<(u16, CurrencyId), MultiLocation> for SubAccountIndexMultiLocationC ), MANTA => { // get parachain id - if let Some(location) = BifrostCurrencyIdConvert::convert(currency_id) { + if let Some(location) = CurrencyIdConvert::convert(currency_id) { let v3_location = xcm::v3::Location::try_from(location).unwrap(); if let Some(Parachain(para_id)) = v3_location.interior().first() { MultiLocation::new( @@ -429,7 +425,7 @@ impl Convert<(u16, CurrencyId), MultiLocation> for SubAccountIndexMultiLocationC // Other sibling chains use the Bifrost para account with "sibl" _ => { // get parachain id - if let Some(location) = BifrostCurrencyIdConvert::convert(currency_id) { + if let Some(location) = CurrencyIdConvert::convert(currency_id) { let v3_location = xcm::v3::Location::try_from(location).unwrap(); if let Some(Parachain(para_id)) = v3_location.interior().first() { MultiLocation::new( @@ -482,8 +478,8 @@ parameter_types! { pub const MaxLengthLimit: u32 = 100; } -pub struct BifrostCurrencyIdConvert; -impl Convert> for BifrostCurrencyIdConvert { +pub struct CurrencyIdConvert; +impl Convert> for CurrencyIdConvert { fn convert(id: CurrencyId) -> Option { use CurrencyId::*; use TokenSymbol::*; @@ -604,7 +600,7 @@ impl xcm_executor::Config for XcmConfig { type SubscriptionService = PolkadotXcm; type Trader = (); type Weigher = FixedWeightBounds; - type XcmSender = DoNothingRouter; + type XcmSender = MockXcmRouter; type PalletInstancesInfo = AllPalletsWithSystem; type MaxAssetsIntoHolding = ConstU32<64>; type FeeManager = (); @@ -634,9 +630,9 @@ impl pallet_xcm::Config for Runtime { type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; type Weigher = FixedWeightBounds; type XcmExecuteFilter = Nothing; - type XcmExecutor = DoNothingExecuteXcm; + type XcmExecutor = MockXcmExecutor; type XcmReserveTransferFilter = Everything; - type XcmRouter = DoNothingRouter; + type XcmRouter = MockXcmRouter; type XcmTeleportFilter = Nothing; type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; diff --git a/pallets/slp/src/tests/kusama_tests.rs b/pallets/slp/src/tests/kusama_tests.rs index 20731999f..8ca215b76 100644 --- a/pallets/slp/src/tests/kusama_tests.rs +++ b/pallets/slp/src/tests/kusama_tests.rs @@ -20,6 +20,7 @@ use crate::{mocks::mock_kusama::*, *}; use bifrost_primitives::currency::{KSM, VKSM}; +use bifrost_vtoken_minting::{OngoingTimeUnit, TokenPool}; use frame_support::{assert_ok, PalletId}; use orml_traits::MultiCurrency; use sp_runtime::traits::AccountIdConversion; @@ -140,7 +141,7 @@ fn decrease_token_pool_works() { assert_ok!(Slp::decrease_token_pool(RuntimeOrigin::signed(ALICE), KSM, 10)); // Check the value after decreasing - assert_eq!(VtokenMinting::token_pool(KSM), 90); + assert_eq!(TokenPool::::get(KSM), 90); }); } @@ -166,7 +167,7 @@ fn update_ongoing_time_unit_works() { )); // Check the value after updating. - assert_eq!(VtokenMinting::ongoing_time_unit(KSM), Some(TimeUnit::Era(9))); + assert_eq!(OngoingTimeUnit::::get(KSM), Some(TimeUnit::Era(9))); }); } @@ -279,7 +280,8 @@ fn set_hosting_fees_works() { Some((pct, treasury_location)) )); - let (fee, location) = Slp::get_hosting_fee(KSM).unwrap(); + // let (fee, location) = Slp::get_hosting_fee(KSM).unwrap(); + let (fee, location) = HostingFees::::get(KSM).unwrap(); assert_eq!(fee, pct); assert_eq!(location, treasury_location); }); diff --git a/pallets/slp/src/tests/manta_tests.rs b/pallets/slp/src/tests/manta_tests.rs index 3e3d1fd1c..a149bbd16 100644 --- a/pallets/slp/src/tests/manta_tests.rs +++ b/pallets/slp/src/tests/manta_tests.rs @@ -1619,7 +1619,7 @@ fn add_validator_and_remove_validator_works() { let bounded_valis = BoundedVec::try_from(valis).unwrap(); - assert_eq!(Slp::get_validators(MANTA), Some(bounded_valis)); + assert_eq!(Validators::::get(MANTA), Some(bounded_valis)); assert_ok!(Slp::remove_validator( RuntimeOrigin::signed(ALICE), @@ -1628,7 +1628,7 @@ fn add_validator_and_remove_validator_works() { )); let empty_bounded_vec = BoundedVec::default(); - assert_eq!(Slp::get_validators(MANTA), Some(empty_bounded_vec)); + assert_eq!(Validators::::get(MANTA), Some(empty_bounded_vec)); }); } @@ -1655,7 +1655,7 @@ fn reset_validators_should_work() { validator_list_input )); - assert_eq!(Slp::get_validators(MANTA), Some(validator_list_output)); + assert_eq!(Validators::::get(MANTA), Some(validator_list_output)); }); } @@ -1695,9 +1695,12 @@ fn set_validator_boost_list_should_work() { let bounded_validator_list_output_1 = BoundedVec::try_from(validator_list_output_1).unwrap(); - assert_eq!(Slp::get_validator_boost_list(MANTA), Some(bounded_validator_list_output_1)); + assert_eq!( + ValidatorBoostList::::get(MANTA), + Some(bounded_validator_list_output_1) + ); let bounded_validator_0 = BoundedVec::try_from(vec![VALIDATOR_0_LOCATION]).unwrap(); - assert_eq!(Slp::get_validators(MANTA), Some(bounded_validator_0)); + assert_eq!(Validators::::get(MANTA), Some(bounded_validator_0)); System::set_block_number(400); @@ -1709,10 +1712,13 @@ fn set_validator_boost_list_should_work() { let bounded_validator_list_output_2 = BoundedVec::try_from(validator_list_output_2).unwrap(); - assert_eq!(Slp::get_validator_boost_list(MANTA), Some(bounded_validator_list_output_2)); + assert_eq!( + ValidatorBoostList::::get(MANTA), + Some(bounded_validator_list_output_2) + ); let bounded_validator_0_1 = BoundedVec::try_from(vec![VALIDATOR_0_LOCATION, VALIDATOR_1_LOCATION]).unwrap(); - assert_eq!(Slp::get_validators(MANTA), Some(bounded_validator_0_1),); + assert_eq!(Validators::::get(MANTA), Some(bounded_validator_0_1),); }); } @@ -1740,10 +1746,10 @@ fn add_to_validator_boost_list_should_work() { Box::new(VALIDATOR_0_LOCATION) )); - assert_eq!(Slp::get_validator_boost_list(MANTA), Some(validator_list_output_1)); + assert_eq!(ValidatorBoostList::::get(MANTA), Some(validator_list_output_1)); let bounded_validator_0 = BoundedVec::try_from(vec![VALIDATOR_0_LOCATION]).unwrap(); - assert_eq!(Slp::get_validators(MANTA), Some(bounded_validator_0.clone())); + assert_eq!(Validators::::get(MANTA), Some(bounded_validator_0.clone())); System::set_block_number(400); @@ -1753,9 +1759,9 @@ fn add_to_validator_boost_list_should_work() { Box::new(VALIDATOR_0_LOCATION) )); - assert_eq!(Slp::get_validators(MANTA), Some(bounded_validator_0)); + assert_eq!(Validators::::get(MANTA), Some(bounded_validator_0)); - assert_eq!(Slp::get_validator_boost_list(MANTA), Some(validator_list_output_2)); + assert_eq!(ValidatorBoostList::::get(MANTA), Some(validator_list_output_2)); assert_ok!(Slp::add_to_validator_boost_list( RuntimeOrigin::signed(ALICE), @@ -1763,10 +1769,10 @@ fn add_to_validator_boost_list_should_work() { Box::new(VALIDATOR_1_LOCATION) )); - assert_eq!(Slp::get_validator_boost_list(MANTA), Some(validator_list_output_3)); + assert_eq!(ValidatorBoostList::::get(MANTA), Some(validator_list_output_3)); let bounded_validator_0_1 = BoundedVec::try_from(vec![VALIDATOR_0_LOCATION, VALIDATOR_1_LOCATION]).unwrap(); - assert_eq!(Slp::get_validators(MANTA), Some(bounded_validator_0_1),); + assert_eq!(Validators::::get(MANTA), Some(bounded_validator_0_1),); }); } @@ -1784,7 +1790,7 @@ fn remove_from_validator_boost_list_should_work() { Box::new(VALIDATOR_0_LOCATION) )); - assert_eq!(Slp::get_validator_boost_list(MANTA), Some(validator_list_output.clone())); + assert_eq!(ValidatorBoostList::::get(MANTA), Some(validator_list_output.clone())); assert_ok!(Slp::remove_from_validator_boot_list( RuntimeOrigin::signed(ALICE), @@ -1792,7 +1798,7 @@ fn remove_from_validator_boost_list_should_work() { Box::new(VALIDATOR_1_LOCATION) )); - assert_eq!(Slp::get_validator_boost_list(MANTA), Some(validator_list_output)); + assert_eq!(ValidatorBoostList::::get(MANTA), Some(validator_list_output)); assert_ok!(Slp::remove_from_validator_boot_list( RuntimeOrigin::signed(ALICE), @@ -1800,7 +1806,7 @@ fn remove_from_validator_boost_list_should_work() { Box::new(VALIDATOR_0_LOCATION) )); - assert_eq!(Slp::get_validator_boost_list(MANTA), None); + assert_eq!(ValidatorBoostList::::get(MANTA), None); }); } @@ -1834,10 +1840,10 @@ fn clean_outdated_validator_boost_list_work() { Box::new(VALIDATOR_0_LOCATION) )); - assert_eq!(Slp::get_validator_boost_list(MANTA), Some(validator_list_output_1)); + assert_eq!(ValidatorBoostList::::get(MANTA), Some(validator_list_output_1)); let bounded_validator_0 = BoundedVec::try_from(vec![VALIDATOR_0_LOCATION]).unwrap(); - assert_eq!(Slp::get_validators(MANTA), Some(bounded_validator_0.clone())); + assert_eq!(Validators::::get(MANTA), Some(bounded_validator_0.clone())); System::set_block_number(400); @@ -1847,9 +1853,12 @@ fn clean_outdated_validator_boost_list_work() { Box::new(VALIDATOR_0_LOCATION) )); - assert_eq!(Slp::get_validators(MANTA), Some(bounded_validator_0)); + assert_eq!(Validators::::get(MANTA), Some(bounded_validator_0)); - assert_eq!(Slp::get_validator_boost_list(MANTA), Some(validator_list_output_2.clone())); + assert_eq!( + ValidatorBoostList::::get(MANTA), + Some(validator_list_output_2.clone()) + ); assert_ok!(Slp::add_to_validator_boost_list( RuntimeOrigin::signed(ALICE), @@ -1857,10 +1866,13 @@ fn clean_outdated_validator_boost_list_work() { Box::new(VALIDATOR_1_LOCATION) )); - assert_eq!(Slp::get_validator_boost_list(MANTA), Some(validator_list_output_3.clone())); + assert_eq!( + ValidatorBoostList::::get(MANTA), + Some(validator_list_output_3.clone()) + ); let bounded_validator_0_1 = BoundedVec::try_from(vec![VALIDATOR_0_LOCATION, VALIDATOR_1_LOCATION]).unwrap(); - assert_eq!(Slp::get_validators(MANTA), Some(bounded_validator_0_1),); + assert_eq!(Validators::::get(MANTA), Some(bounded_validator_0_1),); // no validator due yet. Everything should be kept after calling // clean_outdated_validator_boost_list @@ -1871,7 +1883,7 @@ fn clean_outdated_validator_boost_list_work() { MANTA, 1 )); - assert_eq!(Slp::get_validator_boost_list(MANTA), Some(validator_list_output_3)); + assert_eq!(ValidatorBoostList::::get(MANTA), Some(validator_list_output_3)); // move to block SIX_MONTHS + 400, validator 1 should be removable System::set_block_number(400 + SIX_MONTHS as u64); @@ -1888,7 +1900,10 @@ fn clean_outdated_validator_boost_list_work() { MANTA, 1 )); - assert_eq!(Slp::get_validator_boost_list(MANTA), Some(validator_list_output_2.clone())); + assert_eq!( + ValidatorBoostList::::get(MANTA), + Some(validator_list_output_2.clone()) + ); // do it again assert_ok!(Slp::clean_outdated_validator_boost_list( @@ -1896,7 +1911,7 @@ fn clean_outdated_validator_boost_list_work() { MANTA, 1 )); - assert_eq!(Slp::get_validator_boost_list(MANTA), Some(validator_list_output_2)); + assert_eq!(ValidatorBoostList::::get(MANTA), Some(validator_list_output_2)); assert_noop!( Slp::clean_outdated_validator_boost_list(RuntimeOrigin::signed(ALICE), MANTA, 2), diff --git a/pallets/slp/src/tests/moonriver_tests.rs b/pallets/slp/src/tests/moonriver_tests.rs index 64f523732..34d7f1839 100644 --- a/pallets/slp/src/tests/moonriver_tests.rs +++ b/pallets/slp/src/tests/moonriver_tests.rs @@ -1641,7 +1641,7 @@ fn add_validator_and_remove_validator_works() { let bounded_valis = BoundedVec::try_from(valis).unwrap(); - assert_eq!(Slp::get_validators(MOVR), Some(bounded_valis)); + assert_eq!(Validators::::get(MOVR), Some(bounded_valis)); assert_ok!(Slp::remove_validator( RuntimeOrigin::signed(ALICE), @@ -1650,7 +1650,7 @@ fn add_validator_and_remove_validator_works() { )); let empty_bounded_vec = BoundedVec::default(); - assert_eq!(Slp::get_validators(MOVR), Some(empty_bounded_vec)); + assert_eq!(Validators::::get(MOVR), Some(empty_bounded_vec)); }); } @@ -1673,7 +1673,7 @@ fn reset_validators_should_work() { assert_ok!(Slp::reset_validators(RuntimeOrigin::signed(ALICE), MOVR, validator_list_input)); - assert_eq!(Slp::get_validators(MOVR), Some(validator_list_output)); + assert_eq!(Validators::::get(MOVR), Some(validator_list_output)); }); } @@ -1709,9 +1709,9 @@ fn set_validator_boost_list_should_work() { let bounded_validator_list_output_1 = BoundedVec::try_from(validator_list_output_1).unwrap(); - assert_eq!(Slp::get_validator_boost_list(MOVR), Some(bounded_validator_list_output_1)); + assert_eq!(ValidatorBoostList::::get(MOVR), Some(bounded_validator_list_output_1)); let bounded_validator_0 = BoundedVec::try_from(vec![VALIDATOR_0_LOCATION]).unwrap(); - assert_eq!(Slp::get_validators(MOVR), Some(bounded_validator_0)); + assert_eq!(Validators::::get(MOVR), Some(bounded_validator_0)); System::set_block_number(400); @@ -1723,10 +1723,10 @@ fn set_validator_boost_list_should_work() { let bounded_validator_list_output_2 = BoundedVec::try_from(validator_list_output_2).unwrap(); - assert_eq!(Slp::get_validator_boost_list(MOVR), Some(bounded_validator_list_output_2)); + assert_eq!(ValidatorBoostList::::get(MOVR), Some(bounded_validator_list_output_2)); let bounded_validator_0_1 = BoundedVec::try_from(vec![VALIDATOR_0_LOCATION, VALIDATOR_1_LOCATION]).unwrap(); - assert_eq!(Slp::get_validators(MOVR), Some(bounded_validator_0_1),); + assert_eq!(Validators::::get(MOVR), Some(bounded_validator_0_1),); }); } @@ -1754,10 +1754,10 @@ fn add_to_validator_boost_list_should_work() { Box::new(VALIDATOR_0_LOCATION) )); - assert_eq!(Slp::get_validator_boost_list(MOVR), Some(validator_list_output_1)); + assert_eq!(ValidatorBoostList::::get(MOVR), Some(validator_list_output_1)); let bounded_validator_0 = BoundedVec::try_from(vec![VALIDATOR_0_LOCATION]).unwrap(); - assert_eq!(Slp::get_validators(MOVR), Some(bounded_validator_0.clone())); + assert_eq!(Validators::::get(MOVR), Some(bounded_validator_0.clone())); System::set_block_number(400); @@ -1767,9 +1767,9 @@ fn add_to_validator_boost_list_should_work() { Box::new(VALIDATOR_0_LOCATION) )); - assert_eq!(Slp::get_validators(MOVR), Some(bounded_validator_0)); + assert_eq!(Validators::::get(MOVR), Some(bounded_validator_0)); - assert_eq!(Slp::get_validator_boost_list(MOVR), Some(validator_list_output_2)); + assert_eq!(ValidatorBoostList::::get(MOVR), Some(validator_list_output_2)); assert_ok!(Slp::add_to_validator_boost_list( RuntimeOrigin::signed(ALICE), @@ -1777,10 +1777,10 @@ fn add_to_validator_boost_list_should_work() { Box::new(VALIDATOR_1_LOCATION) )); - assert_eq!(Slp::get_validator_boost_list(MOVR), Some(validator_list_output_3)); + assert_eq!(ValidatorBoostList::::get(MOVR), Some(validator_list_output_3)); let bounded_validator_0_1 = BoundedVec::try_from(vec![VALIDATOR_0_LOCATION, VALIDATOR_1_LOCATION]).unwrap(); - assert_eq!(Slp::get_validators(MOVR), Some(bounded_validator_0_1),); + assert_eq!(Validators::::get(MOVR), Some(bounded_validator_0_1),); }); } @@ -1798,7 +1798,7 @@ fn remove_from_validator_boost_list_should_work() { Box::new(VALIDATOR_0_LOCATION) )); - assert_eq!(Slp::get_validator_boost_list(MOVR), Some(validator_list_output.clone())); + assert_eq!(ValidatorBoostList::::get(MOVR), Some(validator_list_output.clone())); assert_ok!(Slp::remove_from_validator_boot_list( RuntimeOrigin::signed(ALICE), @@ -1806,7 +1806,7 @@ fn remove_from_validator_boost_list_should_work() { Box::new(VALIDATOR_1_LOCATION) )); - assert_eq!(Slp::get_validator_boost_list(MOVR), Some(validator_list_output)); + assert_eq!(ValidatorBoostList::::get(MOVR), Some(validator_list_output)); assert_ok!(Slp::remove_from_validator_boot_list( RuntimeOrigin::signed(ALICE), @@ -1814,6 +1814,6 @@ fn remove_from_validator_boost_list_should_work() { Box::new(VALIDATOR_0_LOCATION) )); - assert_eq!(Slp::get_validator_boost_list(MOVR), None); + assert_eq!(ValidatorBoostList::::get(MOVR), None); }); } diff --git a/pallets/slp/src/tests/parachain_staking_tests.rs b/pallets/slp/src/tests/parachain_staking_tests.rs index 69a8758c5..8dba07be9 100644 --- a/pallets/slp/src/tests/parachain_staking_tests.rs +++ b/pallets/slp/src/tests/parachain_staking_tests.rs @@ -25,7 +25,7 @@ use crate::{ }, BNC, *, }; -use bifrost_parachain_staking::RoundInfo; +use bifrost_parachain_staking::{Round, RoundInfo}; use bifrost_primitives::VBNC; use frame_support::{assert_noop, assert_ok, PalletId}; use parity_scale_codec::alloc::collections::BTreeMap; @@ -279,7 +279,7 @@ fn parachain_staking_bond_to_liquidize_works() { TimeUnit::Round(48) )); bifrost_parachain_staking::Round::::set(RoundInfo::new(10000000, 0, 1)); - assert_eq!(ParachainStaking::round(), RoundInfo::new(10000000, 0, 1)); + assert_eq!(Round::::get(), RoundInfo::new(10000000, 0, 1)); assert_ok!(VtokenMinting::update_ongoing_time_unit(BNC, TimeUnit::Round(1000))); // let delegation_scheduled_requests = ParachainStaking::delegation_scheduled_requests(BOB); @@ -885,7 +885,7 @@ fn add_validator_and_remove_validator_works() { valis.push(validator_0_location); let bounded_valis = BoundedVec::try_from(valis).unwrap(); - assert_eq!(Slp::get_validators(BNC), Some(bounded_valis)); + assert_eq!(Validators::::get(BNC), Some(bounded_valis)); assert_ok!(Slp::remove_validator( RuntimeOrigin::signed(ALICE), @@ -894,7 +894,7 @@ fn add_validator_and_remove_validator_works() { )); let empty_bounded_vec = BoundedVec::default(); - assert_eq!(Slp::get_validators(BNC), Some(empty_bounded_vec)); + assert_eq!(Validators::::get(BNC), Some(empty_bounded_vec)); }); } diff --git a/pallets/slp/src/tests/phala_tests.rs b/pallets/slp/src/tests/phala_tests.rs index c81be3d3a..f5a930017 100644 --- a/pallets/slp/src/tests/phala_tests.rs +++ b/pallets/slp/src/tests/phala_tests.rs @@ -1408,7 +1408,7 @@ fn add_validator_and_remove_validator_works() { valis.push(VALIDATOR_0_LOCATION); let bounded_valis = BoundedVec::try_from(valis).unwrap(); - assert_eq!(Slp::get_validators(PHA), Some(bounded_valis)); + assert_eq!(Validators::::get(PHA), Some(bounded_valis)); assert_ok!(Slp::delegate( RuntimeOrigin::signed(ALICE), @@ -1425,7 +1425,7 @@ fn add_validator_and_remove_validator_works() { )); let empty_bounded_vec = BoundedVec::default(); - assert_eq!(Slp::get_validators(PHA), Some(empty_bounded_vec)); + assert_eq!(Validators::::get(PHA), Some(empty_bounded_vec)); }); } diff --git a/pallets/slpx/src/lib.rs b/pallets/slpx/src/lib.rs index 90b970239..37da11083 100644 --- a/pallets/slpx/src/lib.rs +++ b/pallets/slpx/src/lib.rs @@ -25,7 +25,8 @@ use crate::types::{ use bifrost_asset_registry::AssetMetadata; use bifrost_primitives::{ currency::{BNC, VFIL}, - CurrencyId, CurrencyIdMapping, RedeemType, SlpxOperator, TokenInfo, VtokenMintingInterface, + AstarChainId, CurrencyId, CurrencyIdMapping, HydrationChainId, InterlayChainId, MantaChainId, + RedeemType, SlpxOperator, TokenInfo, VtokenMintingInterface, }; use cumulus_primitives_core::ParaId; use ethereum::TransactionAction; @@ -60,8 +61,6 @@ pub mod types; pub mod weights; pub use weights::WeightInfo; -const BIFROST_KUSAMA_PARA_ID: u32 = 2001; - #[cfg(test)] mod mock; @@ -75,7 +74,7 @@ mod benchmarking; pub mod pallet { use super::*; use crate::types::{Order, OrderType}; - use bifrost_primitives::{currency::MOVR, GLMR}; + use bifrost_primitives::{currency::MOVR, BifrostKusamaChainId, GLMR}; use bifrost_stable_pool::{traits::StablePoolHandler, PoolTokenIndex, StableAssetPoolId}; use frame_support::{ pallet_prelude::{ValueQuery, *}, @@ -267,7 +266,6 @@ pub mod pallet { /// Contract whitelist #[pallet::storage] - #[pallet::getter(fn whitelist_account_ids)] pub type WhitelistAccountId = StorageMap< _, Blake2_128Concat, @@ -278,28 +276,23 @@ pub mod pallet { /// Charge corresponding fees for different CurrencyId #[pallet::storage] - #[pallet::getter(fn execution_fee)] pub type ExecutionFee = StorageMap<_, Blake2_128Concat, CurrencyId, BalanceOf, OptionQuery>; /// XCM fee for transferring to Moonbeam(BNC) #[pallet::storage] - #[pallet::getter(fn transfer_to_fee)] pub type TransferToFee = StorageMap<_, Blake2_128Concat, SupportChain, BalanceOf, OptionQuery>; #[pallet::storage] - #[pallet::getter(fn xcm_ethereum_call_configuration)] pub type XcmEthereumCallConfiguration = StorageValue<_, EthereumCallConfiguration>>; #[pallet::storage] - #[pallet::getter(fn currency_id_list)] pub type CurrencyIdList = StorageValue<_, BoundedVec>, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn support_xcm_fee_list)] pub type SupportXcmFeeList = StorageValue<_, BoundedVec>, ValueQuery>; @@ -370,7 +363,7 @@ pub mod pallet { }); let mut target_fee_currency_id = GLMR; - if T::ParachainId::get() == Id::from(BIFROST_KUSAMA_PARA_ID) { + if T::ParachainId::get() == Id::from(BifrostKusamaChainId::get()) { target_fee_currency_id = MOVR; } @@ -500,7 +493,7 @@ pub mod pallet { Self::ensure_singer_on_whitelist(origin, evm_caller, &target_chain)?; if vtoken_id == VFIL { - let fee_amount = Self::transfer_to_fee(SupportChain::Moonbeam) + let fee_amount = TransferToFee::::get(SupportChain::Moonbeam) .unwrap_or_else(|| Self::get_default_fee(BNC)); T::MultiCurrency::transfer( BNC, @@ -914,8 +907,8 @@ impl Pallet { evm_caller_account_id: &AccountIdOf, ) -> Result, DispatchError> { let free_balance = T::MultiCurrency::free_balance(currency_id, evm_caller_account_id); - let execution_fee = - Self::execution_fee(currency_id).unwrap_or_else(|| Self::get_default_fee(currency_id)); + let execution_fee = ExecutionFee::::get(currency_id) + .unwrap_or_else(|| Self::get_default_fee(currency_id)); T::MultiCurrency::transfer( currency_id, @@ -942,7 +935,7 @@ impl Pallet { let dest = Location::new( 1, [ - Parachain(T::VtokenMintingInterface::get_astar_parachain_id()), + Parachain(AstarChainId::get()), AccountId32 { network: None, id: receiver.encode().try_into().unwrap() }, ], ); @@ -953,7 +946,7 @@ impl Pallet { let dest = Location::new( 1, [ - Parachain(T::VtokenMintingInterface::get_hydradx_parachain_id()), + Parachain(HydrationChainId::get()), AccountId32 { network: None, id: receiver.encode().try_into().unwrap() }, ], ); @@ -964,7 +957,7 @@ impl Pallet { let dest = Location::new( 1, [ - Parachain(T::VtokenMintingInterface::get_interlay_parachain_id()), + Parachain(InterlayChainId::get()), AccountId32 { network: None, id: receiver.encode().try_into().unwrap() }, ], ); @@ -975,7 +968,7 @@ impl Pallet { let dest = Location::new( 1, [ - Parachain(T::VtokenMintingInterface::get_manta_parachain_id()), + Parachain(MantaChainId::get()), AccountId32 { network: None, id: receiver.encode().try_into().unwrap() }, ], ); @@ -993,7 +986,7 @@ impl Pallet { if SupportXcmFeeList::::get().contains(¤cy_id) { T::XcmTransfer::transfer(caller, currency_id, amount, dest, Unlimited)?; } else { - let fee_amount = Self::transfer_to_fee(SupportChain::Moonbeam) + let fee_amount = TransferToFee::::get(SupportChain::Moonbeam) .unwrap_or_else(|| Self::get_default_fee(BNC)); T::MultiCurrency::transfer(BNC, evm_contract_account_id, &caller, fee_amount)?; let assets = vec![(currency_id, amount), (BNC, fee_amount)]; @@ -1084,6 +1077,7 @@ impl Pallet { // Functions to be called by other pallets. impl SlpxOperator> for Pallet { fn get_moonbeam_transfer_to_fee() -> BalanceOf { - Self::transfer_to_fee(SupportChain::Moonbeam).unwrap_or_else(|| Self::get_default_fee(BNC)) + TransferToFee::::get(SupportChain::Moonbeam) + .unwrap_or_else(|| Self::get_default_fee(BNC)) } } diff --git a/pallets/slpx/src/mock.rs b/pallets/slpx/src/mock.rs index 951b740f7..ea6eaf1e8 100644 --- a/pallets/slpx/src/mock.rs +++ b/pallets/slpx/src/mock.rs @@ -19,8 +19,9 @@ use crate as slpx; use bifrost_asset_registry::AssetIdMaps; +use bifrost_primitives::MoonbeamChainId; pub use bifrost_primitives::{ - CurrencyId, CurrencyIdMapping, DoNothingExecuteXcm, SlpxOperator, TokenSymbol, BNC, KSM, + CurrencyId, CurrencyIdMapping, MockXcmExecutor, SlpxOperator, TokenSymbol, BNC, KSM, }; use bifrost_slp::{QueryId, QueryResponseManager}; use cumulus_primitives_core::ParaId; @@ -196,15 +197,11 @@ impl bifrost_vtoken_minting::Config for Test { type WeightInfo = (); type OnRedeemSuccess = (); type XcmTransfer = XTokens; - type AstarParachainId = ConstU32<2007>; - type MoonbeamParachainId = ConstU32<2023>; - type HydradxParachainId = ConstU32<2034>; - type MantaParachainId = ConstU32<2104>; - type InterlayParachainId = ConstU32<2032>; + type MoonbeamChainId = MoonbeamChainId; type ChannelCommission = (); type MaxLockRecords = ConstU32<100>; type IncentivePoolAccount = IncentivePoolAccount; - type VeMinting = (); + type BbBNC = (); type AssetIdMaps = AssetIdMaps; } // Below is the implementation of tokens manipulation functions other than native token. @@ -345,14 +342,14 @@ parameter_types! { pub const MaxAssetsForTransfer: usize = 2; } -pub struct BifrostCurrencyIdConvert(sp_std::marker::PhantomData); -impl> Convert> for BifrostCurrencyIdConvert { +pub struct CurrencyIdConvert(sp_std::marker::PhantomData); +impl> Convert> for CurrencyIdConvert { fn convert(id: CurrencyId) -> Option { AssetIdMaps::::get_location(id) } } -impl> Convert> for BifrostCurrencyIdConvert { +impl> Convert> for CurrencyIdConvert { fn convert(location: Location) -> Option { AssetIdMaps::::get_currency_id(location) } @@ -364,11 +361,11 @@ impl orml_xtokens::Config for Test { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type CurrencyId = CurrencyId; - type CurrencyIdConvert = BifrostCurrencyIdConvert; + type CurrencyIdConvert = CurrencyIdConvert; type AccountIdToLocation = (); type UniversalLocation = UniversalLocation; type SelfLocation = SelfRelativeLocation; - type XcmExecutor = DoNothingExecuteXcm; + type XcmExecutor = MockXcmExecutor; type Weigher = FixedWeightBounds; type BaseXcmWeight = BaseXcmWeight; type MaxAssetsForTransfer = MaxAssetsForTransfer; @@ -454,9 +451,9 @@ impl pallet_xcm::Config for Test { type SendXcmOrigin = EnsureXcmOrigin; type Weigher = FixedWeightBounds; type XcmExecuteFilter = Nothing; - type XcmExecutor = DoNothingExecuteXcm; + type XcmExecutor = MockXcmExecutor; type XcmReserveTransferFilter = Everything; - type XcmRouter = bifrost_primitives::DoNothingRouter; + type XcmRouter = bifrost_primitives::MockXcmRouter; type XcmTeleportFilter = Nothing; type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; diff --git a/pallets/slpx/src/tests.rs b/pallets/slpx/src/tests.rs index 2ab622765..aa58302dc 100644 --- a/pallets/slpx/src/tests.rs +++ b/pallets/slpx/src/tests.rs @@ -58,7 +58,7 @@ fn test_whitelist_work() { assert_ok!(Slpx::add_whitelist(RuntimeOrigin::root(), SupportChain::Astar, ALICE)); assert_ok!(Slpx::add_whitelist(RuntimeOrigin::root(), SupportChain::Astar, BOB)); assert_eq!( - Slpx::whitelist_account_ids(SupportChain::Astar), + WhitelistAccountId::::get(SupportChain::Astar), BoundedVec::>::try_from(vec![ALICE, BOB]).unwrap() ); assert_noop!( @@ -67,7 +67,7 @@ fn test_whitelist_work() { ); assert_ok!(Slpx::remove_whitelist(RuntimeOrigin::root(), SupportChain::Astar, ALICE)); assert_eq!( - Slpx::whitelist_account_ids(SupportChain::Astar), + WhitelistAccountId::::get(SupportChain::Astar), BoundedVec::>::try_from(vec![BOB]).unwrap() ); @@ -111,7 +111,7 @@ fn test_execution_fee_work() { CurrencyId::Token2(0), 10 * 1_000_000_000 )); - assert_eq!(Slpx::execution_fee(CurrencyId::Token2(0)), Some(10 * 1_000_000_000)); + assert_eq!(ExecutionFee::::get(CurrencyId::Token2(0)), Some(10 * 1_000_000_000)); let balance_exclude_fee = Slpx::charge_execution_fee(CurrencyId::Token2(0), &ALICE).unwrap(); @@ -122,7 +122,7 @@ fn test_execution_fee_work() { SupportChain::Moonbeam, 10 * 1_000_000_000 )); - assert_eq!(Slpx::transfer_to_fee(SupportChain::Moonbeam), Some(10 * 1_000_000_000)); + assert_eq!(TransferToFee::::get(SupportChain::Moonbeam), Some(10 * 1_000_000_000)); }); } @@ -277,13 +277,13 @@ fn test_ethereum_call() { fn test_set_currency_ethereum_call_switch() { sp_io::TestExternalities::default().execute_with(|| { assert_ok!(Slpx::set_currency_ethereum_call_switch(RuntimeOrigin::root(), BNC, true)); - assert_eq!(Slpx::currency_id_list().to_vec(), vec![BNC]); + assert_eq!(CurrencyIdList::::get().to_vec(), vec![BNC]); assert_ok!(Slpx::set_currency_ethereum_call_switch(RuntimeOrigin::root(), KSM, true)); - assert_eq!(Slpx::currency_id_list().to_vec(), vec![BNC, KSM]); + assert_eq!(CurrencyIdList::::get().to_vec(), vec![BNC, KSM]); assert_ok!(Slpx::set_currency_ethereum_call_switch(RuntimeOrigin::root(), BNC, false)); - assert_eq!(Slpx::currency_id_list().to_vec(), vec![KSM]); + assert_eq!(CurrencyIdList::::get().to_vec(), vec![KSM]); }) } @@ -299,7 +299,7 @@ fn test_set_ethereum_call_configration() { )); assert_eq!( - Slpx::xcm_ethereum_call_configuration().unwrap(), + XcmEthereumCallConfiguration::::get().unwrap(), EthereumCallConfiguration { xcm_fee: 1_000_000_000_000_000_000u128, xcm_weight: Weight::default(), @@ -318,7 +318,7 @@ fn test_set_ethereum_call_configration() { )); assert_eq!( - Slpx::xcm_ethereum_call_configuration().unwrap(), + XcmEthereumCallConfiguration::::get().unwrap(), EthereumCallConfiguration { xcm_fee: 1u128, xcm_weight: Weight::default(), @@ -334,13 +334,13 @@ fn test_set_ethereum_call_configration() { fn test_set_currency_to_support_xcm_fee() { sp_io::TestExternalities::default().execute_with(|| { assert_ok!(Slpx::set_currency_support_xcm_fee(RuntimeOrigin::root(), BNC, true)); - assert_eq!(Slpx::support_xcm_fee_list().to_vec(), vec![BNC]); + assert_eq!(SupportXcmFeeList::::get().to_vec(), vec![BNC]); assert_ok!(Slpx::set_currency_support_xcm_fee(RuntimeOrigin::root(), KSM, true)); - assert_eq!(Slpx::support_xcm_fee_list().to_vec(), vec![BNC, KSM]); + assert_eq!(SupportXcmFeeList::::get().to_vec(), vec![BNC, KSM]); assert_ok!(Slpx::set_currency_support_xcm_fee(RuntimeOrigin::root(), BNC, false)); - assert_eq!(Slpx::support_xcm_fee_list().to_vec(), vec![KSM]); + assert_eq!(SupportXcmFeeList::::get().to_vec(), vec![KSM]); }) } diff --git a/pallets/slpx/src/weights.rs b/pallets/slpx/src/weights.rs index 446fdaf15..33c9b0dce 100644 --- a/pallets/slpx/src/weights.rs +++ b/pallets/slpx/src/weights.rs @@ -139,18 +139,36 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(16_u64)) .saturating_add(RocksDbWeight::get().writes(8_u64)) } - /// Storage: `Slpx::WhitelistAccountId` (r:1 w:0) - /// Proof: `Slpx::WhitelistAccountId` (`max_values`: None, `max_size`: Some(338), added: 2813, mode: `MaxEncodedLen`) - /// Storage: `Slpx::OrderQueue` (r:1 w:1) - /// Proof: `Slpx::OrderQueue` (`max_values`: Some(1), `max_size`: Some(203002), added: 203497, mode: `MaxEncodedLen`) + /// Storage: Slpx WhitelistAccountId (r:1 w:0) + /// Proof: Slpx WhitelistAccountId (max_values: None, max_size: Some(338), added: 2813, mode: MaxEncodedLen) + /// Storage: Tokens Accounts (r:4 w:4) + /// Proof: Tokens Accounts (max_values: None, max_size: Some(118), added: 2593, mode: MaxEncodedLen) + /// Storage: Slpx ExecutionFee (r:1 w:0) + /// Proof: Slpx ExecutionFee (max_values: None, max_size: Some(46), added: 2521, mode: MaxEncodedLen) + /// Storage: AssetRegistry CurrencyMetadatas (r:1 w:0) + /// Proof Skipped: AssetRegistry CurrencyMetadatas (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:3 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: VtokenMinting MinimumMint (r:1 w:0) + /// Proof: VtokenMinting MinimumMint (max_values: None, max_size: Some(38), added: 2513, mode: MaxEncodedLen) + /// Storage: VtokenMinting TokenPool (r:1 w:1) + /// Proof: VtokenMinting TokenPool (max_values: None, max_size: Some(38), added: 2513, mode: MaxEncodedLen) + /// Storage: Tokens TotalIssuance (r:1 w:1) + /// Proof: Tokens TotalIssuance (max_values: None, max_size: Some(38), added: 2513, mode: MaxEncodedLen) + /// Storage: VtokenMinting Fees (r:1 w:0) + /// Proof: VtokenMinting Fees (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: AssetRegistry CurrencyIdToLocations (r:1 w:0) + /// Proof Skipped: AssetRegistry CurrencyIdToLocations (max_values: None, max_size: None, mode: Measured) + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) fn mint_with_channel_id() -> Weight { // Proof Size summary in bytes: - // Measured: `81` - // Estimated: `204487` - // Minimum execution time: 12_000_000 picoseconds. - Weight::from_parts(12_000_000, 204487) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + // Measured: `2442` + // Estimated: `11362` + // Minimum execution time: 357_850_000 picoseconds. + Weight::from_parts(367_522_000, 11362) + .saturating_add(RocksDbWeight::get().reads(16_u64)) + .saturating_add(RocksDbWeight::get().writes(8_u64)) } /// Storage: Slpx WhitelistAccountId (r:1 w:0) /// Proof: Slpx WhitelistAccountId (max_values: None, max_size: Some(338), added: 2813, mode: MaxEncodedLen) diff --git a/pallets/stable-asset/src/lib.rs b/pallets/stable-asset/src/lib.rs index e204ff915..77d6e473a 100644 --- a/pallets/stable-asset/src/lib.rs +++ b/pallets/stable-asset/src/lib.rs @@ -401,11 +401,9 @@ pub mod pallet { pub struct Pallet(_); #[pallet::storage] - #[pallet::getter(fn pool_count)] pub type PoolCount = StorageValue<_, StableAssetPoolId, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn pools)] pub type Pools = StorageMap< _, Blake2_128Concat, @@ -420,7 +418,6 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn token_rate_caches)] pub type TokenRateCaches = StorageDoubleMap< _, Twox64Concat, @@ -431,7 +428,6 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn token_rate_hardcap)] pub type TokenRateHardcap = StorageMap<_, Twox64Concat, T::AssetId, Permill>; #[pallet::event] diff --git a/pallets/stable-asset/src/tests.rs b/pallets/stable-asset/src/tests.rs index 0992f515c..20bb46cfa 100644 --- a/pallets/stable-asset/src/tests.rs +++ b/pallets/stable-asset/src/tests.rs @@ -17,8 +17,8 @@ // along with this program. If not, see . use crate::{ - mock::*, traits::StableAsset as StableAssetInterface, Error, MintResult, RedeemMultiResult, - RedeemProportionResult, RedeemSingleResult, StableAssetPoolInfo, SwapResult, + mock::*, traits::StableAsset as StableAssetInterface, Error, MintResult, PoolCount, Pools, + RedeemMultiResult, RedeemProportionResult, RedeemSingleResult, StableAssetPoolInfo, SwapResult, }; use frame_support::{assert_noop, assert_ok}; use orml_traits::MultiCurrency; @@ -60,7 +60,7 @@ fn create_pool() -> (i64, i64, i64, u64) { #[test] fn create_pool_successful() { new_test_ext().execute_with(|| { - assert_eq!(StableAsset::pool_count(), 0); + assert_eq!(PoolCount::::get(), 0); assert_ok!(StableAsset::create_pool( RuntimeOrigin::signed(1), 1, @@ -75,7 +75,7 @@ fn create_pool_successful() { 1000000000000000000u128, )); assert_eq!( - StableAsset::pools(0), + Pools::::get(0), Some(StableAssetPoolInfo { pool_id: 0, pool_asset: 1, @@ -150,7 +150,7 @@ fn modify_a_successful() { assert_ok!(StableAsset::modify_a(RuntimeOrigin::signed(1), 0, 100, 100)); assert_eq!( - StableAsset::pools(0), + Pools::::get(0), Some(StableAssetPoolInfo { pool_id: 0, pool_asset, @@ -206,7 +206,7 @@ fn mint_successful_equal_amounts() { let amounts = vec![10000000u128, 10000000u128]; assert_ok!(StableAsset::mint(RuntimeOrigin::signed(1), 0, amounts, 0)); assert_eq!( - StableAsset::pools(0), + Pools::::get(0), Some(StableAssetPoolInfo { pool_id: 0, pool_asset, @@ -246,7 +246,7 @@ fn mint_successful_different_amounts() { let amounts = vec![10000000u128, 20000000u128]; assert_ok!(StableAsset::mint(RuntimeOrigin::signed(1), 0, amounts, 0)); assert_eq!( - StableAsset::pools(0), + Pools::::get(0), Some(StableAssetPoolInfo { pool_id: 0, pool_asset, @@ -373,7 +373,7 @@ fn swap_successful() { assert_ok!(StableAsset::mint(RuntimeOrigin::signed(1), 0, amounts, 0)); assert_ok!(StableAsset::swap(RuntimeOrigin::signed(1), 0, 0, 1, 5000000u128, 0, 2)); assert_eq!( - StableAsset::pools(0), + Pools::::get(0), Some(StableAssetPoolInfo { pool_id: 0, pool_asset, @@ -547,7 +547,7 @@ fn redeem_proportion_successful() { vec![0u128, 0u128] )); assert_eq!( - StableAsset::pools(0), + Pools::::get(0), Some(StableAssetPoolInfo { pool_id: 0, pool_asset, @@ -707,7 +707,7 @@ fn redeem_single_successful() { 2, )); assert_eq!( - StableAsset::pools(0), + Pools::::get(0), Some(StableAssetPoolInfo { pool_id: 0, pool_asset, @@ -874,7 +874,7 @@ fn redeem_multi_successful() { 1100000000000000000u128, )); assert_eq!( - StableAsset::pools(0), + Pools::::get(0), Some(StableAssetPoolInfo { pool_id: 0, pool_asset, @@ -992,7 +992,7 @@ fn swap_exact_success() { assert_ok!(StableAsset::mint(RuntimeOrigin::signed(1), 0, amounts, 0)); let amount = 1000345u128; - let pool_info = StableAsset::pools(0).unwrap(); + let pool_info = Pools::::get(0).unwrap(); let result = StableAsset::get_swap_amount_exact(&pool_info, 0, 1, amount).unwrap(); let result_two = StableAsset::get_swap_amount(&pool_info, 0, 1, result.dx).unwrap(); @@ -1028,7 +1028,7 @@ fn swap_exact_success_different_precision() { assert_ok!(StableAsset::mint(RuntimeOrigin::signed(1), 0, amounts, 0)); let amount = 1000345u128; - let pool_info = StableAsset::pools(0).unwrap(); + let pool_info = Pools::::get(0).unwrap(); let result = StableAsset::get_swap_amount_exact(&pool_info, 0, 1, amount).unwrap(); let result_two = StableAsset::get_swap_amount(&pool_info, 0, 1, result.dx).unwrap(); @@ -1049,7 +1049,7 @@ fn modify_fees_successful() { Some(300) )); assert_eq!( - StableAsset::pools(0), + Pools::::get(0), Some(StableAssetPoolInfo { pool_id: 0, pool_asset, @@ -1083,7 +1083,7 @@ fn get_mint_amount_same_as_mint() { assert_ok!(StableAsset::mint(RuntimeOrigin::signed(1), 0, amounts.clone(), 0)); assert_ok!(::Assets::deposit(coin0, &swap_id, 100_000_000_000)); - let pool_info = StableAsset::pools(0).unwrap(); + let pool_info = Pools::::get(0).unwrap(); assert_eq!(pool_info.balances, vec![99999990000000000u128, 199999990000000000u128]); assert_eq!( StableAsset::get_balance_update_amount(&pool_info).unwrap().balances, @@ -1132,7 +1132,7 @@ fn get_swap_amount_same_as_swap() { assert_ok!(StableAsset::mint(RuntimeOrigin::signed(1), 0, amounts, 0)); assert_ok!(::Assets::deposit(coin0, &swap_id, 100_000_000_000)); - let pool_info = StableAsset::pools(0).unwrap(); + let pool_info = Pools::::get(0).unwrap(); assert_eq!(pool_info.balances, vec![99999990000000000u128, 199999990000000000u128]); assert_eq!( StableAsset::get_balance_update_amount(&pool_info).unwrap().balances, @@ -1181,7 +1181,7 @@ fn get_swap_amount_exact_same_as_swap() { assert_ok!(StableAsset::mint(RuntimeOrigin::signed(1), 0, amounts, 0)); assert_ok!(::Assets::deposit(coin0, &swap_id, 100_000_000_000)); - let pool_info = StableAsset::pools(0).unwrap(); + let pool_info = Pools::::get(0).unwrap(); assert_eq!(pool_info.balances, vec![99999990000000000u128, 199999990000000000u128]); assert_eq!( StableAsset::get_balance_update_amount(&pool_info).unwrap().balances, @@ -1230,7 +1230,7 @@ fn get_redeem_proportion_amount_same_as_redeem_proportion() { assert_ok!(StableAsset::mint(RuntimeOrigin::signed(1), 0, amounts, 0)); assert_ok!(::Assets::deposit(coin0, &swap_id, 100_000_000_000)); - let pool_info = StableAsset::pools(0).unwrap(); + let pool_info = Pools::::get(0).unwrap(); assert_eq!(pool_info.balances, vec![99999990000000000u128, 199999990000000000u128]); assert_eq!( StableAsset::get_balance_update_amount(&pool_info).unwrap().balances, @@ -1285,7 +1285,7 @@ fn get_redeem_single_amount_same_as_redeem_single() { assert_ok!(StableAsset::mint(RuntimeOrigin::signed(1), 0, amounts, 0)); assert_ok!(::Assets::deposit(coin0, &swap_id, 100_000_000_000)); - let pool_info = StableAsset::pools(0).unwrap(); + let pool_info = Pools::::get(0).unwrap(); assert_eq!(pool_info.balances, vec![99999990000000000u128, 199999990000000000u128]); assert_eq!( StableAsset::get_balance_update_amount(&pool_info).unwrap().balances, @@ -1342,7 +1342,7 @@ fn get_redeem_multi_amount_same_as_redeem_multi() { assert_ok!(StableAsset::mint(RuntimeOrigin::signed(1), 0, amounts, 0)); assert_ok!(::Assets::deposit(coin0, &swap_id, 100_000_000_000)); - let pool_info = StableAsset::pools(0).unwrap(); + let pool_info = Pools::::get(0).unwrap(); assert_eq!(pool_info.balances, vec![99999990000000000u128, 199999990000000000u128]); assert_eq!( StableAsset::get_balance_update_amount(&pool_info).unwrap().balances, diff --git a/pallets/stable-pool/src/mock.rs b/pallets/stable-pool/src/mock.rs index 0eb1ce4ad..d63321de7 100644 --- a/pallets/stable-pool/src/mock.rs +++ b/pallets/stable-pool/src/mock.rs @@ -17,6 +17,7 @@ // along with this program. If not, see . use crate as bifrost_stable_pool; use bifrost_asset_registry::AssetIdMaps; +use bifrost_primitives::MoonbeamChainId; pub use bifrost_primitives::{ currency::{MOVR, VMOVR}, Balance, CurrencyId, CurrencyIdMapping, SlpOperator, SlpxOperator, TokenSymbol, ASTR, BNC, DOT, @@ -292,16 +293,12 @@ impl bifrost_vtoken_minting::Config for Test { type WeightInfo = (); type OnRedeemSuccess = (); type XcmTransfer = XTokens; - type AstarParachainId = ConstU32<2007>; - type MoonbeamParachainId = ConstU32<2023>; + type MoonbeamChainId = MoonbeamChainId; type BifrostSlpx = SlpxInterface; - type HydradxParachainId = ConstU32<2034>; - type MantaParachainId = ConstU32<2104>; - type InterlayParachainId = ConstU32<2032>; type ChannelCommission = (); type MaxLockRecords = ConstU32<100>; type IncentivePoolAccount = IncentivePoolAccount; - type VeMinting = (); + type BbBNC = (); type AssetIdMaps = AssetIdMaps; } diff --git a/pallets/stable-pool/src/tests.rs b/pallets/stable-pool/src/tests.rs index d8ce369ba..807f32fde 100644 --- a/pallets/stable-pool/src/tests.rs +++ b/pallets/stable-pool/src/tests.rs @@ -17,7 +17,7 @@ // along with this program. If not, see . use crate::{mock::*, AssetIdOf, AtLeast64BitUnsignedOf, Error}; use bifrost_primitives::VtokenMintingOperator; -use bifrost_stable_asset::StableAssetPoolInfo; +use bifrost_stable_asset::{PoolCount, Pools, StableAssetPoolInfo}; use frame_support::{assert_noop, assert_ok, BoundedVec}; use orml_traits::MultiCurrency; use sp_runtime::{traits::AccountIdConversion, Permill}; @@ -127,7 +127,7 @@ fn create_pool_successful() { ExtBuilder::default().new_test_ext().build().execute_with(|| { let coin0 = DOT; let coin1 = VDOT; - assert_eq!(StableAsset::pool_count(), 0); + assert_eq!(PoolCount::::get(), 0); assert_ok!(StablePool::create_pool( RuntimeOrigin::root(), vec![coin0, coin1], @@ -141,7 +141,7 @@ fn create_pool_successful() { 1000000000000000000u128, )); assert_eq!( - StableAsset::pools(0), + Pools::::get(0), Some(StableAssetPoolInfo { pool_id: 0, pool_asset: CurrencyId::BLP(0), @@ -196,7 +196,7 @@ fn mint_successful_equal_amounts() { assert_ok!(StablePool::mint_inner(&3, 0, amounts, 0)); // assert_ok!(StableAsset::mint(RuntimeOrigin::signed(3), 0, amounts.clone(), 0)); assert_eq!( - StableAsset::pools(0), + Pools::::get(0), Some(StableAssetPoolInfo { pool_id: 0, pool_asset, @@ -246,7 +246,7 @@ fn swap_successful() { assert_ok!(StableAsset::mint(RuntimeOrigin::signed(3), 0, amounts, 0)); assert_ok!(StableAsset::swap(RuntimeOrigin::signed(3), 0, 0, 1, 5000000u128, 0, 2)); assert_eq!( - StableAsset::pools(0), + Pools::::get(0), Some(StableAssetPoolInfo { pool_id: 0, pool_asset, @@ -339,7 +339,7 @@ fn get_swap_output_amount() { orml_tokens::Error::::BalanceTooLow ); assert_eq!( - StableAsset::pools(0), + Pools::::get(0), Some(StableAssetPoolInfo { pool_id: 0, pool_asset, diff --git a/pallets/system-maker/src/lib.rs b/pallets/system-maker/src/lib.rs index d569657b6..31760408e 100644 --- a/pallets/system-maker/src/lib.rs +++ b/pallets/system-maker/src/lib.rs @@ -114,7 +114,6 @@ pub mod pallet { } #[pallet::storage] - #[pallet::getter(fn infos)] pub type Infos = StorageMap<_, Twox64Concat, CurrencyIdOf, Info>>; #[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo)] diff --git a/pallets/system-maker/src/mock.rs b/pallets/system-maker/src/mock.rs index 48323d9f3..756815e07 100644 --- a/pallets/system-maker/src/mock.rs +++ b/pallets/system-maker/src/mock.rs @@ -22,6 +22,7 @@ #![allow(non_upper_case_globals)] use bifrost_asset_registry::AssetIdMaps; +use bifrost_primitives::MoonbeamChainId; pub use bifrost_primitives::{currency::*, CurrencyId, SlpxOperator, TokenSymbol}; use bifrost_slp::{QueryId, QueryResponseManager}; pub use cumulus_primitives_core::ParaId; @@ -305,15 +306,11 @@ impl bifrost_vtoken_minting::Config for Runtime { type WeightInfo = (); type OnRedeemSuccess = (); type XcmTransfer = XTokens; - type AstarParachainId = ConstU32<2007>; - type MoonbeamParachainId = ConstU32<2023>; - type HydradxParachainId = ConstU32<2034>; - type MantaParachainId = ConstU32<2104>; - type InterlayParachainId = ConstU32<2032>; + type MoonbeamChainId = MoonbeamChainId; type ChannelCommission = (); type MaxLockRecords = ConstU32<100>; type IncentivePoolAccount = IncentivePoolAccount; - type VeMinting = (); + type BbBNC = (); type AssetIdMaps = AssetIdMaps; } diff --git a/pallets/system-staking/src/lib.rs b/pallets/system-staking/src/lib.rs index c85503d78..a496f8e4e 100644 --- a/pallets/system-staking/src/lib.rs +++ b/pallets/system-staking/src/lib.rs @@ -109,18 +109,15 @@ pub mod pallet { /// Current Round Information #[pallet::storage] - #[pallet::getter(fn round)] pub(crate) type Round = StorageValue<_, RoundInfo>, OptionQuery>; /// The tokenInfo for each currency #[pallet::storage] - #[pallet::getter(fn token_status)] pub(crate) type TokenStatus = StorageMap<_, Twox64Concat, CurrencyIdOf, TokenInfo>, OptionQuery>; /// All token sets #[pallet::storage] - #[pallet::getter(fn token_list)] pub(crate) type TokenList = StorageValue<_, BoundedVec, T::MaxTokenLen>, ValueQuery>; @@ -233,7 +230,7 @@ pub mod pallet { impl Hooks> for Pallet { fn on_initialize(n: BlockNumberFor) -> Weight { // Get token list - let token_list = Self::token_list(); + let token_list = TokenList::::get(); //Get round info, if can't find it in the storage, a new one will be created. let mut round = if let Some(round) = >::get() { @@ -255,7 +252,7 @@ pub mod pallet { // Iterate through the token list for i in token_list.clone().into_iter() { // Query the token info for each token in the token list - if let Some(mut token_info) = Self::token_status(i) { + if let Some(mut token_info) = TokenStatus::::get(i) { // Check token_info.current_config != token_info.new_config if token_info.check_config_change() { // Update token_info.current_config , set token_info.current_config = @@ -278,7 +275,7 @@ pub mod pallet { // Iterate through the token list for i in token_list.into_iter() { // Query the token info for each token in the token list - if let Some(token_info) = Self::token_status(i) { + if let Some(token_info) = TokenStatus::::get(i) { // Current blockNumber - BlockNumber of Round Start == // token_info.current_config.exec_delay ===> true if round.check_delay(n, token_info.current_config.exec_delay) { @@ -370,7 +367,7 @@ pub mod pallet { // If it is a new token, add it to the token list if new_token { - let mut token_list = Self::token_list(); + let mut token_list = TokenList::::get(); token_list.try_push(token).map_err(|_| Error::::ExceedMaxTokenLen)?; >::put(token_list); } @@ -401,7 +398,7 @@ pub mod pallet { >::remove(&token); // Remove token from token list - let mut token_list = Self::token_list(); + let mut token_list = TokenList::::get(); token_list.retain(|&x| x != token); >::put(token_list); diff --git a/pallets/system-staking/src/mock.rs b/pallets/system-staking/src/mock.rs index 32c2cfd58..a450972d1 100644 --- a/pallets/system-staking/src/mock.rs +++ b/pallets/system-staking/src/mock.rs @@ -19,6 +19,7 @@ #![allow(non_upper_case_globals)] use bifrost_asset_registry::AssetIdMaps; +use bifrost_primitives::MoonbeamChainId; pub use bifrost_primitives::{currency::*, CurrencyId, SlpxOperator, TokenSymbol}; use bifrost_slp::{QueryId, QueryResponseManager}; pub use cumulus_primitives_core::ParaId; @@ -197,15 +198,11 @@ impl bifrost_vtoken_minting::Config for Runtime { type WeightInfo = (); type OnRedeemSuccess = (); type XcmTransfer = XTokens; - type AstarParachainId = ConstU32<2007>; - type MoonbeamParachainId = ConstU32<2023>; - type HydradxParachainId = ConstU32<2034>; - type MantaParachainId = ConstU32<2104>; - type InterlayParachainId = ConstU32<2032>; + type MoonbeamChainId = MoonbeamChainId; type ChannelCommission = (); type MaxLockRecords = ConstU32<100>; type IncentivePoolAccount = IncentivePoolAccount; - type VeMinting = (); + type BbBNC = (); type AssetIdMaps = AssetIdMaps; } @@ -301,7 +298,7 @@ impl bifrost_farming::Config for Runtime { type RewardIssuer = FarmingRewardIssuerPalletId; type FarmingBoost = FarmingBoostPalletId; type WeightInfo = (); - type VeMinting = (); + type BbBNC = (); type BlockNumberToBalance = ConvertInto; type WhitelistMaximumLimit = WhitelistMaximumLimit; type GaugeRewardIssuer = FarmingGaugeRewardIssuerPalletId; diff --git a/pallets/system-staking/src/tests.rs b/pallets/system-staking/src/tests.rs index 0af03cfce..d97ec5aae 100644 --- a/pallets/system-staking/src/tests.rs +++ b/pallets/system-staking/src/tests.rs @@ -111,9 +111,9 @@ fn round_info_should_correct() { None, )); roll_one_block(); - assert_eq!(SystemStaking::round().unwrap().length, 5); - assert_eq!(SystemStaking::round().unwrap().current, 1); - assert_eq!(SystemStaking::round().unwrap().first, 1001); + assert_eq!(Round::::get().unwrap().length, 5); + assert_eq!(Round::::get().unwrap().current, 1); + assert_eq!(Round::::get().unwrap().first, 1001); }); } diff --git a/pallets/token-issuer/src/benchmarking.rs b/pallets/token-issuer/src/benchmarking.rs index e910c8ea6..0dc47d130 100644 --- a/pallets/token-issuer/src/benchmarking.rs +++ b/pallets/token-issuer/src/benchmarking.rs @@ -67,14 +67,14 @@ benchmarks! { let origin = T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; let caller: T::AccountId = whitelisted_caller(); let currency_id = CurrencyId::Token(TokenSymbol::KSM); - let add_call = Call::::add_to_issue_whitelist { currency_id: currency_id.clone(), account: caller.clone() }; + let add_call = Call::::add_to_issue_whitelist { currency_id: currency_id, account: caller.clone() }; add_call.dispatch_bypass_filter(origin.clone())?; - let original_balance = T::MultiCurrency::free_balance(currency_id.clone(), &caller); + let original_balance = T::MultiCurrency::free_balance(currency_id, &caller); let token_amount = BalanceOf::::unique_saturated_from(1000u32 as u128); - }: _(RawOrigin::Signed(caller.clone()), caller.clone(), currency_id.clone(), token_amount) + }: _(RawOrigin::Signed(caller.clone()), caller.clone(), currency_id, token_amount) verify { - assert_eq!(T::MultiCurrency::free_balance(currency_id.clone(), &caller), token_amount + original_balance); + assert_eq!(T::MultiCurrency::free_balance(currency_id, &caller), token_amount + original_balance); } transfer { @@ -83,18 +83,18 @@ benchmarks! { let currency_id = CurrencyId::Token(TokenSymbol::KSM); // add caller to the transfer whitelist - let add_transfer_call = Call::::add_to_transfer_whitelist { currency_id: currency_id.clone(), account: caller.clone() }; + let add_transfer_call = Call::::add_to_transfer_whitelist { currency_id: currency_id, account: caller.clone() }; add_transfer_call.dispatch_bypass_filter(origin.clone())?; // transfer some ksm from caller account to receiver account let receiver: T::AccountId = account("bechmarking_account_1", 0, 0); let transfer_token_amount = BalanceOf::::unique_saturated_from(800u32 as u128); - let caller_original_balance = T::MultiCurrency::free_balance(currency_id.clone(), &caller); - let receiver_original_balance = T::MultiCurrency::free_balance(currency_id.clone(), &receiver); - }: _(RawOrigin::Signed(caller.clone()), receiver.clone(), currency_id.clone(), transfer_token_amount) + let caller_original_balance = T::MultiCurrency::free_balance(currency_id, &caller); + let receiver_original_balance = T::MultiCurrency::free_balance(currency_id, &receiver); + }: _(RawOrigin::Signed(caller.clone()), receiver.clone(), currency_id, transfer_token_amount) verify { - assert_eq!(T::MultiCurrency::free_balance(currency_id.clone(), &caller), caller_original_balance - transfer_token_amount); - assert_eq!(T::MultiCurrency::free_balance(currency_id.clone(), &receiver), transfer_token_amount+ receiver_original_balance); + assert_eq!(T::MultiCurrency::free_balance(currency_id, &caller), caller_original_balance - transfer_token_amount); + assert_eq!(T::MultiCurrency::free_balance(currency_id, &receiver), transfer_token_amount+ receiver_original_balance); } } diff --git a/pallets/token-issuer/src/lib.rs b/pallets/token-issuer/src/lib.rs index 3ec8c0a2c..1dcff3747 100644 --- a/pallets/token-issuer/src/lib.rs +++ b/pallets/token-issuer/src/lib.rs @@ -100,13 +100,11 @@ pub mod pallet { /// Accounts in the whitelist can issue the corresponding Currency. #[pallet::storage] - #[pallet::getter(fn get_issue_whitelist)] pub type IssueWhiteList = StorageMap<_, Blake2_128Concat, CurrencyId, BoundedVec, T::MaxLengthLimit>>; /// Accounts in the whitelist can transfer the corresponding Currency. #[pallet::storage] - #[pallet::getter(fn get_transfer_whitelist)] pub type TransferWhiteList = StorageMap<_, Blake2_128Concat, CurrencyId, BoundedVec, T::MaxLengthLimit>>; @@ -131,7 +129,7 @@ pub mod pallet { let issue_whitelist_new: BoundedVec, T::MaxLengthLimit>; let mut issue_vec: Vec>; - match Self::get_issue_whitelist(currency_id) { + match IssueWhiteList::::get(currency_id) { None => { issue_vec = vec![account.clone()]; }, @@ -189,7 +187,7 @@ pub mod pallet { let transfer_whitelist_new: BoundedVec, T::MaxLengthLimit>; let mut transfer_vec: Vec>; - match Self::get_transfer_whitelist(currency_id) { + match TransferWhiteList::::get(currency_id) { None => { transfer_vec = vec![account.clone()]; }, @@ -253,7 +251,7 @@ pub mod pallet { let issuer = ensure_signed(origin)?; let issue_whitelist = - Self::get_issue_whitelist(currency_id).ok_or(Error::::NotAllowed)?; + IssueWhiteList::::get(currency_id).ok_or(Error::::NotAllowed)?; ensure!(issue_whitelist.contains(&issuer), Error::::NotAllowed); T::MultiCurrency::deposit(currency_id, &dest, amount)?; @@ -277,7 +275,7 @@ pub mod pallet { let transferrer = ensure_signed(origin)?; let transfer_whitelist = - Self::get_transfer_whitelist(currency_id).ok_or(Error::::NotAllowed)?; + TransferWhiteList::::get(currency_id).ok_or(Error::::NotAllowed)?; ensure!(transfer_whitelist.contains(&transferrer), Error::::NotAllowed); let balance = T::MultiCurrency::free_balance(currency_id, &transferrer); diff --git a/pallets/token-issuer/src/tests.rs b/pallets/token-issuer/src/tests.rs index f646577b0..aae47d9d6 100644 --- a/pallets/token-issuer/src/tests.rs +++ b/pallets/token-issuer/src/tests.rs @@ -50,7 +50,7 @@ fn add_to_issue_whitelist_should_work() { )); let bounded_list = BoundedVec::try_from(vec![CHARLIE]).unwrap(); - assert_eq!(TokenIssuer::get_issue_whitelist(ZLK), Some(bounded_list)); + assert_eq!(IssueWhiteList::::get(ZLK), Some(bounded_list)); // Charlie succuessfully issue 800 unit of ZLK to Alice account assert_ok!(TokenIssuer::issue(RuntimeOrigin::signed(CHARLIE), ALICE, ZLK, 800)); assert_eq!(Tokens::free_balance(ZLK, &ALICE), 800); @@ -112,7 +112,7 @@ fn add_to_transfer_whitelist_should_work() { )); let bounded_list = BoundedVec::try_from(vec![CHARLIE]).unwrap(); - assert_eq!(TokenIssuer::get_transfer_whitelist(ZLK), Some(bounded_list)); + assert_eq!(TransferWhiteList::::get(ZLK), Some(bounded_list)); // Charlie succuessfully transfer 800 unit of ZLK to Alice account assert_ok!(TokenIssuer::transfer(RuntimeOrigin::signed(CHARLIE), ALICE, ZLK, 800)); assert_eq!(Tokens::free_balance(ZLK, &ALICE), 800); diff --git a/pallets/traits/src/evm.rs b/pallets/traits/src/evm.rs index 8dc1ea184..5360ab31e 100644 --- a/pallets/traits/src/evm.rs +++ b/pallets/traits/src/evm.rs @@ -1,18 +1,15 @@ pub trait InspectEvmAccounts { - /// Returns `True` if the account is EVM truncated account. - fn is_evm_account(account_id: AccountId) -> bool; - /// get the EVM address from the substrate address. fn evm_address(account_id: &impl AsRef<[u8; 32]>) -> EvmAddress; - /// Get the truncated address from the EVM address. - fn truncated_account_id(evm_address: EvmAddress) -> AccountId; + /// Get the AccountId from the EVM address. + fn convert_account_id(evm_address: EvmAddress) -> AccountId; /// Return the Substrate address bound to the EVM account. If not bound, returns `None`. fn bound_account_id(evm_address: EvmAddress) -> Option; /// Get the Substrate address from the EVM address. - /// Returns the truncated version of the address if the address wasn't bind. + /// Returns the converted address if the address wasn't bind. fn account_id(evm_address: EvmAddress) -> AccountId; /// Returns `True` if the address is allowed to deploy smart contracts. diff --git a/pallets/vbnc-convert/Cargo.toml b/pallets/vbnc-convert/Cargo.toml new file mode 100644 index 000000000..f0f014984 --- /dev/null +++ b/pallets/vbnc-convert/Cargo.toml @@ -0,0 +1,54 @@ +[package] +name = "bifrost-vbnc-convert" +version = "0.8.0" +authors = ["Liebi Technologies "] +edition = "2021" + +[dependencies] +parity-scale-codec = { workspace = true, features = ["derive"] } +scale-info = { workspace = true, features = ["derive"] } +sp-std = { workspace = true } +frame-support = { workspace = true } +frame-system = { workspace = true } +sp-runtime = { workspace = true } +frame-benchmarking = { workspace = true, optional = true } +bifrost-primitives = { workspace = true } +orml-traits = { workspace = true } +sp-core = { workspace = true } +pallet-balances = { workspace = true } +xcm-builder = { workspace = true } + +[dev-dependencies] +orml-tokens = { workspace = true } +bifrost-currencies = { workspace = true } +sp-io = { workspace = true } +bifrost-asset-registry = { workspace = true } + +[features] +default = ["std"] +std = [ + "parity-scale-codec/std", + "scale-info/std", + "sp-std/std", + "sp-runtime/std", + "sp-core/std", + "bifrost-primitives/std", + "frame-support/std", + "frame-system/std", + "frame-benchmarking/std", + "orml-traits/std", + "orml-tokens/std", + "bifrost-currencies/std", + "sp-io/std", + "bifrost-asset-registry/std", + "pallet-balances/std", +] + +runtime-benchmarks = [ + "frame-benchmarking", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", +] +try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/vbnc-convert/src/benchmarking.rs b/pallets/vbnc-convert/src/benchmarking.rs new file mode 100644 index 000000000..b3ff9e321 --- /dev/null +++ b/pallets/vbnc-convert/src/benchmarking.rs @@ -0,0 +1,68 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use crate::*; +use frame_benchmarking::v2::*; +use frame_system::RawOrigin; +use sp_runtime::traits::{UniqueSaturatedFrom, Zero}; + +#[benchmarks(where T: Config)] +mod benchmarks { + use super::*; + + #[benchmark] + fn convert_to_vbnc_p() -> Result<(), BenchmarkError> { + let caller: T::AccountId = whitelisted_caller(); + let currency = VBNC; + let value = BalanceOf::::unique_saturated_from(100_000_000_000_000_000_000u128); + let vbnc_pool_account = Pallet::::vbnc_p_pool_account(); + + // Ensure the pool has enough balance + T::MultiCurrency::deposit(VBNC_P, &vbnc_pool_account, value)?; + + // Make sure the user has enough balance in the provided currency + T::MultiCurrency::deposit(currency, &caller, value)?; + + #[extrinsic_call] + Pallet::::convert_to_vbnc_p(RawOrigin::Signed(caller.clone()), currency, value); + + assert!(T::MultiCurrency::free_balance(VBNC_P, &caller) > Zero::zero()); + + Ok(()) + } + + #[benchmark] + fn charge_vbnc_p() -> Result<(), BenchmarkError> { + let caller: T::AccountId = whitelisted_caller(); + let amount = BalanceOf::::unique_saturated_from(100_000_000_000_000_000_000u128); + let vbnc_pool_account = Pallet::::vbnc_p_pool_account(); + + // Ensure the caller has enough vBNC-P balance + T::MultiCurrency::deposit(VBNC_P, &caller, amount)?; + + #[extrinsic_call] + Pallet::::charge_vbnc_p(RawOrigin::Signed(caller.clone()), amount); + + assert_eq!(T::MultiCurrency::free_balance(VBNC_P, &caller), Zero::zero()); + assert_eq!(T::MultiCurrency::free_balance(VBNC_P, &vbnc_pool_account), amount); + + Ok(()) + } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext_benchmark(), crate::mock::Runtime); +} diff --git a/pallets/vbnc-convert/src/lib.rs b/pallets/vbnc-convert/src/lib.rs new file mode 100644 index 000000000..39573b4b3 --- /dev/null +++ b/pallets/vbnc-convert/src/lib.rs @@ -0,0 +1,211 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// Ensure we're `no_std` when compiling for Wasm. +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; + +use frame_support::{ensure, pallet_prelude::*, sp_runtime::traits::AccountIdConversion, PalletId}; +use frame_system::pallet_prelude::*; +use orml_traits::MultiCurrency; + +use bifrost_primitives::{ + currency::{VBNC, VBNC_P}, + CurrencyId, +}; +pub use pallet::*; +pub use weights::WeightInfo; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; +mod mock; +mod tests; +pub mod weights; + +type BalanceOf = <::MultiCurrency as MultiCurrency< + ::AccountId, +>>::Balance; +type AccountIdOf = ::AccountId; +pub(crate) type CurrencyIdOf = <::MultiCurrency as MultiCurrency< + ::AccountId, +>>::CurrencyId; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + /// Currecny operation handler + type MultiCurrency: MultiCurrency, CurrencyId = CurrencyId>; + /// VBNC-convert Pallet Id + type VBNCConvertPalletId: Get; + /// Weight information for extrinsics in this module. + type WeightInfo: WeightInfo; + } + #[pallet::error] + /// Error types for the VBNC convert pallet. + pub enum Error { + /// The account does not have enough balance to complete the operation. + NotEnoughBalance, + /// The resulting balance is less than the existential deposit, which would lead to the + /// account being reaped. + LessThanExistentialDeposit, + /// The specified currency is not supported for conversion to VBNC-P. + CurrencyNotSupport, + } + + #[pallet::event] + /// Event types emitted by the VBNC convert pallet. + #[pallet::generate_deposit(pub(crate) fn deposit_event)] + pub enum Event { + /// Emitted when VBNC-P has been successfully converted and transferred to the user. + VBNCPConverted { + /// The account that received the converted VBNC-P. + to: AccountIdOf, + /// The amount of VBNC-P converted. + value: BalanceOf, + }, + /// Emitted when VBNC-P has been successfully charged from a user account. + VbncPCharged { + /// The account from which VBNC-P was charged. + who: AccountIdOf, + /// The amount of VBNC-P charged. + value: BalanceOf, + }, + } + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + /// Converts the specified `value` of a supported currency to VBNC-P. + /// + /// # Parameters + /// - `origin`: The origin of the transaction, which must be a signed account. + /// - `currency`: The currency to be converted into VBNC-P. + /// - `value`: The amount of the specified currency to be converted. + /// + /// # Errors + /// - `Error::::CurrencyNotSupport`: If the provided currency is not supported for + /// conversion. + /// - `Error::::NotEnoughBalance`: If the user does not have sufficient balance of the + /// specified currency. + /// - `Error::::LessThanExistentialDeposit`: If the converted amount of VBNC-P is less + /// than the minimum required balance. + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::convert_to_vbnc_p())] + pub fn convert_to_vbnc_p( + origin: OriginFor, + currency: CurrencyIdOf, + value: BalanceOf, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::ensure_currency(¤cy)?; + + // check the user balance of currency + T::MultiCurrency::ensure_can_withdraw(currency, &who, value) + .map_err(|_| Error::::NotEnoughBalance)?; + + // the VBNC and VBNC-P exchange ratio is one to one + let vbnc_p_amount = value; + Self::ensure_pool_balance_enough(VBNC_P, vbnc_p_amount)?; + + let existential_deposit = T::MultiCurrency::minimum_balance(VBNC_P); + ensure!(vbnc_p_amount >= existential_deposit, Error::::LessThanExistentialDeposit); + + // transfer vBNC-p from pool to user + let vbnc_pool_account = Self::vbnc_p_pool_account(); + T::MultiCurrency::transfer(VBNC_P, &vbnc_pool_account, &who, vbnc_p_amount)?; + + // burn currency + T::MultiCurrency::withdraw(currency, &who, value)?; + + // deposit event + Self::deposit_event(Event::VBNCPConverted { to: who, value: vbnc_p_amount }); + + Ok(()) + } + + /// Charges the specified `amount` of VBNC-P from the user's account. + /// + /// # Parameters + /// - `origin`: The origin of the transaction, which must be a signed account. + /// - `amount`: The amount of VBNC-P to charge from the user's account. + /// + /// # Errors + /// - `Error::::NotEnoughBalance`: If the user does not have sufficient VBNC-P to charge. + /// - `Error::::LessThanExistentialDeposit`: If the amount to be charged is less than the + /// existential deposit. + #[pallet::call_index(1)] + #[pallet::weight(T::WeightInfo::charge_vbnc_p())] + pub fn charge_vbnc_p(origin: OriginFor, amount: BalanceOf) -> DispatchResult { + let who = ensure_signed(origin)?; + + // check the user balance of currency + T::MultiCurrency::ensure_can_withdraw(VBNC_P, &who, amount) + .map_err(|_| Error::::NotEnoughBalance)?; + + let vbnc_pool_account = Self::vbnc_p_pool_account(); + T::MultiCurrency::transfer(VBNC_P, &who, &vbnc_pool_account, amount)?; + + // deposit event + Self::deposit_event(Event::VbncPCharged { who, value: amount }); + + Ok(()) + } + } + + impl Pallet { + /// Returns the account ID of VBNCConvertPalletId. + /// This account is used to hold VBNC-P and perform conversions. + pub fn vbnc_p_pool_account() -> AccountIdOf { + T::VBNCConvertPalletId::get().into_account_truncating() + } + + /// Ensures that the provided currency is supported for conversion. + /// Currently, only VBNC is supported. + fn ensure_currency(currency: &CurrencyIdOf) -> Result<(), DispatchError> { + // Ensure that the currency is VBNC, otherwise return an error. + ensure!(*currency == VBNC, Error::::CurrencyNotSupport); + Ok(()) + } + + /// Ensures that the VBNC-P pool has enough balance to complete the transaction. + /// If the pool has insufficient balance, an error is returned. + fn ensure_pool_balance_enough( + currency: CurrencyIdOf, + value: BalanceOf, + ) -> Result<(), DispatchError> { + let pool_account = Self::vbnc_p_pool_account(); + + // Check if the pool account can withdraw the specified amount of currency. + T::MultiCurrency::ensure_can_withdraw(currency, &pool_account, value) + .map_err(|_| Error::::NotEnoughBalance)?; + + Ok(()) + } + } +} diff --git a/pallets/vbnc-convert/src/mock.rs b/pallets/vbnc-convert/src/mock.rs new file mode 100644 index 000000000..ce3b49e9f --- /dev/null +++ b/pallets/vbnc-convert/src/mock.rs @@ -0,0 +1,196 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// Ensure we're `no_std` when compiling for Wasm. + +#![cfg(test)] +#![allow(non_upper_case_globals)] + +use bifrost_asset_registry::AssetIdMaps; +use bifrost_primitives::{ + currency::{BNC, KSM, VBNC, VBNC_P, VKSM}, + CurrencyId, CurrencyIdMapping, TokenSymbol, +}; +use frame_support::{ord_parameter_types, parameter_types, traits::Nothing, PalletId}; +use frame_system::EnsureSignedBy; +use sp_core::H256; +use sp_runtime::{ + traits::{BlakeTwo256, ConstU32, IdentityLookup}, + AccountId32, BuildStorage, +}; + +use crate as bifrost_vbnc_convert; + +pub type BlockNumber = u64; +pub type Amount = i128; +pub type Balance = u128; + +pub type AccountId = AccountId32; + +pub const ALICE: AccountId = AccountId32::new([0u8; 32]); +pub const BOB: AccountId = AccountId32::new([1u8; 32]); + +frame_support::construct_runtime!( + pub enum Runtime { + System: frame_system, + Tokens: orml_tokens, + Balances: pallet_balances, + Currencies: bifrost_currencies, + AssetRegistry: bifrost_asset_registry, + VBNCConvert: bifrost_vbnc_convert, + } +); + +type Block = frame_system::mocking::MockBlock; + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} +impl frame_system::Config for Runtime { + type AccountData = pallet_balances::AccountData; + type AccountId = AccountId; + type BaseCallFilter = frame_support::traits::Everything; + type BlockHashCount = BlockHashCount; + type BlockLength = (); + type BlockWeights = (); + type RuntimeCall = RuntimeCall; + type DbWeight = (); + type RuntimeEvent = RuntimeEvent; + type Hash = H256; + type Hashing = BlakeTwo256; + type Nonce = u32; + type Block = Block; + type Lookup = IdentityLookup; + type OnKilledAccount = (); + type OnNewAccount = (); + type OnSetCode = (); + type RuntimeOrigin = RuntimeOrigin; + type PalletInfo = PalletInfo; + type SS58Prefix = (); + type SystemWeightInfo = (); + type Version = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; + type RuntimeTask = (); + type SingleBlockMigrations = (); + type MultiBlockMigrator = (); + type PreInherents = (); + type PostInherents = (); + type PostTransactions = (); +} + +parameter_types! { + pub const NativeCurrencyId: CurrencyId = CurrencyId::Native(TokenSymbol::BNC); +} + +pub type AdaptedBasicCurrency = + bifrost_currencies::BasicCurrencyAdapter; + +impl bifrost_currencies::Config for Runtime { + type GetNativeCurrencyId = NativeCurrencyId; + type MultiCurrency = Tokens; + type NativeCurrency = AdaptedBasicCurrency; + type WeightInfo = (); +} + +parameter_types! { + pub const ExistentialDeposit: Balance = 5; +} + +impl pallet_balances::Config for Runtime { + type AccountStore = frame_system::Pallet; + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); + type RuntimeHoldReason = RuntimeHoldReason; + type RuntimeFreezeReason = RuntimeFreezeReason; + type FreezeIdentifier = (); + type MaxFreezes = ConstU32<0>; +} + +orml_traits::parameter_type_with_key! { + pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance { + match currency_id { + &BNC => 5, + &VBNC_P => 5, + &KSM => 5, + &VKSM => 5, + &VBNC => 5, + _ => AssetIdMaps::::get_currency_metadata(*currency_id) + .map_or(Balance::max_value(), |metatata| metatata.minimal_balance) + } + }; +} +impl orml_tokens::Config for Runtime { + type Amount = i128; + type Balance = Balance; + type CurrencyId = CurrencyId; + type DustRemovalWhitelist = Nothing; + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposits = ExistentialDeposits; + type MaxLocks = ConstU32<50>; + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); + type CurrencyHooks = (); +} + +ord_parameter_types! { + pub const One: AccountId = ALICE; +} + +impl bifrost_asset_registry::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type RegisterOrigin = EnsureSignedBy; + type WeightInfo = (); +} + +parameter_types! { + pub const VBNCConvertPalletId: PalletId = PalletId(*b"bf/vbncc"); +} + +impl bifrost_vbnc_convert::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type MultiCurrency = Currencies; + type VBNCConvertPalletId = VBNCConvertPalletId; + type WeightInfo = (); +} + +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![(BOB, 10)] } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +#[cfg(feature = "runtime-benchmarks")] +pub fn new_test_ext_benchmark() -> sp_io::TestExternalities { + frame_system::GenesisConfig::::default() + .build_storage() + .unwrap() + .into() +} diff --git a/pallets/vbnc-convert/src/tests.rs b/pallets/vbnc-convert/src/tests.rs new file mode 100644 index 000000000..91193e00e --- /dev/null +++ b/pallets/vbnc-convert/src/tests.rs @@ -0,0 +1,136 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// Ensure we're `no_std` when compiling for Wasm. + +#![cfg(test)] + +use crate::{mock::*, *}; +use bifrost_primitives::{ + currency::{VBNC, VBNC_P}, + BNC, +}; +use frame_support::{assert_noop, assert_ok}; + +#[test] +fn convert_to_vbnc_p_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Tokens::deposit(VBNC, &BOB, 5000)); + assert_ok!(Tokens::deposit(VBNC_P, &VBNCConvert::vbnc_p_pool_account(), 5000)); + + assert_ok!(VBNCConvert::convert_to_vbnc_p(RuntimeOrigin::signed(BOB), VBNC, 1000)); + System::assert_last_event(RuntimeEvent::VBNCConvert(Event::VBNCPConverted { + to: BOB, + value: 1000, + })); + + assert_eq!(::MultiCurrency::free_balance(VBNC, &BOB,), 4000); + assert_eq!(::MultiCurrency::free_balance(VBNC_P, &BOB,), 1000); + assert_eq!( + ::MultiCurrency::free_balance( + VBNC_P, + &VBNCConvert::vbnc_p_pool_account() + ), + 4000 + ); + }); +} + +#[test] +fn convert_to_vbnc_p_should_fail_with_wrong_currency() { + new_test_ext().execute_with(|| { + assert_ok!(Tokens::deposit(BNC, &BOB, 5000)); + assert_ok!(Tokens::deposit(VBNC_P, &BOB, 5000)); + + assert_noop!( + VBNCConvert::convert_to_vbnc_p(RuntimeOrigin::signed(BOB), BNC, 1000), + Error::::CurrencyNotSupport + ); + assert_noop!( + VBNCConvert::convert_to_vbnc_p(RuntimeOrigin::signed(BOB), VBNC_P, 1000), + Error::::CurrencyNotSupport + ); + }); +} + +#[test] +fn convert_to_vbnc_p_should_fail_with_account_balance_poor() { + new_test_ext().execute_with(|| { + assert_noop!( + VBNCConvert::convert_to_vbnc_p(RuntimeOrigin::signed(BOB), VBNC, 100), + Error::::NotEnoughBalance + ); + }); +} + +#[test] +fn convert_to_vbnc_p_should_fail_with_pool_balance_poor() { + new_test_ext().execute_with(|| { + assert_ok!(Tokens::deposit(VBNC, &BOB, 500)); + + assert_noop!( + VBNCConvert::convert_to_vbnc_p(RuntimeOrigin::signed(BOB), VBNC, 100), + Error::::NotEnoughBalance + ); + }); +} + +#[test] +fn convert_to_vbnc_p_should_fail_with_less_than_existential_depositr() { + new_test_ext().execute_with(|| { + assert_ok!(Tokens::deposit(VBNC, &BOB, 500)); + assert_ok!(Tokens::deposit(VBNC_P, &VBNCConvert::vbnc_p_pool_account(), 500)); + + assert_noop!( + VBNCConvert::convert_to_vbnc_p(RuntimeOrigin::signed(BOB), VBNC, 1), + Error::::LessThanExistentialDeposit + ); + }); +} + +#[test] +fn charge_vbnc_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Tokens::deposit(VBNC_P, &BOB, 500)); + + assert_ok!(VBNCConvert::charge_vbnc_p(RuntimeOrigin::signed(BOB), 100)); + System::assert_last_event(RuntimeEvent::VBNCConvert(Event::VbncPCharged { + who: BOB, + value: 100, + })); + + assert_eq!(::MultiCurrency::free_balance(VBNC_P, &BOB), 400); + assert_eq!( + ::MultiCurrency::free_balance( + VBNC_P, + &VBNCConvert::vbnc_p_pool_account() + ), + 100 + ); + }); +} + +#[test] +fn charge_vbnc_should_fail_with_account_balance_poor() { + new_test_ext().execute_with(|| { + assert_noop!( + VBNCConvert::charge_vbnc_p(RuntimeOrigin::signed(BOB), 100), + Error::::NotEnoughBalance + ); + }); +} diff --git a/pallets/vbnc-convert/src/weights.rs b/pallets/vbnc-convert/src/weights.rs new file mode 100644 index 000000000..05b2cc7af --- /dev/null +++ b/pallets/vbnc-convert/src/weights.rs @@ -0,0 +1,94 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Autogenerated weights for bifrost_vbnc_convert +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-09-05, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! HOSTNAME: `suntiebingdeMacBook-Pro.local`, CPU: `` +//! WASM-EXECUTION: Compiled, CHAIN: Some("bifrost-kusama-local"), DB CACHE: 1024 + +// Executed Command: +// target/release/bifrost +// benchmark +// pallet +// --chain=bifrost-kusama-local +// --steps=50 +// --repeat=20 +// --pallet=bifrost_vbnc_convert +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./pallets/vbnc-convert/src/weights.rs +// --template=./weight-template/pallet-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for bifrost_vbnc_convert. +pub trait WeightInfo { + fn convert_to_vbnc_p() -> Weight; + fn charge_vbnc_p() -> Weight; +} + +// For backwards compatibility and tests +impl WeightInfo for () { + /// Storage: `Tokens::Accounts` (r:3 w:3) + /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(118), added: 2593, mode: `MaxEncodedLen`) + /// Storage: `AssetRegistry::CurrencyMetadatas` (r:2 w:0) + /// Proof: `AssetRegistry::CurrencyMetadatas` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Tokens::TotalIssuance` (r:1 w:1) + /// Proof: `Tokens::TotalIssuance` (`max_values`: None, `max_size`: Some(38), added: 2513, mode: `MaxEncodedLen`) + fn convert_to_vbnc_p() -> Weight { + // Proof Size summary in bytes: + // Measured: `980` + // Estimated: `8769` + // Minimum execution time: 66_000_000 picoseconds. + Weight::from_parts(67_000_000, 8769) + .saturating_add(RocksDbWeight::get().reads(7_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) + } + /// Storage: `Tokens::Accounts` (r:2 w:2) + /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(118), added: 2593, mode: `MaxEncodedLen`) + /// Storage: `AssetRegistry::CurrencyMetadatas` (r:1 w:0) + /// Proof: `AssetRegistry::CurrencyMetadatas` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn charge_vbnc_p() -> Weight { + // Proof Size summary in bytes: + // Measured: `712` + // Estimated: `6176` + // Minimum execution time: 41_000_000 picoseconds. + Weight::from_parts(42_000_000, 6176) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } +} diff --git a/pallets/vsbond-auction/src/lib.rs b/pallets/vsbond-auction/src/lib.rs index 890cc45ca..8f68b1dce 100644 --- a/pallets/vsbond-auction/src/lib.rs +++ b/pallets/vsbond-auction/src/lib.rs @@ -217,13 +217,11 @@ pub mod pallet { } #[pallet::storage] - #[pallet::getter(fn order_id)] pub(crate) type NextOrderId, I: 'static = ()> = StorageValue<_, OrderId, ValueQuery>; // Just store order ids that be in-trade. #[pallet::storage] - #[pallet::getter(fn user_order_ids)] pub(crate) type UserOrderIds, I: 'static = ()> = StorageDoubleMap< _, Blake2_128Concat, @@ -235,13 +233,11 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn order_info)] pub type TotalOrderInfos, I: 'static = ()> = StorageMap<_, Blake2_128Concat, OrderId, OrderInfo, BalanceOf>>; /// transaction fee rate[sellFee, buyFee] #[pallet::storage] - #[pallet::getter(fn get_transaction_fee_rate)] pub type TransactionFee, I: 'static = ()> = StorageValue<_, (Permill, Permill), ValueQuery, DefaultPrice>; @@ -289,7 +285,7 @@ pub mod pallet { }; // Calculate the transaction fee - let maker_fee_rate = Self::get_transaction_fee_rate().0; + let maker_fee_rate = TransactionFee::::get().0; let maker_fee = maker_fee_rate.mul_floor(total_price); match order_type { @@ -321,7 +317,7 @@ pub mod pallet { }, } - let order_ids_len = Self::user_order_ids(&owner, order_type).len(); + let order_ids_len = UserOrderIds::::get(&owner, order_type).len(); ensure!( order_ids_len < T::MaximumOrderInTrade::get() as usize, Error::::ExceedMaximumOrderInTrade, @@ -387,7 +383,8 @@ pub mod pallet { let from = ensure_signed(origin)?; // Check OrderInfo - let order_info = Self::order_info(order_id).ok_or(Error::::NotFindOrderInfo)?; + let order_info = + TotalOrderInfos::::get(order_id).ok_or(Error::::NotFindOrderInfo)?; // Check OrderOwner ensure!(order_info.owner == from, Error::::ForbidRevokeOrderWithoutOwnership); @@ -419,7 +416,8 @@ pub mod pallet { origin: OriginFor, #[pallet::compact] order_id: OrderId, ) -> DispatchResultWithPostInfo { - let order_info = Self::order_info(order_id).ok_or(Error::::NotFindOrderInfo)?; + let order_info = + TotalOrderInfos::::get(order_id).ok_or(Error::::NotFindOrderInfo)?; Self::partial_clinch_order(origin, order_id, order_info.remain)?; @@ -443,7 +441,8 @@ pub mod pallet { let order_taker = ensure_signed(origin)?; // Check OrderInfo - let order_info = Self::order_info(order_id).ok_or(Error::::NotFindOrderInfo)?; + let order_info = + TotalOrderInfos::::get(order_id).ok_or(Error::::NotFindOrderInfo)?; // Check OrderOwner ensure!( @@ -466,7 +465,7 @@ pub mod pallet { }; // Calculate the transaction fee - let taker_fee_rate = Self::get_transaction_fee_rate().1; + let taker_fee_rate = TransactionFee::::get().1; let taker_fee = taker_fee_rate.mul_floor(price_to_pay); // Check the balance of order taker @@ -635,7 +634,8 @@ pub mod pallet { impl, I: 'static> Pallet { pub(crate) fn next_order_id() -> OrderId { - let next_order_id = Self::order_id(); + // let next_order_id = Self::order_id(); + let next_order_id = NextOrderId::::get(); NextOrderId::::mutate(|current| *current += 1); next_order_id } @@ -666,7 +666,8 @@ pub mod pallet { pub(crate) fn do_order_revoke(order_id: OrderId) -> DispatchResultWithPostInfo { // Check OrderInfo - let order_info = Self::order_info(order_id).ok_or(Error::::NotFindOrderInfo)?; + let order_info = + TotalOrderInfos::::get(order_id).ok_or(Error::::NotFindOrderInfo)?; let (token_to_return, amount_to_return) = match order_info.order_type { OrderType::Buy => (T::InvoicingCurrency::get(), order_info.remain_price), diff --git a/pallets/vsbond-auction/src/mock.rs b/pallets/vsbond-auction/src/mock.rs index 545d48e59..2e4c9088e 100644 --- a/pallets/vsbond-auction/src/mock.rs +++ b/pallets/vsbond-auction/src/mock.rs @@ -153,13 +153,13 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities { (BRUCE, SPECIAL_VSBOND, 100), (DAVE, VSBOND, 100), #[cfg(feature = "runtime-benchmarks")] - (whitelist_caller.clone(), TOKEN, 100_000_000_000_000), + (whitelist_caller, TOKEN, 100_000_000_000_000), #[cfg(feature = "runtime-benchmarks")] - (whitelist_caller.clone(), VSBOND, 100_000_000_000_000), + (whitelist_caller, VSBOND, 100_000_000_000_000), #[cfg(feature = "runtime-benchmarks")] - (benchmarking_account_1.clone(), TOKEN, 100_000_000_000_000), + (benchmarking_account_1, TOKEN, 100_000_000_000_000), #[cfg(feature = "runtime-benchmarks")] - (benchmarking_account_1.clone(), VSBOND, 100_000_000_000_000), + (benchmarking_account_1, VSBOND, 100_000_000_000_000), ], } .assimilate_storage(&mut fs_gc) diff --git a/pallets/vsbond-auction/src/tests.rs b/pallets/vsbond-auction/src/tests.rs index 5a36a263b..fa2ce179c 100644 --- a/pallets/vsbond-auction/src/tests.rs +++ b/pallets/vsbond-auction/src/tests.rs @@ -35,12 +35,12 @@ fn create_sell_order_should_work() { OrderType::Sell )); - assert_eq!(Auction::order_id(), 1); + assert_eq!(NextOrderId::::get(), 1); - let user_order_ids = Auction::user_order_ids(ALICE, OrderType::Sell); + let user_order_ids = UserOrderIds::::get(ALICE, OrderType::Sell); assert!(user_order_ids.contains(&0)); - assert!(Auction::order_info(&0).is_some()); + assert!(TotalOrderInfos::::get(&0).is_some()); assert_eq!(Tokens::accounts(ALICE, VSBOND).free, 0); assert_eq!(Tokens::accounts(ALICE, VSBOND).frozen, 0); @@ -65,15 +65,15 @@ fn create_buy_order_should_work() { OrderType::Buy )); - assert_eq!(Auction::order_id(), 1); + assert_eq!(NextOrderId::::get(), 1); - let user_order_ids = Auction::user_order_ids(ALICE, OrderType::Buy); + let user_order_ids = UserOrderIds::::get(ALICE, OrderType::Buy); assert!(user_order_ids.contains(&0)); let module_account: u64 = ::PalletId::get().into_account_truncating(); - assert!(Auction::order_info(&0).is_some()); + assert!(TotalOrderInfos::::get(&0).is_some()); assert_eq!(Tokens::accounts(ALICE, TOKEN).free, 0); assert_eq!(Tokens::accounts(ALICE, TOKEN).frozen, 0); @@ -105,15 +105,15 @@ fn double_create_order_should_work() { OrderType::Buy )); - assert_eq!(Auction::order_id(), 2); + assert_eq!(NextOrderId::::get(), 2); - let user_sell_order_ids = Auction::user_order_ids(ALICE, OrderType::Sell); - let user_buy_order_ids = Auction::user_order_ids(ALICE, OrderType::Buy); + let user_sell_order_ids = UserOrderIds::::get(ALICE, OrderType::Sell); + let user_buy_order_ids = UserOrderIds::::get(ALICE, OrderType::Buy); assert!(user_sell_order_ids.contains(&0)); assert!(user_buy_order_ids.contains(&1)); - assert!(Auction::order_info(&0).is_some()); - assert!(Auction::order_info(&1).is_some()); + assert!(TotalOrderInfos::::get(&0).is_some()); + assert!(TotalOrderInfos::::get(&1).is_some()); let module_account: u64 = ::PalletId::get().into_account_truncating(); @@ -339,16 +339,16 @@ fn revoke_order_should_work() { )); assert_ok!(Auction::revoke_order(Some(ALICE).into(), 1)); - assert_eq!(Auction::order_id(), 2); + assert_eq!(NextOrderId::::get(), 2); - let user_sell_order_ids = Auction::user_order_ids(ALICE, OrderType::Sell); - let user_buy_order_ids = Auction::user_order_ids(ALICE, OrderType::Buy); + let user_sell_order_ids = UserOrderIds::::get(ALICE, OrderType::Sell); + let user_buy_order_ids = UserOrderIds::::get(ALICE, OrderType::Buy); assert_eq!(user_sell_order_ids.len(), 0); assert_eq!(user_buy_order_ids.len(), 0); - assert!(Auction::order_info(0).is_none()); - assert!(Auction::order_info(1).is_none()); + assert!(TotalOrderInfos::::get(0).is_none()); + assert!(TotalOrderInfos::::get(1).is_none()); assert_eq!(Tokens::accounts(ALICE, VSBOND).free, 100); assert_eq!(Tokens::accounts(ALICE, VSBOND).frozen, 0); @@ -410,12 +410,12 @@ fn revoke_sell_order_which_be_partial_clinchd_should_work() { assert_ok!(Auction::partial_clinch_order(Some(BRUCE).into(), 0, 33)); assert_ok!(Auction::revoke_order(Some(ALICE).into(), 0)); - assert_eq!(Auction::order_id(), 1); + assert_eq!(NextOrderId::::get(), 1); - let user_sell_order_ids = Auction::user_order_ids(ALICE, OrderType::Sell); + let user_sell_order_ids = UserOrderIds::::get(ALICE, OrderType::Sell); assert_eq!(user_sell_order_ids.len(), 0); - assert!(Auction::order_info(0).is_none()); + assert!(TotalOrderInfos::::get(0).is_none()); assert_eq!(Tokens::accounts(ALICE, VSBOND).free, 67); assert_eq!(Tokens::accounts(ALICE, VSBOND).frozen, 0); @@ -451,12 +451,12 @@ fn revoke_buy_order_which_be_partial_clinchd_should_work() { assert_ok!(Auction::partial_clinch_order(Some(BRUCE).into(), 0, 33)); assert_ok!(Auction::revoke_order(Some(ALICE).into(), 0)); - assert_eq!(Auction::order_id(), 1); + assert_eq!(NextOrderId::::get(), 1); - let user_buy_order_ids = Auction::user_order_ids(ALICE, OrderType::Buy); + let user_buy_order_ids = UserOrderIds::::get(ALICE, OrderType::Buy); assert_eq!(user_buy_order_ids.len(), 0); - assert!(Auction::order_info(0).is_none()); + assert!(TotalOrderInfos::::get(0).is_none()); assert_eq!(Tokens::accounts(ALICE, VSBOND).free, 133); assert_eq!(Tokens::accounts(ALICE, VSBOND).frozen, 0); @@ -539,7 +539,7 @@ fn partial_clinch_sell_order_should_work_with_ed_limits() { )); assert_ok!(Auction::partial_clinch_order(Some(CHARLIE).into(), 0, 4)); - let order_info = Auction::order_info(0).unwrap(); + let order_info = TotalOrderInfos::::get(0).unwrap(); assert_eq!(order_info.remain, 96); let module_account: u64 = @@ -575,12 +575,12 @@ fn partial_clinch_sell_order_should_work() { )); assert_ok!(Auction::partial_clinch_order(Some(BRUCE).into(), 0, 33)); - assert_eq!(Auction::order_id(), 1); + assert_eq!(NextOrderId::::get(), 1); - let user_sell_order_ids = Auction::user_order_ids(ALICE, OrderType::Sell); + let user_sell_order_ids = UserOrderIds::::get(ALICE, OrderType::Sell); assert_eq!(user_sell_order_ids.len(), 1); - let order_info = Auction::order_info(0).unwrap(); + let order_info = TotalOrderInfos::::get(0).unwrap(); assert_eq!(order_info.remain, 67); let module_account: u64 = @@ -604,10 +604,10 @@ fn partial_clinch_sell_order_should_work() { assert_ok!(Auction::partial_clinch_order(Some(BRUCE).into(), 0, 9999999)); - let user_sell_order_ids = Auction::user_order_ids(ALICE, OrderType::Buy); + let user_sell_order_ids = UserOrderIds::::get(ALICE, OrderType::Buy); assert_eq!(user_sell_order_ids.len(), 0); - assert!(Auction::order_info(0).is_none()); + assert!(TotalOrderInfos::::get(0).is_none()); assert_eq!(Tokens::accounts(ALICE, VSBOND).free, 0); assert_eq!(Tokens::accounts(ALICE, VSBOND).frozen, 0); @@ -642,12 +642,12 @@ fn partial_clinch_buy_order_should_work() { )); assert_ok!(Auction::partial_clinch_order(Some(BRUCE).into(), 0, 33)); - assert_eq!(Auction::order_id(), 1); + assert_eq!(NextOrderId::::get(), 1); - let user_buy_order_ids = Auction::user_order_ids(ALICE, OrderType::Buy); + let user_buy_order_ids = UserOrderIds::::get(ALICE, OrderType::Buy); assert_eq!(user_buy_order_ids.len(), 1); - let order_info = Auction::order_info(0).unwrap(); + let order_info = TotalOrderInfos::::get(0).unwrap(); assert_eq!(order_info.remain, 67); let module_account: u64 = @@ -671,10 +671,10 @@ fn partial_clinch_buy_order_should_work() { assert_ok!(Auction::partial_clinch_order(Some(BRUCE).into(), 0, 9999999)); - let user_buy_order_ids = Auction::user_order_ids(ALICE, OrderType::Buy); + let user_buy_order_ids = UserOrderIds::::get(ALICE, OrderType::Buy); assert_eq!(user_buy_order_ids.len(), 0); - assert!(Auction::order_info(0).is_none()); + assert!(TotalOrderInfos::::get(0).is_none()); assert_eq!(Tokens::accounts(ALICE, VSBOND).free, 200); assert_eq!(Tokens::accounts(ALICE, VSBOND).frozen, 0); @@ -774,12 +774,12 @@ fn handle_special_vsbond_sell_order_should_work() { )); assert_ok!(Auction::partial_clinch_order(Some(BRUCE).into(), 0, 33)); - assert_eq!(Auction::order_id(), 1); + assert_eq!(NextOrderId::::get(), 1); - let user_sell_order_ids = Auction::user_order_ids(ALICE, OrderType::Sell); + let user_sell_order_ids = UserOrderIds::::get(ALICE, OrderType::Sell); assert_eq!(user_sell_order_ids.len(), 1); - let order_info = Auction::order_info(0).unwrap(); + let order_info = TotalOrderInfos::::get(0).unwrap(); assert_eq!(order_info.remain, 67); let module_account: u64 = @@ -803,10 +803,10 @@ fn handle_special_vsbond_sell_order_should_work() { assert_ok!(Auction::partial_clinch_order(Some(BRUCE).into(), 0, 9999999)); - let user_sell_order_ids = Auction::user_order_ids(ALICE, OrderType::Buy); + let user_sell_order_ids = UserOrderIds::::get(ALICE, OrderType::Buy); assert_eq!(user_sell_order_ids.len(), 0); - assert!(Auction::order_info(0).is_none()); + assert!(TotalOrderInfos::::get(0).is_none()); assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).free, 0); assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).frozen, 0); @@ -841,12 +841,12 @@ fn handle_special_vsbond_buy_order_should_work() { )); assert_ok!(Auction::partial_clinch_order(Some(BRUCE).into(), 0, 33)); - assert_eq!(Auction::order_id(), 1); + assert_eq!(NextOrderId::::get(), 1); - let user_buy_order_ids = Auction::user_order_ids(ALICE, OrderType::Buy); + let user_buy_order_ids = UserOrderIds::::get(ALICE, OrderType::Buy); assert_eq!(user_buy_order_ids.len(), 1); - let order_info = Auction::order_info(0).unwrap(); + let order_info = TotalOrderInfos::::get(0).unwrap(); assert_eq!(order_info.remain, 67); let module_account: u64 = @@ -870,10 +870,10 @@ fn handle_special_vsbond_buy_order_should_work() { assert_ok!(Auction::partial_clinch_order(Some(BRUCE).into(), 0, 9999999)); - let user_buy_order_ids = Auction::user_order_ids(ALICE, OrderType::Buy); + let user_buy_order_ids = UserOrderIds::::get(ALICE, OrderType::Buy); assert_eq!(user_buy_order_ids.len(), 0); - assert!(Auction::order_info(0).is_none()); + assert!(TotalOrderInfos::::get(0).is_none()); assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).free, 200); assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).frozen, 0); @@ -900,7 +900,7 @@ fn set_buy_and_sell_transaction_fee_rate_should_work() { assert_ok!(Auction::set_buy_and_sell_transaction_fee_rate(Some(ALICE).into(), 1000, 1000)); assert_eq!( - Auction::get_transaction_fee_rate(), + TransactionFee::::get(), (Permill::from_percent(10), Permill::from_percent(10)) ); diff --git a/pallets/vstoken-conversion/src/lib.rs b/pallets/vstoken-conversion/src/lib.rs index 06cd13980..26b086679 100644 --- a/pallets/vstoken-conversion/src/lib.rs +++ b/pallets/vstoken-conversion/src/lib.rs @@ -141,17 +141,14 @@ pub mod pallet { } #[pallet::storage] - #[pallet::getter(fn relaychain_lease)] pub type RelaychainLease = StorageValue<_, u32, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn exchange_rate)] pub type ExchangeRate = StorageMap<_, Twox64Concat, i32, VstokenConversionExchangeRate, ValueQuery>; /// exchange fee #[pallet::storage] - #[pallet::getter(fn exchange_fee)] pub type ExchangeFee = StorageValue<_, VstokenConversionExchangeFee>, ValueQuery>; diff --git a/pallets/vstoken-conversion/src/tests.rs b/pallets/vstoken-conversion/src/tests.rs index edef330cb..d997229fd 100644 --- a/pallets/vstoken-conversion/src/tests.rs +++ b/pallets/vstoken-conversion/src/tests.rs @@ -66,7 +66,7 @@ fn vsksm_convert_to_vsbond() { 8, EXCHANGE_RATE )); - assert_eq!(VstokenConversion::exchange_rate(8), EXCHANGE_RATE); + assert_eq!(ExchangeRate::::get(8), EXCHANGE_RATE); assert_noop!( VstokenConversion::vstoken_convert_to_vsbond( Some(BOB).into(), @@ -141,7 +141,7 @@ fn vsbond_convert_to_vsksm() { 8, EXCHANGE_RATE )); - assert_eq!(VstokenConversion::exchange_rate(8), EXCHANGE_RATE); + assert_eq!(ExchangeRate::::get(8), EXCHANGE_RATE); let vsbond_account: AccountId = ::VsbondAccount::get().into_account_truncating(); assert_ok!(VstokenConversion::vsbond_convert_to_vstoken( diff --git a/pallets/vtoken-minting/Cargo.toml b/pallets/vtoken-minting/Cargo.toml index ade306b6e..248ac8e8d 100644 --- a/pallets/vtoken-minting/Cargo.toml +++ b/pallets/vtoken-minting/Cargo.toml @@ -23,7 +23,7 @@ xcm = { workspace = true } cumulus-primitives-core = { workspace = true } sp-core = { workspace = true } sp-runtime = { workspace = true } -bifrost-ve-minting = { workspace = true } +bb-bnc = { workspace = true } bifrost-asset-registry = { workspace = true } [dev-dependencies] diff --git a/pallets/vtoken-minting/src/lib.rs b/pallets/vtoken-minting/src/lib.rs index 599ea45f5..687ee5475 100644 --- a/pallets/vtoken-minting/src/lib.rs +++ b/pallets/vtoken-minting/src/lib.rs @@ -33,13 +33,13 @@ pub mod traits; pub mod weights; pub use weights::WeightInfo; +use bb_bnc::traits::BbBNCInterface; use bifrost_asset_registry::AssetMetadata; use bifrost_primitives::{ CurrencyId, CurrencyIdConversion, CurrencyIdExt, CurrencyIdMapping, CurrencyIdRegister, RedeemType, SlpOperator, SlpxOperator, TimeUnit, VTokenMintRedeemProvider, VTokenSupplyProvider, VtokenMintingInterface, VtokenMintingOperator, }; -use bifrost_ve_minting::traits::VeMintingInterface; use frame_support::{ pallet_prelude::*, sp_runtime::{ @@ -76,7 +76,9 @@ const INCENTIVE_LOCK_ID: LockIdentifier = *b"vmincntv"; #[frame_support::pallet] pub mod pallet { use super::*; - use bifrost_primitives::{currency::BNC, FIL}; + use bifrost_primitives::{ + currency::BNC, AstarChainId, HydrationChainId, InterlayChainId, MantaChainId, FIL, + }; use frame_support::pallet_prelude::DispatchResultWithPostInfo; use orml_traits::XcmTransfer; use xcm::{prelude::*, v4::Location}; @@ -135,26 +137,14 @@ pub mod pallet { type RelayChainToken: Get; #[pallet::constant] - type AstarParachainId: Get; - - #[pallet::constant] - type MoonbeamParachainId: Get; - - #[pallet::constant] - type HydradxParachainId: Get; - - #[pallet::constant] - type InterlayParachainId: Get; - - #[pallet::constant] - type MantaParachainId: Get; + type MoonbeamChainId: Get; type BifrostSlp: SlpOperator; type BifrostSlpx: SlpxOperator>; - // veMinting interface - type VeMinting: VeMintingInterface< + // bbBNC interface + type BbBNC: BbBNCInterface< AccountIdOf, CurrencyIdOf, BalanceOf, @@ -310,39 +300,31 @@ pub mod pallet { } #[pallet::storage] - #[pallet::getter(fn fees)] pub type Fees = StorageValue<_, (Permill, Permill), ValueQuery>; #[pallet::storage] - #[pallet::getter(fn token_pool)] pub type TokenPool = StorageMap<_, Twox64Concat, CurrencyIdOf, BalanceOf, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn unlock_duration)] pub type UnlockDuration = StorageMap<_, Twox64Concat, CurrencyIdOf, TimeUnit>; #[pallet::storage] - #[pallet::getter(fn ongoing_time_unit)] pub type OngoingTimeUnit = StorageMap<_, Twox64Concat, CurrencyIdOf, TimeUnit>; #[pallet::storage] - #[pallet::getter(fn minimum_mint)] pub type MinimumMint = StorageMap<_, Twox64Concat, CurrencyIdOf, BalanceOf, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn minimum_redeem)] pub type MinimumRedeem = StorageMap<_, Twox64Concat, CurrencyIdOf, BalanceOf, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn token_unlock_next_id)] pub type TokenUnlockNextId = StorageMap<_, Twox64Concat, CurrencyIdOf, u32, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn token_unlock_ledger)] pub type TokenUnlockLedger = StorageDoubleMap< _, Blake2_128Concat, @@ -354,7 +336,6 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn user_unlock_ledger)] pub type UserUnlockLedger = StorageDoubleMap< _, Blake2_128Concat, @@ -366,7 +347,6 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn time_unit_unlock_ledger)] pub type TimeUnitUnlockLedger = StorageDoubleMap< _, Blake2_128Concat, @@ -378,39 +358,32 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn token_to_rebond)] pub type TokenToRebond = StorageMap<_, Twox64Concat, CurrencyIdOf, BalanceOf>; #[pallet::storage] - #[pallet::getter(fn min_time_unit)] pub type MinTimeUnit = StorageMap<_, Twox64Concat, CurrencyIdOf, TimeUnit, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn unlocking_total)] pub type UnlockingTotal = StorageMap<_, Twox64Concat, CurrencyIdOf, BalanceOf, ValueQuery>; #[pallet::storage] - #[pallet::getter(fn hook_iteration_limit)] pub type HookIterationLimit = StorageValue<_, u32, ValueQuery>; //【vtoken -> Blocks】, the locked blocks for each vtoken when minted in an incentive mode #[pallet::storage] - #[pallet::getter(fn get_mint_with_lock_blocks)] pub type MintWithLockBlocks = StorageMap<_, Blake2_128Concat, CurrencyId, BlockNumberFor>; //【vtoken -> incentive coefficient】,the incentive coefficient for each vtoken when minted in // an incentive mode #[pallet::storage] - #[pallet::getter(fn get_vtoken_incentive_coef)] pub type VtokenIncentiveCoef = StorageMap<_, Blake2_128Concat, CurrencyId, u128>; //【user + vtoken -> (total_locked, vec[(locked_amount, due_block_num)])】, the locked vtoken // records for each user #[pallet::storage] - #[pallet::getter(fn get_vtoken_lock_ledger)] pub type VtokenLockLedger = StorageDoubleMap< _, Blake2_128Concat, @@ -478,9 +451,9 @@ pub mod pallet { let vtoken_id = T::CurrencyIdConversion::convert_to_vtoken(token_id) .map_err(|_| Error::::NotSupportTokenType)?; let _token_amount_to_rebond = - Self::token_to_rebond(token_id).ok_or(Error::::InvalidRebondToken)?; + TokenToRebond::::get(token_id).ok_or(Error::::InvalidRebondToken)?; if let Some((user_unlock_amount, mut ledger_list)) = - Self::user_unlock_ledger(&exchanger, token_id) + UserUnlockLedger::::get(&exchanger, token_id) { ensure!(user_unlock_amount >= token_amount, Error::::NotEnoughBalanceToUnlock); let mut tmp_amount = token_amount; @@ -492,7 +465,7 @@ pub mod pallet { .iter() .map(|&index| -> Result<(UnlockId, bool), Error> { if let Some((_, unlock_amount, time_unit, _)) = - Self::token_unlock_ledger(token_id, index) + TokenUnlockLedger::::get(token_id, index) { if tmp_amount >= unlock_amount { if let Some((_, _, time_unit, _)) = @@ -646,9 +619,9 @@ pub mod pallet { let vtoken_id = T::CurrencyIdConversion::convert_to_vtoken(token_id) .map_err(|_| Error::::NotSupportTokenType)?; let _token_amount_to_rebond = - Self::token_to_rebond(token_id).ok_or(Error::::InvalidRebondToken)?; + TokenToRebond::::get(token_id).ok_or(Error::::InvalidRebondToken)?; - let unlock_amount = match Self::token_unlock_ledger(token_id, unlock_id) { + let unlock_amount = match TokenUnlockLedger::::get(token_id, unlock_id) { Some((who, unlock_amount, time_unit, _)) => { ensure!(who == exchanger, Error::::CanNotRebond); TimeUnitUnlockLedger::::mutate_exists( @@ -825,7 +798,7 @@ pub mod pallet { if TokenToRebond::::contains_key(token_id) { let token_amount_to_rebond = - Self::token_to_rebond(token_id).ok_or(Error::::InvalidRebondToken)?; + TokenToRebond::::get(token_id).ok_or(Error::::InvalidRebondToken)?; ensure!( token_amount_to_rebond == BalanceOf::::zero(), Error::::TokenToRebondNotZero @@ -933,8 +906,8 @@ pub mod pallet { ensure!(MinimumMint::::contains_key(token_id), Error::::NotSupportTokenType); // check whether the user has veBNC - let vebnc_balance = T::VeMinting::balance_of(&minter, None) - .map_err(|_| Error::::VeBNCCheckingError)?; + let vebnc_balance = + T::BbBNC::balance_of(&minter, None).map_err(|_| Error::::VeBNCCheckingError)?; ensure!(vebnc_balance > BalanceOf::::zero(), Error::::NotEnoughBalance); // check whether the vtoken coefficient is set @@ -1164,7 +1137,7 @@ pub mod pallet { token_id: CurrencyId, token_amount: BalanceOf, ) -> Result<(BalanceOf, BalanceOf, BalanceOf), DispatchError> { - let token_pool_amount = Self::token_pool(token_id); + let token_pool_amount = TokenPool::::get(token_id); let vtoken_total_issuance = T::MultiCurrency::total_issuance(vtoken_id); let (mint_rate, _redeem_rate) = Fees::::get(); let mint_fee = mint_rate * token_amount; @@ -1273,7 +1246,7 @@ pub mod pallet { let dest = Location::new( 1, [ - Parachain(T::AstarParachainId::get()), + Parachain(AstarChainId::get()), AccountId32 { network: None, id: receiver.encode().try_into().unwrap(), @@ -1293,7 +1266,7 @@ pub mod pallet { let dest = Location::new( 1, [ - Parachain(T::HydradxParachainId::get()), + Parachain(HydrationChainId::get()), AccountId32 { network: None, id: receiver.encode().try_into().unwrap(), @@ -1313,7 +1286,7 @@ pub mod pallet { let dest = Location::new( 1, [ - Parachain(T::InterlayParachainId::get()), + Parachain(InterlayChainId::get()), AccountId32 { network: None, id: receiver.encode().try_into().unwrap(), @@ -1333,7 +1306,7 @@ pub mod pallet { let dest = Location::new( 1, [ - Parachain(T::MantaParachainId::get()), + Parachain(MantaChainId::get()), AccountId32 { network: None, id: receiver.encode().try_into().unwrap(), @@ -1353,7 +1326,7 @@ pub mod pallet { let dest = Location::new( 1, [ - Parachain(T::MoonbeamParachainId::get()), + Parachain(T::MoonbeamChainId::get()), AccountKey20 { network: None, key: receiver.to_fixed_bytes() }, ], ); @@ -1506,9 +1479,9 @@ pub mod pallet { if let Some((_total_locked, ledger_list, token_id)) = TimeUnitUnlockLedger::::get(time_unit.clone(), currency) { - for index in ledger_list.iter().take(Self::hook_iteration_limit() as usize) { + for index in ledger_list.iter().take(HookIterationLimit::::get() as usize) { if let Some((account, unlock_amount, time_unit, redeem_type)) = - Self::token_unlock_ledger(token_id, index) + TokenUnlockLedger::::get(token_id, index) { let entrance_account_balance = T::MultiCurrency::free_balance( token_id, @@ -1634,7 +1607,7 @@ pub mod pallet { redeem_fee, )?; - let token_pool_amount = Self::token_pool(token_id); + let token_pool_amount = TokenPool::::get(token_id); let vtoken_total_issuance = T::MultiCurrency::total_issuance(vtoken_id); let token_amount: BalanceOf = U256::from(vtoken_amount.saturated_into::()) .saturating_mul(token_pool_amount.saturated_into::().into()) @@ -1644,12 +1617,12 @@ pub mod pallet { .map_err(|_| Error::::CalculationOverflow)? .unique_saturated_into(); - let next_id = Self::token_unlock_next_id(token_id); + let next_id = TokenUnlockNextId::::get(token_id); match OngoingTimeUnit::::get(token_id) { Some(time_unit) => { // Calculate the time to be locked let result_time_unit = Self::add_time_unit( - Self::unlock_duration(token_id) + UnlockDuration::::get(token_id) .ok_or(Error::::UnlockDurationNotFound)?, time_unit, )?; @@ -1769,7 +1742,7 @@ pub mod pallet { vtoken_id: CurrencyIdOf, token_amount: BalanceOf, ) -> Result, DispatchError> { - let token_pool_amount = Self::token_pool(token_id); + let token_pool_amount = TokenPool::::get(token_id); let vtoken_total_issuance = T::MultiCurrency::total_issuance(vtoken_id); let value = U256::from(token_amount.saturated_into::()) @@ -1787,7 +1760,7 @@ pub mod pallet { vtoken_id: CurrencyIdOf, vtoken_amount: BalanceOf, ) -> Result, DispatchError> { - let token_pool_amount = Self::token_pool(token_id); + let token_pool_amount = TokenPool::::get(token_id); let vtoken_total_issuance = T::MultiCurrency::total_issuance(vtoken_id); let value = U256::from(vtoken_amount.saturated_into::()) @@ -1835,7 +1808,7 @@ pub mod pallet { &vtoken_id, |value| -> Result<(), Error> { // get the vtoken lock duration from VtokenIncentiveCoef - let lock_duration = Self::get_mint_with_lock_blocks(vtoken_id) + let lock_duration = MintWithLockBlocks::::get(vtoken_id) .ok_or(Error::::IncentiveLockBlocksNotSet)?; let current_block = frame_system::Pallet::::block_number(); let due_block = current_block @@ -1885,13 +1858,13 @@ pub mod pallet { // get current block number let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); // get the veBNC total amount - let vebnc_total_issuance = T::VeMinting::total_supply(current_block_number) + let vebnc_total_issuance = T::BbBNC::total_supply(current_block_number) .map_err(|_| Error::::VeBNCCheckingError)?; ensure!(vebnc_total_issuance > BalanceOf::::zero(), Error::::BalanceZero); // get the veBNC balance of the minter - let minter_vebnc_balance = T::VeMinting::balance_of(minter, None) - .map_err(|_| Error::::VeBNCCheckingError)?; + let minter_vebnc_balance = + T::BbBNC::balance_of(minter, None).map_err(|_| Error::::VeBNCCheckingError)?; ensure!(minter_vebnc_balance > BalanceOf::::zero(), Error::::NotEnoughBalance); // get the percentage of the veBNC balance of the minter to the total veBNC amount and @@ -1907,7 +1880,7 @@ pub mod pallet { let vtoken_total_issuance = T::MultiCurrency::total_issuance(vtoken_id); // get the incentive coef for the vtoken - let incentive_coef = Self::get_vtoken_incentive_coef(vtoken_id) + let incentive_coef = VtokenIncentiveCoef::::get(vtoken_id) .ok_or(Error::::IncentiveCoefNotFound)?; // calculate the incentive amount, but mind the overflow @@ -1958,7 +1931,7 @@ pub mod pallet { let vtoken_id = T::CurrencyIdConversion::convert_to_vtoken(token) .map_err(|_| Error::::NotSupportTokenType)?; - let token_pool_amount = Self::token_pool(token); + let token_pool_amount = TokenPool::::get(token); let vtoken_total_issuance = T::MultiCurrency::total_issuance(vtoken_id); let mut vtoken_amount = U256::from(amount); @@ -1981,7 +1954,7 @@ impl VtokenMintingOperator, AccountIdOf, for Pallet { fn get_token_pool(currency_id: CurrencyId) -> BalanceOf { - Self::token_pool(currency_id) + TokenPool::::get(currency_id) } fn increase_token_pool(currency_id: CurrencyId, token_amount: BalanceOf) -> DispatchResult { @@ -2013,14 +1986,14 @@ impl VtokenMintingOperator, AccountIdOf, } fn get_ongoing_time_unit(currency_id: CurrencyId) -> Option { - Self::ongoing_time_unit(currency_id) + OngoingTimeUnit::::get(currency_id) } fn get_unlock_records( currency_id: CurrencyId, time_unit: TimeUnit, ) -> Option<(BalanceOf, Vec)> { - if let Some((balance, list, _)) = Self::time_unit_unlock_ledger(&time_unit, currency_id) { + if let Some((balance, list, _)) = TimeUnitUnlockLedger::::get(&time_unit, currency_id) { Some((balance, list.into_inner())) } else { None @@ -2034,7 +2007,7 @@ impl VtokenMintingOperator, AccountIdOf, deduct_amount: BalanceOf, ) -> DispatchResult { if let Some((who, unlock_amount, time_unit, _)) = - Self::token_unlock_ledger(currency_id, index) + TokenUnlockLedger::::get(currency_id, index) { ensure!(unlock_amount >= deduct_amount, Error::::NotEnoughBalanceToUnlock); @@ -2124,23 +2097,11 @@ impl VtokenMintingOperator, AccountIdOf, currency_id: CurrencyId, index: u32, ) -> Option<(AccountIdOf, BalanceOf, TimeUnit, RedeemType>)> { - Self::token_unlock_ledger(currency_id, index) + TokenUnlockLedger::::get(currency_id, index) } - fn get_astar_parachain_id() -> u32 { - T::AstarParachainId::get() - } fn get_moonbeam_parachain_id() -> u32 { - T::MoonbeamParachainId::get() - } - fn get_hydradx_parachain_id() -> u32 { - T::HydradxParachainId::get() - } - fn get_interlay_parachain_id() -> u32 { - T::InterlayParachainId::get() - } - fn get_manta_parachain_id() -> u32 { - T::MantaParachainId::get() + T::MoonbeamChainId::get() } } @@ -2203,23 +2164,11 @@ impl VtokenMintingInterface, CurrencyIdOf, BalanceO } fn get_token_pool(currency_id: CurrencyId) -> BalanceOf { - Self::token_pool(currency_id) + TokenPool::::get(currency_id) } - fn get_astar_parachain_id() -> u32 { - T::AstarParachainId::get() - } fn get_moonbeam_parachain_id() -> u32 { - T::MoonbeamParachainId::get() - } - fn get_hydradx_parachain_id() -> u32 { - T::HydradxParachainId::get() - } - fn get_interlay_parachain_id() -> u32 { - T::InterlayParachainId::get() - } - fn get_manta_parachain_id() -> u32 { - T::MantaParachainId::get() + T::MoonbeamChainId::get() } } @@ -2234,7 +2183,7 @@ impl VTokenSupplyProvider, BalanceOf> for Pallet) -> Option> { if CurrencyId::is_token(&token) { - Some(Self::token_pool(token)) + Some(TokenPool::::get(token)) } else { None } diff --git a/pallets/vtoken-minting/src/mock.rs b/pallets/vtoken-minting/src/mock.rs index 24d469e92..f04aa0e80 100644 --- a/pallets/vtoken-minting/src/mock.rs +++ b/pallets/vtoken-minting/src/mock.rs @@ -21,14 +21,14 @@ #![cfg(test)] #![allow(non_upper_case_globals)] +use bb_bnc::{BbBNCInterface, Point}; use bifrost_asset_registry::AssetIdMaps; use bifrost_primitives::{ currency::{BNC, DOT, FIL, KSM, MOVR, VBNC, VFIL, VKSM, VMOVR}, - CurrencyId, CurrencyIdMapping, SlpxOperator, TokenSymbol, + CurrencyId, CurrencyIdMapping, MoonbeamChainId, SlpxOperator, TokenSymbol, }; use bifrost_runtime_common::{micro, milli}; use bifrost_slp::{QueryId, QueryResponseManager}; -use bifrost_ve_minting::{Point, VeMintingInterface}; pub use cumulus_primitives_core::ParaId; use frame_support::{ derive_impl, ord_parameter_types, @@ -222,18 +222,14 @@ impl vtoken_minting::Config for Runtime { type IncentivePoolAccount = IncentivePoolAccount; type BifrostSlp = Slp; type BifrostSlpx = SlpxInterface; - type VeMinting = VeMinting; + type BbBNC = BbBNC; type RelayChainToken = RelayCurrencyId; type CurrencyIdConversion = AssetIdMaps; type CurrencyIdRegister = AssetIdMaps; type WeightInfo = (); type OnRedeemSuccess = (); type XcmTransfer = XTokens; - type AstarParachainId = ConstU32<2007>; - type MoonbeamParachainId = ConstU32<2023>; - type HydradxParachainId = ConstU32<2034>; - type MantaParachainId = ConstU32<2104>; - type InterlayParachainId = ConstU32<2032>; + type MoonbeamChainId = MoonbeamChainId; type ChannelCommission = (); type AssetIdMaps = AssetIdMaps; } @@ -467,11 +463,11 @@ pub fn run_to_block(n: BlockNumber) { } } +use bb_bnc::IncentiveConfig; use bifrost_primitives::PoolId; -use bifrost_ve_minting::IncentiveConfig; -// Mock VeMinting Struct -pub struct VeMinting; -impl VeMintingInterface for VeMinting { +// Mock BbBNC Struct +pub struct BbBNC; +impl BbBNCInterface for BbBNC { fn balance_of(_addr: &AccountId, _time: Option) -> Result { Ok(100) } diff --git a/pallets/vtoken-minting/src/tests.rs b/pallets/vtoken-minting/src/tests.rs index 9f7c4015e..20e47dac7 100644 --- a/pallets/vtoken-minting/src/tests.rs +++ b/pallets/vtoken-minting/src/tests.rs @@ -41,7 +41,7 @@ fn mint_bnc() { TimeUnit::Era(1) )); assert_ok!(VtokenMinting::increase_token_pool(BNC, 70000000000)); - // assert_eq!(VtokenMinting::token_pool(BNC), 70000000000); + // assert_eq!(TokenPool::::get(BNC), 70000000000); assert_ok!(VtokenMinting::update_ongoing_time_unit(BNC, TimeUnit::Era(1))); assert_eq!(Tokens::free_balance(VBNC, &BOB), 95000000000); assert_ok!(VtokenMinting::redeem(Some(BOB).into(), VBNC, 20000000000)); @@ -104,9 +104,9 @@ fn mint() { BoundedVec::default(), None )); - assert_eq!(VtokenMinting::token_pool(MOVR), 190000000000000000000); - assert_eq!(VtokenMinting::token_pool(KSM), 95000000000); - assert_eq!(VtokenMinting::minimum_mint(KSM), 200); + assert_eq!(TokenPool::::get(MOVR), 190000000000000000000); + assert_eq!(TokenPool::::get(KSM), 95000000000); + assert_eq!(MinimumMint::::get(KSM), 200); assert_eq!(Tokens::total_issuance(VKSM), 95000001000); let (entrance_account, _exit_account) = VtokenMinting::get_entrance_and_exit_accounts(); @@ -140,8 +140,8 @@ fn redeem() { ); assert_ok!(VtokenMinting::redeem(Some(BOB).into(), VKSM, 100)); assert_ok!(VtokenMinting::redeem(Some(BOB).into(), VKSM, 200)); - assert_eq!(VtokenMinting::token_pool(KSM), 1686); // 1000 + 980 - 98 - 196 - assert_eq!(VtokenMinting::unlocking_total(KSM), 294); // 98 + 196 + assert_eq!(TokenPool::::get(KSM), 1686); // 1000 + 980 - 98 - 196 + assert_eq!(UnlockingTotal::::get(KSM), 294); // 98 + 196 assert_ok!(VtokenMinting::set_unlock_duration( RuntimeOrigin::signed(ALICE), MOVR, @@ -163,27 +163,27 @@ fn redeem() { MOVR, TimeUnit::Round(1) )); - assert_eq!(VtokenMinting::min_time_unit(MOVR), TimeUnit::Round(1)); + assert_eq!(MinTimeUnit::::get(MOVR), TimeUnit::Round(1)); assert_ok!(VtokenMinting::set_unlocking_total(RuntimeOrigin::signed(ALICE), MOVR, 1000)); - assert_eq!(VtokenMinting::unlocking_total(MOVR), 1000); + assert_eq!(UnlockingTotal::::get(MOVR), 1000); let (entrance_account, _exit_account) = VtokenMinting::get_entrance_and_exit_accounts(); assert_eq!(Tokens::free_balance(KSM, &entrance_account), 980); let mut ledger_list_origin = BoundedVec::default(); assert_ok!(ledger_list_origin.try_push(0)); assert_ok!(ledger_list_origin.try_push(1)); assert_eq!( - VtokenMinting::user_unlock_ledger(BOB, KSM), + UserUnlockLedger::::get(BOB, KSM), Some((294, ledger_list_origin.clone())) ); assert_eq!( - VtokenMinting::token_unlock_ledger(KSM, 0), + TokenUnlockLedger::::get(KSM, 0), Some((BOB, 98, TimeUnit::Era(2), RedeemType::Native)) ); let mut ledger_list_origin2 = BoundedVec::default(); assert_ok!(ledger_list_origin2.try_push(0)); assert_ok!(ledger_list_origin2.try_push(1)); assert_eq!( - VtokenMinting::time_unit_unlock_ledger(TimeUnit::Era(2), KSM), + TimeUnitUnlockLedger::::get(TimeUnit::Era(2), KSM), Some((294, ledger_list_origin2, KSM)) ); }); @@ -210,7 +210,7 @@ fn rebond() { assert_ok!(VtokenMinting::redeem(Some(BOB).into(), VKSM, 200)); assert_ok!(VtokenMinting::redeem(Some(BOB).into(), VKSM, 100)); assert_eq!( - VtokenMinting::token_unlock_ledger(KSM, 1), + TokenUnlockLedger::::get(KSM, 1), Some((BOB, 100, TimeUnit::Era(1), RedeemType::Native)) ); assert_noop!( @@ -220,20 +220,20 @@ fn rebond() { assert_ok!(VtokenMinting::add_support_rebond_token(RuntimeOrigin::signed(ALICE), KSM)); assert_ok!(VtokenMinting::rebond(Some(BOB).into(), KSM, 200)); assert_eq!( - VtokenMinting::time_unit_unlock_ledger(TimeUnit::Era(1), KSM), + TimeUnitUnlockLedger::::get(TimeUnit::Era(1), KSM), Some((100, ledger_list_origin.clone(), KSM)) ); assert_eq!( - VtokenMinting::user_unlock_ledger(BOB, KSM), + UserUnlockLedger::::get(BOB, KSM), Some((100, ledger_list_origin2.clone())) ); assert_eq!( - VtokenMinting::token_unlock_ledger(KSM, 0), + TokenUnlockLedger::::get(KSM, 0), Some((BOB, 100, TimeUnit::Era(1), RedeemType::Native)) ); - assert_eq!(VtokenMinting::token_unlock_ledger(KSM, 1), None); - assert_eq!(VtokenMinting::token_pool(KSM), 1200); - assert_eq!(VtokenMinting::unlocking_total(KSM), 100); // 200 + 100 - 200 + assert_eq!(TokenUnlockLedger::::get(KSM, 1), None); + assert_eq!(TokenPool::::get(KSM), 1200); + assert_eq!(UnlockingTotal::::get(KSM), 100); // 200 + 100 - 200 let (entrance_account, _exit_account) = VtokenMinting::get_entrance_and_exit_accounts(); assert_eq!(Tokens::free_balance(KSM, &entrance_account), 300); }); @@ -273,10 +273,10 @@ fn movr() { VtokenMinting::on_initialize(100); VtokenMinting::on_initialize(100); VtokenMinting::on_initialize(100); - assert_eq!(VtokenMinting::min_time_unit(MOVR), TimeUnit::Round(2)); - assert_eq!(VtokenMinting::ongoing_time_unit(MOVR), Some(TimeUnit::Round(1))); + assert_eq!(MinTimeUnit::::get(MOVR), TimeUnit::Round(2)); + assert_eq!(OngoingTimeUnit::::get(MOVR), Some(TimeUnit::Round(1))); assert_eq!(Tokens::free_balance(MOVR, &BOB), 984200000000000000000); - assert_eq!(VtokenMinting::token_unlock_ledger(MOVR, 0), None); + assert_eq!(TokenUnlockLedger::::get(MOVR, 0), None); assert_ok!(VtokenMinting::mint( Some(CHARLIE).into(), MOVR, @@ -286,41 +286,41 @@ fn movr() { )); assert_ok!(VtokenMinting::redeem(Some(CHARLIE).into(), VMOVR, 20000000000000000000000)); assert_ok!(VtokenMinting::add_support_rebond_token(RuntimeOrigin::signed(ALICE), MOVR)); - assert_eq!(VtokenMinting::token_unlock_ledger(MOVR, 0), None); - assert_eq!(VtokenMinting::token_unlock_ledger(MOVR, 1), None); - assert_eq!(VtokenMinting::token_unlock_ledger(MOVR, 2), None); - assert_eq!(VtokenMinting::token_unlock_next_id(MOVR), 4); + assert_eq!(TokenUnlockLedger::::get(MOVR, 0), None); + assert_eq!(TokenUnlockLedger::::get(MOVR, 1), None); + assert_eq!(TokenUnlockLedger::::get(MOVR, 2), None); + assert_eq!(TokenUnlockNextId::::get(MOVR), 4); assert_ok!(VtokenMinting::rebond(Some(CHARLIE).into(), MOVR, 19000000000000000000000)); assert_ok!(VtokenMinting::rebond_by_unlock_id(Some(CHARLIE).into(), MOVR, 3)); - assert_eq!(VtokenMinting::unlocking_total(MOVR), 0); + assert_eq!(UnlockingTotal::::get(MOVR), 0); }); } #[test] fn hook() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { - assert_eq!(VtokenMinting::min_time_unit(KSM), TimeUnit::Era(0)); + assert_eq!(MinTimeUnit::::get(KSM), TimeUnit::Era(0)); assert_ok!(VtokenMinting::update_ongoing_time_unit(KSM, TimeUnit::Era(3))); - assert_eq!(VtokenMinting::ongoing_time_unit(KSM), Some(TimeUnit::Era(3))); + assert_eq!(OngoingTimeUnit::::get(KSM), Some(TimeUnit::Era(3))); assert_ok!(VtokenMinting::set_unlock_duration( RuntimeOrigin::signed(ALICE), KSM, TimeUnit::Era(1) )); assert_ok!(VtokenMinting::set_hook_iteration_limit(RuntimeOrigin::signed(ALICE), 1)); - assert_eq!(VtokenMinting::unlock_duration(KSM), Some(TimeUnit::Era(1))); + assert_eq!(UnlockDuration::::get(KSM), Some(TimeUnit::Era(1))); VtokenMinting::on_initialize(100); VtokenMinting::on_initialize(100); VtokenMinting::on_initialize(100); VtokenMinting::on_initialize(100); VtokenMinting::on_initialize(100); - assert_eq!(VtokenMinting::min_time_unit(KSM), TimeUnit::Era(4)); + assert_eq!(MinTimeUnit::::get(KSM), TimeUnit::Era(4)); assert_ok!(VtokenMinting::increase_token_pool(KSM, 1000)); assert_ok!(VtokenMinting::mint(Some(BOB).into(), KSM, 200, BoundedVec::default(), None)); assert_ok!(VtokenMinting::mint(Some(BOB).into(), KSM, 100, BoundedVec::default(), None)); assert_ok!(VtokenMinting::redeem(Some(BOB).into(), VKSM, 200)); assert_ok!(VtokenMinting::redeem(Some(BOB).into(), VKSM, 100)); - assert_eq!(VtokenMinting::unlocking_total(KSM), 300); // 200 + 100 + assert_eq!(UnlockingTotal::::get(KSM), 300); // 200 + 100 assert_noop!( VtokenMinting::rebond(Some(BOB).into(), KSM, 100), Error::::InvalidRebondToken @@ -329,26 +329,26 @@ fn hook() { let (entrance_account, _exit_account) = VtokenMinting::get_entrance_and_exit_accounts(); assert_eq!(Tokens::free_balance(KSM, &entrance_account), 300); VtokenMinting::on_initialize(100); - assert_eq!(VtokenMinting::min_time_unit(KSM), TimeUnit::Era(4)); + assert_eq!(MinTimeUnit::::get(KSM), TimeUnit::Era(4)); VtokenMinting::on_initialize(100); - assert_eq!(VtokenMinting::token_unlock_ledger(KSM, 0), None); - assert_eq!(VtokenMinting::token_unlock_ledger(KSM, 1), None); - assert_eq!(VtokenMinting::time_unit_unlock_ledger(TimeUnit::Era(4), KSM), None); - assert_eq!(VtokenMinting::time_unit_unlock_ledger(TimeUnit::Era(5), KSM), None); - assert_eq!(VtokenMinting::user_unlock_ledger(BOB, KSM), None); - assert_eq!(VtokenMinting::token_pool(KSM), 1000); + assert_eq!(TokenUnlockLedger::::get(KSM, 0), None); + assert_eq!(TokenUnlockLedger::::get(KSM, 1), None); + assert_eq!(TimeUnitUnlockLedger::::get(TimeUnit::Era(4), KSM), None); + assert_eq!(TimeUnitUnlockLedger::::get(TimeUnit::Era(5), KSM), None); + assert_eq!(UserUnlockLedger::::get(BOB, KSM), None); + assert_eq!(TokenPool::::get(KSM), 1000); assert_eq!(Tokens::free_balance(KSM, &entrance_account), 0); assert_ok!(VtokenMinting::update_ongoing_time_unit(KSM, TimeUnit::Era(5))); VtokenMinting::on_initialize(100); VtokenMinting::on_initialize(0); VtokenMinting::on_initialize(1); - assert_eq!(VtokenMinting::min_time_unit(KSM), TimeUnit::Era(6)); - assert_eq!(VtokenMinting::unlocking_total(KSM), 0); + assert_eq!(MinTimeUnit::::get(KSM), TimeUnit::Era(6)); + assert_eq!(UnlockingTotal::::get(KSM), 0); assert_ok!(VtokenMinting::mint(Some(BOB).into(), KSM, 100, BoundedVec::default(), None)); assert_ok!(VtokenMinting::redeem(Some(BOB).into(), VKSM, 200)); VtokenMinting::on_initialize(0); assert_eq!( - VtokenMinting::token_unlock_ledger(KSM, 2), + TokenUnlockLedger::::get(KSM, 2), Some((BOB, 100, TimeUnit::Era(6), RedeemType::Native)) ); let mut ledger_list_origin = BoundedVec::default(); @@ -356,11 +356,11 @@ fn hook() { let mut ledger_list_origin2 = BoundedVec::default(); assert_ok!(ledger_list_origin2.try_push(2)); assert_eq!( - VtokenMinting::time_unit_unlock_ledger(TimeUnit::Era(6), KSM), + TimeUnitUnlockLedger::::get(TimeUnit::Era(6), KSM), Some((100, ledger_list_origin.clone(), KSM)) ); assert_eq!( - VtokenMinting::user_unlock_ledger(BOB, KSM), + UserUnlockLedger::::get(BOB, KSM), Some((100, ledger_list_origin2.clone())) ); }); @@ -384,7 +384,7 @@ fn rebond_by_unlock_id() { assert_ok!(VtokenMinting::mint(Some(BOB).into(), KSM, 100, BoundedVec::default(), None)); assert_ok!(VtokenMinting::redeem(Some(BOB).into(), VKSM, 200)); assert_ok!(VtokenMinting::redeem(Some(BOB).into(), VKSM, 100)); - assert_eq!(VtokenMinting::token_pool(KSM), 1000); + assert_eq!(TokenPool::::get(KSM), 1000); assert_noop!( VtokenMinting::rebond_by_unlock_id(Some(BOB).into(), KSM, 0), Error::::InvalidRebondToken @@ -396,20 +396,20 @@ fn rebond_by_unlock_id() { ); assert_ok!(VtokenMinting::rebond_by_unlock_id(Some(BOB).into(), KSM, 0)); assert_eq!( - VtokenMinting::time_unit_unlock_ledger(TimeUnit::Era(1), KSM), + TimeUnitUnlockLedger::::get(TimeUnit::Era(1), KSM), Some((100, ledger_list_origin.clone(), KSM)) ); assert_eq!( - VtokenMinting::user_unlock_ledger(BOB, KSM), + UserUnlockLedger::::get(BOB, KSM), Some((100, ledger_list_origin2.clone())) ); - assert_eq!(VtokenMinting::token_unlock_ledger(KSM, 0), None); + assert_eq!(TokenUnlockLedger::::get(KSM, 0), None); assert_eq!( - VtokenMinting::token_unlock_ledger(KSM, 1), + TokenUnlockLedger::::get(KSM, 1), Some((BOB, 100, TimeUnit::Era(1), RedeemType::Native)) ); - assert_eq!(VtokenMinting::token_pool(KSM), 1200); - assert_eq!(VtokenMinting::unlocking_total(KSM), 100); // 200 + 100 - 200 + assert_eq!(TokenPool::::get(KSM), 1200); + assert_eq!(UnlockingTotal::::get(KSM), 100); // 200 + 100 - 200 let (entrance_account, _exit_account) = VtokenMinting::get_entrance_and_exit_accounts(); assert_eq!(Tokens::free_balance(KSM, &entrance_account), 300); }); @@ -424,28 +424,28 @@ fn fast_redeem_for_fil() { FIL, TimeUnit::Kblock(1) )); - assert_eq!(VtokenMinting::min_time_unit(FIL), TimeUnit::Kblock(1)); + assert_eq!(MinTimeUnit::::get(FIL), TimeUnit::Kblock(1)); assert_ok!(VtokenMinting::update_ongoing_time_unit(FIL, TimeUnit::Kblock(3))); - assert_eq!(VtokenMinting::ongoing_time_unit(FIL), Some(TimeUnit::Kblock(3))); + assert_eq!(OngoingTimeUnit::::get(FIL), Some(TimeUnit::Kblock(3))); assert_ok!(VtokenMinting::set_unlock_duration( RuntimeOrigin::signed(ALICE), FIL, TimeUnit::Kblock(1) )); assert_ok!(VtokenMinting::set_hook_iteration_limit(RuntimeOrigin::signed(ALICE), 1)); - assert_eq!(VtokenMinting::unlock_duration(FIL), Some(TimeUnit::Kblock(1))); + assert_eq!(UnlockDuration::::get(FIL), Some(TimeUnit::Kblock(1))); VtokenMinting::on_initialize(100); VtokenMinting::on_initialize(100); VtokenMinting::on_initialize(100); VtokenMinting::on_initialize(100); VtokenMinting::on_initialize(100); - assert_eq!(VtokenMinting::min_time_unit(FIL), TimeUnit::Kblock(4)); + assert_eq!(MinTimeUnit::::get(FIL), TimeUnit::Kblock(4)); assert_ok!(VtokenMinting::increase_token_pool(FIL, 1000)); assert_ok!(VtokenMinting::mint(Some(BOB).into(), FIL, 200, BoundedVec::default(), None)); assert_ok!(VtokenMinting::mint(Some(BOB).into(), FIL, 100, BoundedVec::default(), None)); assert_ok!(VtokenMinting::redeem(Some(BOB).into(), VFIL, 200)); assert_ok!(VtokenMinting::redeem(Some(BOB).into(), VFIL, 100)); - assert_eq!(VtokenMinting::unlocking_total(FIL), 300); // 200 + 100 + assert_eq!(UnlockingTotal::::get(FIL), 300); // 200 + 100 assert_noop!( VtokenMinting::rebond(Some(BOB).into(), FIL, 100), Error::::InvalidRebondToken @@ -454,26 +454,26 @@ fn fast_redeem_for_fil() { let (entrance_account, _exit_account) = VtokenMinting::get_entrance_and_exit_accounts(); assert_eq!(Tokens::free_balance(FIL, &entrance_account), 300); VtokenMinting::on_initialize(100); - assert_eq!(VtokenMinting::min_time_unit(FIL), TimeUnit::Kblock(4)); + assert_eq!(MinTimeUnit::::get(FIL), TimeUnit::Kblock(4)); VtokenMinting::on_initialize(100); - assert_eq!(VtokenMinting::token_unlock_ledger(FIL, 0), None); - assert_eq!(VtokenMinting::token_unlock_ledger(FIL, 1), None); - assert_eq!(VtokenMinting::time_unit_unlock_ledger(TimeUnit::Kblock(4), FIL), None); - assert_eq!(VtokenMinting::time_unit_unlock_ledger(TimeUnit::Kblock(5), FIL), None); - assert_eq!(VtokenMinting::user_unlock_ledger(BOB, FIL), None); - assert_eq!(VtokenMinting::token_pool(FIL), 1000); + assert_eq!(TokenUnlockLedger::::get(FIL, 0), None); + assert_eq!(TokenUnlockLedger::::get(FIL, 1), None); + assert_eq!(TimeUnitUnlockLedger::::get(TimeUnit::Kblock(4), FIL), None); + assert_eq!(TimeUnitUnlockLedger::::get(TimeUnit::Kblock(5), FIL), None); + assert_eq!(UserUnlockLedger::::get(BOB, FIL), None); + assert_eq!(TokenPool::::get(FIL), 1000); assert_eq!(Tokens::free_balance(FIL, &entrance_account), 0); assert_ok!(VtokenMinting::update_ongoing_time_unit(FIL, TimeUnit::Kblock(5))); VtokenMinting::on_initialize(100); VtokenMinting::on_initialize(0); VtokenMinting::on_initialize(1); - assert_eq!(VtokenMinting::min_time_unit(FIL), TimeUnit::Kblock(6)); - assert_eq!(VtokenMinting::unlocking_total(FIL), 0); + assert_eq!(MinTimeUnit::::get(FIL), TimeUnit::Kblock(6)); + assert_eq!(UnlockingTotal::::get(FIL), 0); assert_ok!(VtokenMinting::mint(Some(BOB).into(), FIL, 100, BoundedVec::default(), None)); assert_ok!(VtokenMinting::redeem(Some(BOB).into(), VFIL, 200)); VtokenMinting::on_initialize(0); assert_eq!( - VtokenMinting::token_unlock_ledger(FIL, 2), + TokenUnlockLedger::::get(FIL, 2), Some((BOB, 100, TimeUnit::Kblock(6), RedeemType::Native)) ); let mut ledger_list_origin = BoundedVec::default(); @@ -481,11 +481,11 @@ fn fast_redeem_for_fil() { let mut ledger_list_origin2 = BoundedVec::default(); assert_ok!(ledger_list_origin2.try_push(2)); assert_eq!( - VtokenMinting::time_unit_unlock_ledger(TimeUnit::Kblock(6), FIL), + TimeUnitUnlockLedger::::get(TimeUnit::Kblock(6), FIL), Some((100, ledger_list_origin.clone(), FIL)) ); assert_eq!( - VtokenMinting::user_unlock_ledger(BOB, FIL), + UserUnlockLedger::::get(BOB, FIL), Some((100, ledger_list_origin2.clone())) ); }); @@ -498,7 +498,7 @@ fn recreate_currency_ongoing_time_unit_should_work() { // set KSM ongoing time unit to be Era(1) OngoingTimeUnit::::insert(KSM, TimeUnit::Era(1)); - assert_eq!(VtokenMinting::ongoing_time_unit(KSM), Some(TimeUnit::Era(1))); + assert_eq!(OngoingTimeUnit::::get(KSM), Some(TimeUnit::Era(1))); // recreate_currency_ongoing_time_unit the ongoing time unit of KSM to be Round(2) assert_ok!(VtokenMinting::recreate_currency_ongoing_time_unit( @@ -506,7 +506,7 @@ fn recreate_currency_ongoing_time_unit_should_work() { KSM, TimeUnit::Round(2) )); - assert_eq!(VtokenMinting::ongoing_time_unit(KSM), Some(TimeUnit::Round(2))); + assert_eq!(OngoingTimeUnit::::get(KSM), Some(TimeUnit::Round(2))); }) } @@ -595,7 +595,7 @@ fn mint_with_lock_should_work() { ); // check ledger - let lock_ledger = VtokenMinting::get_vtoken_lock_ledger(BOB, VKSM).unwrap(); + let lock_ledger = VtokenLockLedger::::get(BOB, VKSM).unwrap(); let list = BoundedVec::try_from(vec![(95000000000u128, 100u64)]).unwrap(); let should_be_ledger = (95000000000u128, list); assert_eq!(lock_ledger, should_be_ledger); @@ -637,7 +637,7 @@ fn unlock_incentive_minted_vtoken_should_work() { run_to_block(101); // check ledger - let lock_ledger = VtokenMinting::get_vtoken_lock_ledger(BOB, VKSM).unwrap(); + let lock_ledger = VtokenLockLedger::::get(BOB, VKSM).unwrap(); let list = BoundedVec::try_from(vec![(95000000000u128, 100u64)]).unwrap(); let should_be_ledger = (95000000000u128, list); assert_eq!(lock_ledger, should_be_ledger); @@ -672,7 +672,7 @@ fn unlock_incentive_minted_vtoken_should_work() { assert_eq!(new_bob_vksm_balance, bob_vksm_balance); // check ledger - let lock_ledger = VtokenMinting::get_vtoken_lock_ledger(BOB, VKSM); + let lock_ledger = VtokenLockLedger::::get(BOB, VKSM); assert_eq!(lock_ledger, None); }) } @@ -683,19 +683,19 @@ fn set_incentive_coef_should_work() { env_logger::try_init().unwrap_or(()); // get vksm coefficient should return None - assert_eq!(VtokenMinting::get_vtoken_incentive_coef(VKSM), None); + assert_eq!(VtokenIncentiveCoef::::get(VKSM), None); // set vksm coefficient assert_ok!(VtokenMinting::set_incentive_coef(RuntimeOrigin::signed(ALICE), VKSM, Some(1))); // get vksm coefficient should return Some(1) - assert_eq!(VtokenMinting::get_vtoken_incentive_coef(VKSM), Some(1)); + assert_eq!(VtokenIncentiveCoef::::get(VKSM), Some(1)); // set vksm coefficient to None assert_ok!(VtokenMinting::set_incentive_coef(RuntimeOrigin::signed(ALICE), VKSM, None)); // get vksm coefficient should return None - assert_eq!(VtokenMinting::get_vtoken_incentive_coef(VKSM), None); + assert_eq!(VtokenIncentiveCoef::::get(VKSM), None); }) } @@ -705,7 +705,7 @@ fn set_vtoken_incentive_lock_blocks_should_work() { env_logger::try_init().unwrap_or(()); // get vksm lock blocks should return None - assert_eq!(VtokenMinting::get_mint_with_lock_blocks(VKSM), None); + assert_eq!(MintWithLockBlocks::::get(VKSM), None); // set vksm lock blocks assert_ok!(VtokenMinting::set_vtoken_incentive_lock_blocks( @@ -715,7 +715,7 @@ fn set_vtoken_incentive_lock_blocks_should_work() { )); // get vksm lock blocks should return Some(100) - assert_eq!(VtokenMinting::get_mint_with_lock_blocks(VKSM), Some(100)); + assert_eq!(MintWithLockBlocks::::get(VKSM), Some(100)); // set vksm lock blocks to None assert_ok!(VtokenMinting::set_vtoken_incentive_lock_blocks( @@ -725,6 +725,6 @@ fn set_vtoken_incentive_lock_blocks_should_work() { )); // get vksm lock blocks should return None - assert_eq!(VtokenMinting::get_mint_with_lock_blocks(VKSM), None); + assert_eq!(MintWithLockBlocks::::get(VKSM), None); }) } diff --git a/pallets/vtoken-voting/src/mock.rs b/pallets/vtoken-voting/src/mock.rs index ffb1dee22..a9bada263 100644 --- a/pallets/vtoken-voting/src/mock.rs +++ b/pallets/vtoken-voting/src/mock.rs @@ -23,7 +23,7 @@ use crate::{BalanceOf, DerivativeAccountHandler, DerivativeIndex, DispatchResult use bifrost_primitives::{ currency::{KSM, VBNC, VKSM}, traits::XcmDestWeightAndFeeHandler, - CurrencyId, DoNothingRouter, TokenSymbol, VTokenSupplyProvider, XcmOperationType, + CurrencyId, MockXcmRouter, TokenSymbol, VTokenSupplyProvider, XcmOperationType, }; use cumulus_primitives_core::ParaId; use frame_support::{ @@ -191,7 +191,7 @@ impl pallet_xcm::Config for Runtime { type XcmExecuteFilter = Nothing; type XcmExecutor = XcmExecutor; type XcmReserveTransferFilter = Everything; - type XcmRouter = DoNothingRouter; + type XcmRouter = MockXcmRouter; type XcmTeleportFilter = Nothing; type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; diff --git a/pallets/xcm-interface/src/lib.rs b/pallets/xcm-interface/src/lib.rs index f56f617ee..ee096d51e 100644 --- a/pallets/xcm-interface/src/lib.rs +++ b/pallets/xcm-interface/src/lib.rs @@ -148,7 +148,6 @@ pub mod pallet { /// /// XcmWeightAndFee: map: XcmOperationType => (Weight, Balance) #[pallet::storage] - #[pallet::getter(fn xcm_dest_weight_and_fee)] pub type XcmWeightAndFee = StorageDoubleMap< _, Blake2_128Concat, @@ -161,7 +160,6 @@ pub mod pallet { // Tracker for the next nonce index #[pallet::storage] - #[pallet::getter(fn current_nonce)] pub(super) type CurrentNonce = StorageMap<_, Blake2_128Concat, ChainId, Nonce, ValueQuery>; @@ -238,7 +236,7 @@ pub mod pallet { let dst_location = T::AccountIdToLocation::convert(dest.clone()); - let (dest_weight, xcm_fee) = Self::xcm_dest_weight_and_fee( + let (dest_weight, xcm_fee) = XcmWeightAndFee::::get( T::RelaychainCurrencyId::get(), XcmOperationType::StatemineTransfer, ) @@ -298,7 +296,7 @@ pub mod pallet { }; let (require_weight_at_most, xcm_fee) = - Self::xcm_dest_weight_and_fee(currency_id, XcmOperationType::EthereumTransfer) + XcmWeightAndFee::::get(currency_id, XcmOperationType::EthereumTransfer) .ok_or(Error::::OperationWeightAndFeeNotExist)?; let fee: Asset = Asset { @@ -359,7 +357,7 @@ pub mod pallet { ) -> Result { // Construct contribute call data let contribute_call = Self::build_ump_crowdloan_contribute(index, amount); - let (dest_weight, xcm_fee) = Self::xcm_dest_weight_and_fee( + let (dest_weight, xcm_fee) = XcmWeightAndFee::::get( T::RelaychainCurrencyId::get(), XcmOperationType::UmpContributeTransact, ) @@ -396,7 +394,7 @@ pub mod pallet { token: CurrencyIdOf, operation: XcmOperationType, ) -> Option<(Weight, BalanceOf)> { - Self::xcm_dest_weight_and_fee(token, operation) + XcmWeightAndFee::::get(token, operation) } fn set_xcm_dest_weight_and_fee( diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 7e276ed5e..c7081880c 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -19,6 +19,7 @@ xcm-executor = { workspace = true } zenlink-protocol = { workspace = true } orml-oracle = { workspace = true } +orml-traits = { workspace = true } [features] default = ["std"] @@ -33,9 +34,11 @@ std = [ "sp-std/std", "xcm/std", + "xcm-executor/std", "zenlink-protocol/std", "orml-oracle/std", + "orml-traits/std", ] with-bifrost-runtime = [ diff --git a/primitives/src/currency.rs b/primitives/src/currency.rs index f3598dff8..3709c2598 100644 --- a/primitives/src/currency.rs +++ b/primitives/src/currency.rs @@ -55,6 +55,7 @@ pub const DOT_U_TOKEN_ID: u8 = 2u8; pub const DOT_U: CurrencyId = CurrencyId::Token2(DOT_U_TOKEN_ID); pub const ASTR_TOKEN_ID: u8 = 3u8; pub const ASTR: CurrencyId = CurrencyId::Token2(ASTR_TOKEN_ID); +pub const VASTR: CurrencyId = CurrencyId::VToken2(ASTR_TOKEN_ID); pub const FIL_TOKEN_ID: u8 = 4u8; pub const FIL: CurrencyId = CurrencyId::Token2(FIL_TOKEN_ID); pub const VFIL: CurrencyId = CurrencyId::VToken2(FIL_TOKEN_ID); @@ -80,6 +81,8 @@ pub const WETH: CurrencyId = CurrencyId::Token2(WETH_TOKEN_ID); pub const VSBOND_BNC_2001_0_8: CurrencyId = CurrencyId::VSBond(TokenSymbol::BNC, 2001, 0, 8); pub const CLOUD_TOKEN_ID: u8 = 12u8; pub const CLOUD: CurrencyId = CurrencyId::Token2(CLOUD_TOKEN_ID); +pub const VBNC_P_TOKEN_ID: u8 = 5u8; +pub const VBNC_P: CurrencyId = CurrencyId::VToken2(VBNC_P_TOKEN_ID); pub const LDOT: CurrencyId = CurrencyId::Lend(0); pub const LKSM: CurrencyId = CurrencyId::Lend(1); diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 6c3714c4c..26e07c98f 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -28,25 +28,23 @@ use sp_runtime::{ traits::{BlakeTwo256, IdentifyAccount, Verify}, FixedU128, MultiSignature, OpaqueExtrinsic, Permill, }; -use xcm::v4::{prelude::*, Asset, Location}; -use xcm_executor::traits::{AssetTransferError, TransferType, XcmAssetTransfers}; pub mod currency; -mod salp; -pub mod traits; +pub use currency::*; +pub mod xcm; +pub use crate::xcm::*; +pub mod mock_xcm; +pub use crate::mock_xcm::*; +pub mod salp; pub use salp::*; +pub mod traits; +pub use crate::traits::*; +pub mod time_unit; +pub use crate::time_unit::*; #[cfg(test)] mod tests; -pub use crate::{ - currency::{ - AssetIds, CurrencyId, ForeignAssetId, TokenId, TokenSymbol, ASTR, ASTR_TOKEN_ID, BNC, DOT, - DOT_TOKEN_ID, DOT_U, FIL, GLMR, GLMR_TOKEN_ID, KSM, MANTA, VBNC, VDOT, VKSM, VSKSM, - }, - traits::*, -}; - /// An index to a block. pub type BlockNumber = u32; @@ -167,66 +165,6 @@ pub enum ExtraFeeName { EthereumTransfer, } -// For vtoken-minting and slp modules -#[derive(Encode, Decode, Clone, RuntimeDebug, Eq, TypeInfo, MaxEncodedLen)] -pub enum TimeUnit { - // Kusama staking time unit - Era(#[codec(compact)] u32), - SlashingSpan(#[codec(compact)] u32), - // Moonriver staking time unit - Round(#[codec(compact)] u32), - // 1000 blocks. Can be used by Filecoin. - // 30 seconds per block. Kblock means 8.33 hours. - Kblock(#[codec(compact)] u32), - // 1 hour. Should be Unix Timstamp in seconds / 3600 - Hour(#[codec(compact)] u32), -} - -impl Default for TimeUnit { - fn default() -> Self { - TimeUnit::Era(0u32) - } -} - -impl PartialEq for TimeUnit { - fn eq(&self, other: &Self) -> bool { - match (&self, other) { - (Self::Era(a), Self::Era(b)) => a.eq(b), - (Self::SlashingSpan(a), Self::SlashingSpan(b)) => a.eq(b), - (Self::Round(a), Self::Round(b)) => a.eq(b), - (Self::Kblock(a), Self::Kblock(b)) => a.eq(b), - (Self::Hour(a), Self::Hour(b)) => a.eq(b), - _ => false, - } - } -} - -impl Ord for TimeUnit { - fn cmp(&self, other: &Self) -> sp_std::cmp::Ordering { - match (&self, other) { - (Self::Era(a), Self::Era(b)) => a.cmp(b), - (Self::SlashingSpan(a), Self::SlashingSpan(b)) => a.cmp(b), - (Self::Round(a), Self::Round(b)) => a.cmp(b), - (Self::Kblock(a), Self::Kblock(b)) => a.cmp(b), - (Self::Hour(a), Self::Hour(b)) => a.cmp(b), - _ => sp_std::cmp::Ordering::Less, - } - } -} - -impl PartialOrd for TimeUnit { - fn partial_cmp(&self, other: &Self) -> Option { - match (&self, other) { - (Self::Era(a), Self::Era(b)) => Some(a.cmp(b)), - (Self::SlashingSpan(a), Self::SlashingSpan(b)) => Some(a.cmp(b)), - (Self::Round(a), Self::Round(b)) => Some(a.cmp(b)), - (Self::Kblock(a), Self::Kblock(b)) => Some(a.cmp(b)), - (Self::Hour(a), Self::Hour(b)) => Some(a.cmp(b)), - _ => None, - } - } -} - // For vtoken-minting #[derive( PartialEq, Eq, Clone, Encode, Decode, MaxEncodedLen, RuntimeDebug, scale_info::TypeInfo, @@ -252,56 +190,6 @@ impl Default for RedeemType { } } -pub struct DoNothingRouter; -impl SendXcm for DoNothingRouter { - type Ticket = (); - fn validate(_dest: &mut Option, _msg: &mut Option>) -> SendResult<()> { - Ok(((), Assets::new())) - } - fn deliver(_: ()) -> Result { - Ok([0; 32]) - } -} - -pub struct Weightless; -impl PreparedMessage for Weightless { - fn weight_of(&self) -> Weight { - Weight::default() - } -} - -pub struct DoNothingExecuteXcm; -impl ExecuteXcm for DoNothingExecuteXcm { - type Prepared = Weightless; - - fn prepare(_message: Xcm) -> Result> { - Ok(Weightless) - } - - fn execute( - _origin: impl Into, - _pre: Self::Prepared, - _hash: &mut XcmHash, - _weight_credit: Weight, - ) -> Outcome { - Outcome::Complete { used: Weight::default() } - } - - fn charge_fees(_location: impl Into, _fees: Assets) -> XcmResult { - Ok(()) - } -} - -impl XcmAssetTransfers for DoNothingExecuteXcm { - type IsReserve = (); - type IsTeleporter = (); - type AssetTransactor = (); - - fn determine_for(_asset: &Asset, _dest: &Location) -> Result { - Ok(TransferType::DestinationReserve) - } -} - #[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, TypeInfo)] pub enum XcmOperationType { // SALP operations diff --git a/primitives/src/mock_xcm.rs b/primitives/src/mock_xcm.rs new file mode 100644 index 000000000..a52dda543 --- /dev/null +++ b/primitives/src/mock_xcm.rs @@ -0,0 +1,146 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use crate::{AccountId, Balance, CurrencyId}; +use orml_traits::{xcm_transfer::Transferred, XcmTransfer}; +use sp_runtime::DispatchError; +use sp_std::vec::Vec; +use xcm::{ + latest::Asset, + prelude::{ExecuteXcm, Fungible, Outcome, PreparedMessage, SendResult, Xcm, XcmResult}, + v4::{AssetId, Assets, Location, SendError, SendXcm, Weight, WeightLimit, XcmHash}, +}; +use xcm_executor::traits::{AssetTransferError, TransferType, XcmAssetTransfers}; + +pub struct MockXcmRouter; +impl SendXcm for MockXcmRouter { + type Ticket = (); + fn validate(_dest: &mut Option, _msg: &mut Option>) -> SendResult<()> { + Ok(((), Assets::new())) + } + fn deliver(_: ()) -> Result { + Ok([0; 32]) + } +} + +pub struct MockXcmTransfer; +impl XcmTransfer for MockXcmTransfer { + fn transfer( + who: AccountId, + _currency_id: CurrencyId, + amount: Balance, + dest: Location, + _dest_weight_limit: WeightLimit, + ) -> Result, DispatchError> { + Ok(Transferred { + sender: who, + assets: Default::default(), + fee: Asset { id: AssetId(Location::here()), fun: Fungible(amount) }, + dest, + }) + } + + fn transfer_multiasset( + _who: AccountId, + _asset: Asset, + _dest: Location, + _dest_weight_limit: WeightLimit, + ) -> Result, DispatchError> { + unimplemented!() + } + + fn transfer_with_fee( + _who: AccountId, + _currency_id: CurrencyId, + _amount: Balance, + _fee: Balance, + _dest: Location, + _dest_weight_limit: WeightLimit, + ) -> Result, DispatchError> { + unimplemented!() + } + + fn transfer_multiasset_with_fee( + _who: AccountId, + _asset: Asset, + _fee: Asset, + _dest: Location, + _dest_weight_limit: WeightLimit, + ) -> Result, DispatchError> { + unimplemented!() + } + + fn transfer_multicurrencies( + _who: AccountId, + _currencies: Vec<(CurrencyId, Balance)>, + _fee_item: u32, + _dest: Location, + _dest_weight_limit: WeightLimit, + ) -> Result, DispatchError> { + unimplemented!() + } + + fn transfer_multiassets( + _who: AccountId, + _assets: Assets, + _fee: Asset, + _dest: Location, + _dest_weight_limit: WeightLimit, + ) -> Result, DispatchError> { + unimplemented!() + } +} + +pub struct Weightless; +impl PreparedMessage for Weightless { + fn weight_of(&self) -> Weight { + Weight::default() + } +} + +pub struct MockXcmExecutor; +impl ExecuteXcm for MockXcmExecutor { + type Prepared = Weightless; + + fn prepare(_message: Xcm) -> Result> { + Ok(Weightless) + } + + fn execute( + _origin: impl Into, + _pre: Self::Prepared, + _hash: &mut XcmHash, + _weight_credit: Weight, + ) -> Outcome { + Outcome::Complete { used: Weight::default() } + } + + fn charge_fees(_location: impl Into, _fees: Assets) -> XcmResult { + Ok(()) + } +} + +impl XcmAssetTransfers for MockXcmExecutor { + type IsReserve = (); + type IsTeleporter = (); + type AssetTransactor = (); + + fn determine_for(_asset: &Asset, _dest: &Location) -> Result { + Ok(TransferType::DestinationReserve) + } +} diff --git a/primitives/src/time_unit.rs b/primitives/src/time_unit.rs new file mode 100644 index 000000000..8d6a5cafb --- /dev/null +++ b/primitives/src/time_unit.rs @@ -0,0 +1,102 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Low-level types used throughout the Bifrost code. + +use parity_scale_codec::MaxEncodedLen; +use scale_info::TypeInfo; +use sp_core::{Decode, Encode, RuntimeDebug}; + +// For vtoken-minting and slp modules +#[derive(Encode, Decode, Clone, RuntimeDebug, Eq, TypeInfo, MaxEncodedLen)] +pub enum TimeUnit { + // Kusama staking time unit + Era(#[codec(compact)] u32), + SlashingSpan(#[codec(compact)] u32), + // Moonriver staking time unit + Round(#[codec(compact)] u32), + // 1000 blocks. Can be used by Filecoin. + // 30 seconds per block. Kblock means 8.33 hours. + Kblock(#[codec(compact)] u32), + // 1 hour. Should be Unix Timstamp in seconds / 3600 + Hour(#[codec(compact)] u32), +} + +impl TimeUnit { + pub fn add_one(self) -> Self { + match self { + TimeUnit::Era(a) => TimeUnit::Era(a.saturating_add(1)), + TimeUnit::SlashingSpan(a) => TimeUnit::SlashingSpan(a.saturating_add(1)), + TimeUnit::Round(a) => TimeUnit::Round(a.saturating_add(1)), + TimeUnit::Kblock(a) => TimeUnit::Kblock(a.saturating_add(1)), + TimeUnit::Hour(a) => TimeUnit::Hour(a.saturating_add(1)), + } + } + + pub fn add(self, other_time: Self) -> Option { + match (self, other_time) { + (TimeUnit::Era(a), TimeUnit::Era(b)) => Some(TimeUnit::Era(a.saturating_add(b))), + _ => None, + } + } +} + +impl Default for TimeUnit { + fn default() -> Self { + TimeUnit::Era(0u32) + } +} + +impl PartialEq for TimeUnit { + fn eq(&self, other: &Self) -> bool { + match (&self, other) { + (Self::Era(a), Self::Era(b)) => a.eq(b), + (Self::SlashingSpan(a), Self::SlashingSpan(b)) => a.eq(b), + (Self::Round(a), Self::Round(b)) => a.eq(b), + (Self::Kblock(a), Self::Kblock(b)) => a.eq(b), + (Self::Hour(a), Self::Hour(b)) => a.eq(b), + _ => false, + } + } +} + +impl Ord for TimeUnit { + fn cmp(&self, other: &Self) -> sp_std::cmp::Ordering { + match (&self, other) { + (Self::Era(a), Self::Era(b)) => a.cmp(b), + (Self::SlashingSpan(a), Self::SlashingSpan(b)) => a.cmp(b), + (Self::Round(a), Self::Round(b)) => a.cmp(b), + (Self::Kblock(a), Self::Kblock(b)) => a.cmp(b), + (Self::Hour(a), Self::Hour(b)) => a.cmp(b), + _ => sp_std::cmp::Ordering::Less, + } + } +} + +impl PartialOrd for TimeUnit { + fn partial_cmp(&self, other: &Self) -> Option { + match (&self, other) { + (Self::Era(a), Self::Era(b)) => Some(a.cmp(b)), + (Self::SlashingSpan(a), Self::SlashingSpan(b)) => Some(a.cmp(b)), + (Self::Round(a), Self::Round(b)) => Some(a.cmp(b)), + (Self::Kblock(a), Self::Kblock(b)) => Some(a.cmp(b)), + (Self::Hour(a), Self::Hour(b)) => Some(a.cmp(b)), + _ => None, + } + } +} diff --git a/primitives/src/traits.rs b/primitives/src/traits.rs index 87a9d5727..99914216c 100644 --- a/primitives/src/traits.rs +++ b/primitives/src/traits.rs @@ -26,13 +26,14 @@ use crate::{ }; use frame_support::pallet_prelude::{DispatchResultWithPostInfo, Weight}; use parity_scale_codec::{Decode, Encode, FullCodec}; +use sp_core::U256; use sp_runtime::{ traits::{ AccountIdConversion, AtLeast32BitUnsigned, ConstU32, MaybeSerializeDeserialize, Zero, }, BoundedVec, DispatchError, DispatchResult, TokenError, TypeId, }; -use sp_std::{fmt::Debug, vec::Vec}; +use sp_std::{cmp::Ordering, fmt::Debug, vec::Vec}; pub trait TokenInfo { fn name(&self) -> Option<&str>; @@ -145,11 +146,7 @@ pub trait VtokenMintingOperator { currency_id: CurrencyId, index: u32, ) -> Option<(AccountId, Balance, TimeUnit, RedeemType)>; - fn get_astar_parachain_id() -> u32; fn get_moonbeam_parachain_id() -> u32; - fn get_hydradx_parachain_id() -> u32; - fn get_interlay_parachain_id() -> u32; - fn get_manta_parachain_id() -> u32; } /// Trait for Vtoken-Minting module to check whether accept redeeming or not. @@ -347,11 +344,7 @@ pub trait VtokenMintingInterface { fn token_id(vtoken_id: CurrencyId) -> Option; fn get_token_pool(currency_id: CurrencyId) -> Balance; fn get_minimums_redeem(vtoken_id: CurrencyId) -> Balance; - fn get_astar_parachain_id() -> u32; fn get_moonbeam_parachain_id() -> u32; - fn get_hydradx_parachain_id() -> u32; - fn get_interlay_parachain_id() -> u32; - fn get_manta_parachain_id() -> u32; } impl VtokenMintingInterface @@ -416,21 +409,9 @@ impl VtokenMintingInterface u32 { - 0 - } fn get_moonbeam_parachain_id() -> u32 { 0 } - fn get_hydradx_parachain_id() -> u32 { - 0 - } - fn get_interlay_parachain_id() -> u32 { - 0 - } - fn get_manta_parachain_id() -> u32 { - 0 - } } pub trait TryConvertFrom { @@ -554,13 +535,26 @@ impl SlpHostingFeeProvider { - fn get(a: &AccountId) -> CurrencyId; + type Error; + /// Retrieves the currency used to pay the transaction fee. + /// + /// This method returns the `CurrencyId` of the currency that will be used to pay the + /// transaction fee for the current transaction. It is useful for determining which currency + /// will be deducted to cover the cost of the transaction. + fn get_fee_currency(account: &AccountId, fee: U256) -> Result; } /// Provides account's balance of fee asset currency in a given currency pub trait AccountFeeCurrencyBalanceInCurrency { type Output; - fn get_balance_in_currency(to_currency: CurrencyId, account: &AccountId) -> Self::Output; + type Error; + + // This `fee` variable is used to determine the currency for paying transaction fees. + fn get_balance_in_currency( + to_currency: CurrencyId, + account: &AccountId, + fee: U256, + ) -> Result; } pub trait PriceProvider { @@ -568,3 +562,27 @@ pub trait PriceProvider { fn get_price(asset_a: CurrencyId, asset_b: CurrencyId) -> Option; } + +/// A trait for comparing the balance of a specific currency for a given account. +pub trait BalanceCmp { + type Error; + /// Compares the balance of the specified currency for the given account with + /// an input amount, considering the precision of both the currency and the amount. + /// + /// # Parameters + /// - `account`: The account ID whose balance is to be compared. + /// - `currency`: The currency ID whose balance is to be compared. + /// - `amount`: The amount to compare against. + /// - `amount_precision`: The precision of the input amount. + /// + /// # Returns + /// - `Ok(std::cmp::Ordering)`: The result of the comparison, indicating whether the balance is + /// less than, equal to, or greater than the input amount. + /// - `Err(Self::Error)`: An error if the comparison fails. + fn cmp_with_precision( + account: &AccountId, + currency: &CurrencyId, + amount: u128, + amount_precision: u32, + ) -> Result; +} diff --git a/primitives/src/xcm.rs b/primitives/src/xcm.rs new file mode 100644 index 000000000..dd3a742ac --- /dev/null +++ b/primitives/src/xcm.rs @@ -0,0 +1,123 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use crate::AccountId; +use frame_support::{ + parameter_types, + traits::{ContainsPair, Get}, +}; +use sp_runtime::traits::Convert; +use sp_std::marker::PhantomData; +use xcm::{ + latest::Asset, + prelude::{AccountId32, Ethereum, Fungible, GlobalConsensus, Parachain}, + v4::{AssetId, InteriorLocation, Location, NetworkId, Parent}, +}; + +// Parachain Id +parameter_types! { + pub const AssetHubChainId: u32 = 1000; + pub const AstarChainId: u32 = 2006; + pub const BifrostKusamaChainId: u32 = 2001; + pub const BifrostPolkadotChainId: u32 = 2030; + pub const BridgeHubChainId: u32 = 1002; + pub const HydrationChainId: u32 = 2034; + pub const InterlayChainId: u32 = 2032; + pub const MantaChainId: u32 = 2104; + pub const MoonbeamChainId: u32 = 2004; + pub const MoonriverChainId: u32 = 2023; + pub const EthereumChainId: u64 = 1; +} + +// Location +parameter_types! { + pub SelfLocation: Location = Location::here(); + pub AssetHubLocation: Location = Location::new(1, Parachain(AssetHubChainId::get())); + pub EthereumLocation: Location = Location::new(2, [GlobalConsensus(Ethereum { chain_id: EthereumChainId::get() })]); + + pub const KusamaNetwork: NetworkId = NetworkId::Kusama; + pub const PolkadotNetwork: NetworkId = NetworkId::Polkadot; + + pub KusamaUniversalLocation: InteriorLocation = [GlobalConsensus(KusamaNetwork::get()), Parachain(BifrostKusamaChainId::get())].into(); + pub PolkadotUniversalLocation: InteriorLocation = [GlobalConsensus(PolkadotNetwork::get()), Parachain(BifrostPolkadotChainId::get())].into(); +} + +/// Asset filter that allows all assets from a certain location matching asset id. +pub struct AssetPrefixFrom(PhantomData<(Prefix, Origin)>); +impl ContainsPair for AssetPrefixFrom +where + Prefix: Get, + Origin: Get, +{ + fn contains(asset: &Asset, origin: &Location) -> bool { + let loc = Origin::get(); + &loc == origin && + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } + if asset_loc.starts_with(&Prefix::get())) + } +} + +/// Asset filter that allows native/relay asset if coming from a certain location. +pub struct NativeAssetFrom(PhantomData); +impl> ContainsPair for NativeAssetFrom { + fn contains(asset: &Asset, origin: &Location) -> bool { + let loc = T::get(); + &loc == origin && + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } + if *asset_loc == Location::from(Parent)) + } +} + +/// Convert AccountId to Location +pub struct AccountIdToLocation; +impl Convert for AccountIdToLocation { + fn convert(account: AccountId) -> Location { + Location::new(0, [AccountId32 { network: None, id: account.into() }]) + } +} + +#[cfg(test)] +mod test { + use super::*; + use xcm::v4::Junctions; + + #[test] + fn parachain_location() { + let assethub_location: Location = (Parent, Parachain(1000)).into(); + assert_eq!(assethub_location, Location::new(1, Parachain(1000))); + } + + #[test] + fn bifrost_account_to_location() { + let account: AccountId = AccountId::new([0u8; 32]); + let location: Location = AccountIdToLocation::convert(account); + assert_eq!(location, Location::new(0, [AccountId32 { network: None, id: [0u8; 32] }])); + } + + #[test] + fn universal_location() { + assert_eq!( + KusamaUniversalLocation::get(), + Junctions::X2([GlobalConsensus(NetworkId::Kusama), Parachain(2001)].into()) + ); + assert_eq!( + PolkadotUniversalLocation::get(), + Junctions::X2([GlobalConsensus(NetworkId::Polkadot), Parachain(2030)].into()) + ); + } +} diff --git a/runtime/bifrost-kusama/Cargo.toml b/runtime/bifrost-kusama/Cargo.toml index 3e93f2e4d..0f18e7357 100644 --- a/runtime/bifrost-kusama/Cargo.toml +++ b/runtime/bifrost-kusama/Cargo.toml @@ -46,6 +46,7 @@ pallet-proxy = { workspace = true } pallet-ranked-collective = { workspace = true } pallet-referenda = { workspace = true } pallet-scheduler = { workspace = true } +pallet-staking = { workspace = true } pallet-session = { workspace = true } pallet-timestamp = { workspace = true } pallet-tips = { workspace = true } @@ -145,6 +146,7 @@ pallet-prices = { workspace = true } leverage-staking = { workspace = true } bifrost-channel-commission = { workspace = true } bifrost-vtoken-minting-rpc-runtime-api = { workspace = true } +bifrost-vbnc-convert = { workspace = true } [build-dependencies] substrate-wasm-builder = { workspace = true, optional = true } @@ -271,6 +273,7 @@ std = [ "bifrost-parachain-staking/std", "bifrost-xcm-interface/std", "bifrost-channel-commission/std", + "bifrost-vbnc-convert/std", "substrate-wasm-builder" ] @@ -289,6 +292,7 @@ runtime-benchmarks = [ "pallet-indices/runtime-benchmarks", "pallet-ranked-collective/runtime-benchmarks", "pallet-referenda/runtime-benchmarks", + "pallet-staking/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", @@ -321,6 +325,7 @@ runtime-benchmarks = [ "lend-market/runtime-benchmarks", "leverage-staking/runtime-benchmarks", "bifrost-channel-commission/runtime-benchmarks", + "bifrost-vbnc-convert/runtime-benchmarks", ] try-runtime = [ @@ -393,6 +398,7 @@ try-runtime = [ "bifrost-vtoken-voting/try-runtime", "leverage-staking/try-runtime", "bifrost-channel-commission/try-runtime", + "bifrost-vbnc-convert/try-runtime", ] # Enable the metadata hash generation in the wasm builder. diff --git a/runtime/bifrost-kusama/src/lib.rs b/runtime/bifrost-kusama/src/lib.rs index a0c7eded8..ee116c46a 100644 --- a/runtime/bifrost-kusama/src/lib.rs +++ b/runtime/bifrost-kusama/src/lib.rs @@ -87,6 +87,7 @@ pub use bifrost_runtime_common::{ use bifrost_slp::QueryId; use constants::currency::*; use cumulus_pallet_parachain_system::{RelayNumberStrictlyIncreases, RelaychainDataProvider}; +use cumulus_primitives_core::AggregateMessageOrigin; use frame_support::{ dispatch::DispatchClass, genesis_builder_helper::{build_state, get_preset}, @@ -121,13 +122,14 @@ use governance::{ // xcm config pub mod xcm_config; +use bifrost_primitives::MoonriverChainId; +use bifrost_runtime_common::currency_converter::CurrencyIdConvert; use pallet_xcm::{EnsureResponse, QueryStatus}; use sp_runtime::traits::{IdentityLookup, Verify}; use xcm::{v3::MultiLocation, v4::prelude::*}; pub use xcm_config::{ - parachains, AccountId32Aliases, BifrostCurrencyIdConvert, BifrostTreasuryAccount, - ExistentialDeposits, MultiCurrency, SelfParaChainId, Sibling, SiblingParachainConvertsVia, - XcmConfig, XcmRouter, + parachains, AccountId32Aliases, BifrostTreasuryAccount, ExistentialDeposits, MultiCurrency, + Sibling, SiblingParachainConvertsVia, XcmConfig, XcmRouter, }; use xcm_executor::{traits::QueryHandler, XcmExecutor}; @@ -143,7 +145,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("bifrost"), impl_name: create_runtime_str!("bifrost"), authoring_version: 1, - spec_version: 12000, + spec_version: 13000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -231,6 +233,7 @@ parameter_types! { pub IncentivePoolAccount: PalletId = PalletId(*b"bf/inpoo"); pub const FarmingGaugeRewardIssuerPalletId: PalletId = PalletId(*b"bf/fmgar"); pub const FlexibleFeePalletId: PalletId = PalletId(*b"bf/flexi"); + pub const VBNCConvertPalletId: PalletId = PalletId(*b"bf/vbncc"); } impl frame_system::Config for Runtime { @@ -867,10 +870,11 @@ where parameter_types! { pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); + pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent; } impl cumulus_pallet_parachain_system::Config for Runtime { - type DmpQueue = frame_support::traits::EnqueueWithOrigin; + type DmpQueue = frame_support::traits::EnqueueWithOrigin; type RuntimeEvent = RuntimeEvent; type OnSystemEvent = (); type OutboundXcmpMessageSource = XcmpQueue; @@ -938,8 +942,7 @@ parameter_types! { impl bifrost_parachain_staking::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; - type MonetaryGovernanceOrigin = - EitherOfDiverse; + type MonetaryGovernanceOrigin = TechAdminOrCouncil; type MinBlocksPerRound = MinBlocksPerRound; type DefaultBlocksPerRound = DefaultBlocksPerRound; type LeaveCandidatesDelay = LeaveCandidatesDelay; @@ -1126,7 +1129,7 @@ pub fn create_x2_multilocation(index: u16, currency_id: CurrencyId) -> xcm::v3:: _ => { // get parachain id if let Some(location) = - BifrostCurrencyIdConvert::::convert(currency_id) + CurrencyIdConvert::::convert(currency_id) { if let Some(Parachain(para_id)) = location.interior().first() { xcm::v3::Location::new( @@ -1220,13 +1223,13 @@ impl bifrost_vsbond_auction::Config for Runtime { type WeightInfo = weights::bifrost_vsbond_auction::BifrostWeight; type PalletId = VsbondAuctionPalletId; type TreasuryAccount = BifrostTreasuryAccount; - type ControlOrigin = EitherOfDiverse; + type ControlOrigin = TechAdminOrCouncil; } impl bifrost_token_issuer::Config for Runtime { type RuntimeEvent = RuntimeEvent; type MultiCurrency = Currencies; - type ControlOrigin = EitherOfDiverse; + type ControlOrigin = TechAdminOrCouncil; type WeightInfo = weights::bifrost_token_issuer::BifrostWeight; type MaxLengthLimit = MaxLengthLimit; } @@ -1290,7 +1293,7 @@ impl bifrost_slp::Config for Runtime { type WeightInfo = weights::bifrost_slp::BifrostWeight; type VtokenMinting = VtokenMinting; type AccountConverter = SubAccountIndexMultiLocationConvertor; - type ParachainId = SelfParaChainId; + type ParachainId = ParachainInfo; type SubstrateResponseManager = SubstrateResponseManager; type MaxTypeEntryPerBlock = MaxTypeEntryPerBlock; type MaxRefundPerBlock = MaxRefundPerBlock; @@ -1329,7 +1332,7 @@ impl bifrost_farming::Config for Runtime { type RewardIssuer = FarmingRewardIssuerPalletId; type WeightInfo = weights::bifrost_farming::BifrostWeight; type FarmingBoost = FarmingBoostPalletId; - type VeMinting = (); + type BbBNC = (); type BlockNumberToBalance = ConvertInto; type WhitelistMaximumLimit = WhitelistMaximumLimit; type GaugeRewardIssuer = FarmingGaugeRewardIssuerPalletId; @@ -1358,7 +1361,7 @@ impl bifrost_system_staking::Config for Runtime { impl bifrost_system_maker::Config for Runtime { type RuntimeEvent = RuntimeEvent; type MultiCurrency = Currencies; - type ControlOrigin = EitherOfDiverse; + type ControlOrigin = TechAdminOrCouncil; type WeightInfo = weights::bifrost_system_maker::BifrostWeight; type DexOperator = ZenlinkProtocol; type CurrencyIdConversion = AssetIdMaps; @@ -1375,6 +1378,7 @@ impl bifrost_fee_share::Config for Runtime { type ControlOrigin = CoreAdminOrCouncil; type WeightInfo = weights::bifrost_fee_share::BifrostWeight; type FeeSharePalletId = FeeSharePalletId; + type PriceFeeder = Prices; } impl bifrost_cross_in_out::Config for Runtime { @@ -1409,7 +1413,7 @@ impl bifrost_vtoken_voting::Config for Runtime { type DerivativeAccount = DerivativeAccountProvider; type RelaychainBlockNumberProvider = RelaychainDataProvider; type VTokenSupplyProvider = VtokenMinting; - type ParachainId = SelfParaChainId; + type ParachainId = ParachainInfo; type MaxVotes = ConstU32<256>; type QueryTimeout = QueryTimeout; type ReferendumCheckInterval = ReferendumCheckInterval; @@ -1541,15 +1545,11 @@ impl bifrost_vtoken_minting::Config for Runtime { type CurrencyIdConversion = AssetIdMaps; type CurrencyIdRegister = AssetIdMaps; type XcmTransfer = XTokens; - type AstarParachainId = ConstU32<2007>; - type MoonbeamParachainId = ConstU32<2023>; - type HydradxParachainId = ConstU32<2034>; - type MantaParachainId = ConstU32<2104>; - type InterlayParachainId = ConstU32<2092>; + type MoonbeamChainId = MoonriverChainId; type ChannelCommission = ChannelCommission; type MaxLockRecords = ConstU32<100>; type IncentivePoolAccount = IncentivePoolAccount; - type VeMinting = (); + type BbBNC = (); type AssetIdMaps = AssetIdMaps; } @@ -1564,7 +1564,7 @@ impl bifrost_slpx::Config for Runtime { type XcmSender = XcmRouter; type CurrencyIdConvert = AssetIdMaps; type TreasuryAccount = BifrostTreasuryAccount; - type ParachainId = SelfParaChainId; + type ParachainId = ParachainInfo; type WeightInfo = weights::bifrost_slpx::BifrostWeight; } @@ -1588,7 +1588,7 @@ impl bifrost_stable_asset::Config for Runtime { type PoolAssetLimit = ConstU32<5>; type SwapExactOverAmount = ConstU128<100>; type WeightInfo = (); - type ListingOrigin = EitherOfDiverse; + type ListingOrigin = TechAdminOrCouncil; type EnsurePoolAssetId = EnsurePoolAssetId; } @@ -1662,8 +1662,8 @@ impl DataFeeder for AggregatedDataProvi impl pallet_prices::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Source = AggregatedDataProvider; - type FeederOrigin = EitherOfDiverse; - type UpdateOrigin = EitherOfDiverse; + type FeederOrigin = TechAdminOrCouncil; + type UpdateOrigin = TechAdminOrCouncil; type RelayCurrency = RelayCurrencyId; type CurrencyIdConvert = AssetIdMaps; type Assets = Currencies; @@ -1727,6 +1727,13 @@ impl bifrost_channel_commission::Config for Runtime { type NameLengthLimit = NameLengthLimit; } +impl bifrost_vbnc_convert::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type MultiCurrency = Currencies; + type VBNCConvertPalletId = VBNCConvertPalletId; + type WeightInfo = weights::bifrost_vbnc_convert::BifrostWeight; +} + // Below is the implementation of tokens manipulation functions other than native token. pub struct LocalAssetAdaptor(PhantomData); @@ -1877,7 +1884,7 @@ construct_runtime! { // Third party modules XTokens: orml_xtokens = 70, Tokens: orml_tokens = 71, - Currencies: bifrost_currencies = 72, + Currencies: bifrost_currencies exclude_parts { Call } = 72, UnknownTokens: orml_unknown_tokens = 73, OrmlXcm: orml_xcm = 74, ZenlinkProtocol: zenlink_protocol = 80, @@ -1912,6 +1919,7 @@ construct_runtime! { OracleMembership: pallet_membership:: = 134, LeverageStaking: leverage_staking = 135, ChannelCommission: bifrost_channel_commission = 136, + VBNCConvert: bifrost_vbnc_convert = 140, } } @@ -1953,10 +1961,6 @@ pub type CheckedExtrinsic = generic::CheckedExtrinsic; -parameter_types! { - pub const CallSwitchgearPalletName: &'static str = "CallSwitchgear"; -} - impl cumulus_pallet_xcmp_queue::migration::v5::V5Config for Runtime { // This must be the same as the `ChannelInfo` from the `Config`: type ChannelList = ParachainSystem; @@ -1977,15 +1981,6 @@ pub mod migrations { pub type Unreleased = ( // permanent migration, do not remove pallet_xcm::migration::MigrateToLatestXcmVersion, - frame_support::migrations::RemovePallet< - CallSwitchgearPalletName, - ::DbWeight, - >, - cumulus_pallet_xcmp_queue::migration::v5::MigrateV4ToV5, - crate::migration::opengov::RankedCollectiveV1< - Runtime, - governance::fellowship::FellowshipCollectiveInstance, - >, ); } @@ -2024,6 +2019,7 @@ mod benches { [bifrost_vtoken_voting, VtokenVoting] [lend_market, LendMarket] [leverage_staking, LeverageStaking] + [bifrost_vbnc_convert, VBNCConvert] // [bifrost_channel_commission, ChannelCommission] ); } diff --git a/runtime/bifrost-kusama/src/weights/bifrost_fee_share.rs b/runtime/bifrost-kusama/src/weights/bifrost_fee_share.rs index 2050da409..1e2478564 100644 --- a/runtime/bifrost-kusama/src/weights/bifrost_fee_share.rs +++ b/runtime/bifrost-kusama/src/weights/bifrost_fee_share.rs @@ -127,4 +127,18 @@ impl bifrost_fee_share::WeightInfo for BifrostWeight .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `FeeShare::DistributionInfos` (r:1 w:0) + /// Proof: `FeeShare::DistributionInfos` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `FeeShare::DollarStandardInfos` (r:0 w:1) + /// Proof: `FeeShare::DollarStandardInfos` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn set_usd_config() -> Weight { + // Proof Size summary in bytes: + // Measured: `94` + // Estimated: `3559` + // Minimum execution time: 9_077_000 picoseconds. + Weight::from_parts(9_408_000, 0) + .saturating_add(Weight::from_parts(0, 3559)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/runtime/bifrost-kusama/src/weights/bifrost_slpx.rs b/runtime/bifrost-kusama/src/weights/bifrost_slpx.rs index 5cc4a3e80..cc9f6ce45 100644 --- a/runtime/bifrost-kusama/src/weights/bifrost_slpx.rs +++ b/runtime/bifrost-kusama/src/weights/bifrost_slpx.rs @@ -127,18 +127,36 @@ impl bifrost_slpx::WeightInfo for BifrostWeight { .saturating_add(T::DbWeight::get().reads(16)) .saturating_add(T::DbWeight::get().writes(8)) } - // Storage: `Slpx::WhitelistAccountId` (r:1 w:0) - // Proof: `Slpx::WhitelistAccountId` (`max_values`: None, `max_size`: Some(338), added: 2813, mode: `MaxEncodedLen`) - // Storage: `Slpx::OrderQueue` (r:1 w:1) - // Proof: `Slpx::OrderQueue` (`max_values`: Some(1), `max_size`: Some(203002), added: 203497, mode: `MaxEncodedLen`) + // Storage: Slpx WhitelistAccountId (r:1 w:0) + // Proof: Slpx WhitelistAccountId (max_values: None, max_size: Some(338), added: 2813, mode: MaxEncodedLen) + // Storage: Tokens Accounts (r:4 w:4) + // Proof: Tokens Accounts (max_values: None, max_size: Some(118), added: 2593, mode: MaxEncodedLen) + // Storage: Slpx ExecutionFee (r:1 w:0) + // Proof: Slpx ExecutionFee (max_values: None, max_size: Some(46), added: 2521, mode: MaxEncodedLen) + // Storage: AssetRegistry CurrencyMetadatas (r:1 w:0) + // Proof Skipped: AssetRegistry CurrencyMetadatas (max_values: None, max_size: None, mode: Measured) + // Storage: System Account (r:3 w:2) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + // Storage: VtokenMinting MinimumMint (r:1 w:0) + // Proof: VtokenMinting MinimumMint (max_values: None, max_size: Some(38), added: 2513, mode: MaxEncodedLen) + // Storage: VtokenMinting TokenPool (r:1 w:1) + // Proof: VtokenMinting TokenPool (max_values: None, max_size: Some(38), added: 2513, mode: MaxEncodedLen) + // Storage: Tokens TotalIssuance (r:1 w:1) + // Proof: Tokens TotalIssuance (max_values: None, max_size: Some(38), added: 2513, mode: MaxEncodedLen) + // Storage: VtokenMinting Fees (r:1 w:0) + // Proof: VtokenMinting Fees (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + // Storage: AssetRegistry CurrencyIdToLocations (r:1 w:0) + // Proof Skipped: AssetRegistry CurrencyIdToLocations (max_values: None, max_size: None, mode: Measured) + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) fn mint_with_channel_id() -> Weight { // Proof Size summary in bytes: - // Measured: `81` - // Estimated: `204487` - // Minimum execution time: 12_000 nanoseconds. - Weight::from_parts(13_000_000, 204487) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `2442` + // Estimated: `11362` + // Minimum execution time: 355_230 nanoseconds. + Weight::from_parts(360_766_000, 11362) + .saturating_add(T::DbWeight::get().reads(16)) + .saturating_add(T::DbWeight::get().writes(8)) } // Storage: Slpx WhitelistAccountId (r:1 w:0) // Proof: Slpx WhitelistAccountId (max_values: None, max_size: Some(338), added: 2813, mode: MaxEncodedLen) diff --git a/runtime/bifrost-kusama/src/weights/bifrost_vbnc_convert.rs b/runtime/bifrost-kusama/src/weights/bifrost_vbnc_convert.rs new file mode 100644 index 000000000..ec0b1fd20 --- /dev/null +++ b/runtime/bifrost-kusama/src/weights/bifrost_vbnc_convert.rs @@ -0,0 +1,89 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Autogenerated weights for bifrost_vbnc_convert +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-09-05, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! HOSTNAME: `suntiebingdeMacBook-Pro.local`, CPU: `` +//! WASM-EXECUTION: Compiled, CHAIN: Some("bifrost-kusama-local"), DB CACHE: 1024 + +// Executed Command: +// target/release/bifrost +// benchmark +// pallet +// --chain=bifrost-kusama-local +// --steps=50 +// --repeat=20 +// --pallet=bifrost_vbnc_convert +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./runtime/bifrost-kusama/src/weights/bifrost_vbnc_convert.rs +// --template=./weight-template/runtime-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions for bifrost_vbnc_convert. +pub struct BifrostWeight(PhantomData); +impl bifrost_vbnc_convert::WeightInfo for BifrostWeight { + // Storage: `Tokens::Accounts` (r:3 w:3) + // Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(118), added: 2593, mode: `MaxEncodedLen`) + // Storage: `AssetRegistry::CurrencyMetadatas` (r:2 w:0) + // Proof: `AssetRegistry::CurrencyMetadatas` (`max_values`: None, `max_size`: None, mode: `Measured`) + // Storage: `System::Account` (r:1 w:1) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + // Storage: `Tokens::TotalIssuance` (r:1 w:1) + // Proof: `Tokens::TotalIssuance` (`max_values`: None, `max_size`: Some(38), added: 2513, mode: `MaxEncodedLen`) + fn convert_to_vbnc_p() -> Weight { + // Proof Size summary in bytes: + // Measured: `980` + // Estimated: `8769` + // Minimum execution time: 67_000 nanoseconds. + Weight::from_parts(68_000_000, 8769) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(5)) + } + // Storage: `Tokens::Accounts` (r:2 w:2) + // Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(118), added: 2593, mode: `MaxEncodedLen`) + // Storage: `AssetRegistry::CurrencyMetadatas` (r:1 w:0) + // Proof: `AssetRegistry::CurrencyMetadatas` (`max_values`: None, `max_size`: None, mode: `Measured`) + // Storage: `System::Account` (r:1 w:1) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn charge_vbnc_p() -> Weight { + // Proof Size summary in bytes: + // Measured: `712` + // Estimated: `6176` + // Minimum execution time: 41_000 nanoseconds. + Weight::from_parts(42_000_000, 6176) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/runtime/bifrost-kusama/src/weights/mod.rs b/runtime/bifrost-kusama/src/weights/mod.rs index 9782e1bcc..41bea25e1 100644 --- a/runtime/bifrost-kusama/src/weights/mod.rs +++ b/runtime/bifrost-kusama/src/weights/mod.rs @@ -34,6 +34,7 @@ pub mod bifrost_stable_pool; pub mod bifrost_system_maker; pub mod bifrost_system_staking; pub mod bifrost_token_issuer; +pub mod bifrost_vbnc_convert; pub mod bifrost_vesting; pub mod bifrost_vsbond_auction; pub mod bifrost_vstoken_conversion; diff --git a/runtime/bifrost-kusama/src/xcm_config.rs b/runtime/bifrost-kusama/src/xcm_config.rs index dbfec5ce6..c56411628 100644 --- a/runtime/bifrost-kusama/src/xcm_config.rs +++ b/runtime/bifrost-kusama/src/xcm_config.rs @@ -18,17 +18,17 @@ use super::*; use bifrost_asset_registry::{AssetIdMaps, FixedRateOfAsset}; -use bifrost_primitives::{AccountId, CurrencyId, CurrencyIdMapping, TokenSymbol}; +use bifrost_primitives::{ + AccountId, AccountIdToLocation, AssetHubLocation, AssetPrefixFrom, CurrencyId, + CurrencyIdMapping, EthereumLocation, KusamaNetwork, KusamaUniversalLocation, NativeAssetFrom, + SelfLocation, TokenSymbol, +}; pub use bifrost_xcm_interface::traits::{parachains, XcmBaseWeight}; pub use cumulus_primitives_core::ParaId; -use frame_support::{ - ensure, parameter_types, - sp_runtime::traits::{CheckedConversion, Convert}, - traits::Get, -}; -use parity_scale_codec::{Decode, Encode}; +use frame_support::{parameter_types, sp_runtime::traits::Convert, traits::Get}; +use parity_scale_codec::Encode; pub use polkadot_parachain_primitives::primitives::Sibling; -use sp_std::{convert::TryFrom, marker::PhantomData}; +use sp_std::convert::TryFrom; pub use xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, DescribeAllTerminal, DescribeFamily, EnsureXcmOrigin, @@ -37,211 +37,39 @@ pub use xcm_builder::{ SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeRevenue, TakeWeightCredit, }; -use xcm_executor::traits::{MatchesFungible, ShouldExecute}; // orml imports use bifrost_currencies::BasicCurrencyAdapter; -use bifrost_runtime_common::currency_adapter::{ - BifrostDropAssets, DepositToAlternative, MultiCurrencyAdapter, -}; -use cumulus_primitives_core::{AggregateMessageOrigin, ParaId as CumulusParaId}; -use frame_support::traits::{ContainsPair, ProcessMessageError, TransformOrigin}; -use orml_traits::{ - currency::MutationHooks, - location::{RelativeReserveProvider, Reserve}, +use bifrost_runtime_common::{ + currency_adapter::{BifrostDropAssets, DepositToAlternative, MultiCurrencyAdapter}, + currency_converter::CurrencyIdConvert, }; +use cumulus_primitives_core::AggregateMessageOrigin; +use frame_support::traits::TransformOrigin; +use orml_traits::{currency::MutationHooks, location::RelativeReserveProvider}; pub use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key, MultiCurrency}; +use orml_xcm_support::{IsNativeConcrete, MultiNativeAsset}; use pallet_xcm::XcmPassthrough; use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling}; use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery; use sp_core::bounded::BoundedVec; use xcm::v4::{prelude::*, Location}; -use xcm_builder::{FrameTransactionalProcessor, TrailingSetTopicAsId}; -use xcm_executor::traits::Properties; - -/// Bifrost Asset Matcher -pub struct BifrostAssetMatcher( - PhantomData<(CurrencyId, CurrencyIdConvert)>, -); - -impl MatchesFungible - for BifrostAssetMatcher -where - CurrencyIdConvert: Convert>, - Amount: TryFrom, -{ - fn matches_fungible(a: &Asset) -> Option { - if let (Fungible(ref amount), AssetId(ref location)) = (&a.fun, &a.id) { - if CurrencyIdConvert::convert(location.clone()).is_some() { - return CheckedConversion::checked_from(*amount); - } - } - None - } -} - -/// A `FilterAssetLocation` implementation. Filters multi native assets whose -/// reserve is same with `origin`. -pub struct MultiNativeAsset(PhantomData); -impl ContainsPair for MultiNativeAsset -where - ReserveProvider: Reserve, -{ - fn contains(asset: &Asset, origin: &Location) -> bool { - if let Some(ref reserve) = ReserveProvider::reserve(asset) { - if reserve == origin { - return true; - } - } - false - } -} - -fn native_currency_location(id: CurrencyId) -> Location { - Location::new(0, [Junction::from(BoundedVec::try_from(id.encode()).unwrap())]) -} - -impl> Convert> for BifrostCurrencyIdConvert { - fn convert(asset: Asset) -> Option { - if let Asset { id: AssetId(id), fun: xcm::v4::Fungibility::Fungible(_) } = asset { - Self::convert(id) - } else { - None - } - } -} - -pub struct BifrostAccountIdToLocation; -impl Convert for BifrostAccountIdToLocation { - fn convert(account: AccountId) -> Location { - [AccountId32 { network: None, id: account.into() }].into() - } -} - -pub struct BifrostCurrencyIdConvert(sp_std::marker::PhantomData); -impl> Convert> for BifrostCurrencyIdConvert { - fn convert(id: CurrencyId) -> Option { - use CurrencyId::*; - use TokenSymbol::*; - - if let Some(id) = AssetIdMaps::::get_location(id) { - return Some(id); - } - - match id { - Token(KSM) => Some(Location::parent()), - Native(ASG) | Native(BNC) | VSToken(KSM) | Token(ZLK) => - Some(native_currency_location(id)), - // Karura currencyId types - Token(KAR) => Some(Location::new( - 1, - [ - Parachain(parachains::karura::ID), - Junction::from( - BoundedVec::try_from(parachains::karura::KAR_KEY.to_vec()).unwrap(), - ), - ], - )), - Stable(KUSD) => Some(Location::new( - 1, - [ - Parachain(parachains::karura::ID), - Junction::from( - BoundedVec::try_from(parachains::karura::KUSD_KEY.to_vec()).unwrap(), - ), - ], - )), - Token(RMRK) => Some(Location::new( - 1, - [ - Parachain(parachains::Statemine::ID), - PalletInstance(parachains::Statemine::PALLET_ID), - GeneralIndex(parachains::Statemine::RMRK_ID as u128), - ], - )), - // Phala Native token - Token(PHA) => Some(Location::new(1, [Parachain(parachains::phala::ID)])), - // Moonriver Native token - Token(MOVR) => Some(Location::new( - 1, - [ - Parachain(parachains::moonriver::ID), - PalletInstance(parachains::moonriver::PALLET_ID.into()), - ], - )), - _ => None, - } - } -} - -impl> Convert> for BifrostCurrencyIdConvert { - fn convert(location: Location) -> Option { - use CurrencyId::*; - use TokenSymbol::*; - - if location == Location::parent() { - return Some(Token(KSM)); - } - - if let Some(currency_id) = AssetIdMaps::::get_currency_id(location.clone()) { - return Some(currency_id); - } - - match location.unpack() { - (1, [Parachain(id), GeneralKey { data, length }]) if *id == parachains::karura::ID => - if data[..*length as usize] == parachains::karura::KAR_KEY.to_vec() { - Some(Token(KAR)) - } else if data[..*length as usize] == parachains::karura::KUSD_KEY.to_vec() { - Some(Stable(KUSD)) - } else { - None - }, - (1, [Parachain(id), GeneralIndex(key)]) if *id == parachains::Statemine::ID => { - if *key == parachains::Statemine::RMRK_ID as u128 { - Some(Token(RMRK)) - } else { - None - } - }, - (1, [Parachain(id), PalletInstance(index), GeneralIndex(key)]) - if (*id == parachains::Statemine::ID && - *index == parachains::Statemine::PALLET_ID) => - { - if *key == parachains::Statemine::RMRK_ID as u128 { - Some(Token(RMRK)) - } else { - None - } - }, - (1, [Parachain(id)]) if *id == parachains::phala::ID => Some(Token(PHA)), - (1, [Parachain(id), PalletInstance(index)]) - if (*id == parachains::moonriver::ID) && - (*index == parachains::moonriver::PALLET_ID) => - Some(Token(MOVR)), - (0, [GeneralKey { data, length }]) => { - // decode the general key - let key = &data[..*length as usize]; - if let Ok(currency_id) = CurrencyId::decode(&mut &key[..]) { - match currency_id { - Native(ASG) | Native(BNC) | VToken(KSM) | VSToken(KSM) | Token(ZLK) => - Some(currency_id), - _ => None, - } - } else { - None - } - }, - _ => None, - } - } -} +use xcm_builder::{FrameTransactionalProcessor, TrailingSetTopicAsId, WithComputedOrigin}; parameter_types! { - pub const KsmLocation: Location = Location::parent(); - pub const RelayNetwork: NetworkId = Kusama; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub SelfParaChainId: CumulusParaId = ParachainInfo::parachain_id(); - pub UniversalLocation: InteriorLocation = [GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())].into(); + // Maximum weight assigned to MessageQueue pallet to execute messages when the block is on_initialize + pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; + // Maximum weight assigned to MessageQueue pallet to execute messages when the block is on_idle + pub MessageQueueIdleServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; + // XTokens pallet BaseXcmWeight, Actually weight for an XCM message is `T::BaseXcmWeight + T::Weigher::weight(&msg)`. + pub const BaseXcmWeight: Weight = Weight::from_parts(1000_000_000u64, 0); + // XTokens pallet supports maximum number of assets to be transferred at a time + pub const MaxAssetsForTransfer: usize = 2; + // One XCM operation is 200_000_000 weight, cross-chain transfer ~= 2x of transfer = 3_000_000_000 + pub const UnitWeightCost: Weight = Weight::from_parts(200_000_000, 0); + // Maximum number of instructions that can be executed in one XCM message + pub const MaxInstructions: u32 = 100; } /// Type for specifying how a `Location` can be converted into an `AccountId`. This is used @@ -253,7 +81,7 @@ pub type LocationToAccountId = ( // Sibling parachain origins convert to AccountId via the `ParaId::into`. SiblingParachainConvertsVia, // Straight up local `AccountId32` origins just alias directly to `AccountId`. - AccountId32Aliases, + AccountId32Aliases, // Foreign locations alias into accounts according to a hash of their standard description. HashedDescription>, ); @@ -277,95 +105,36 @@ pub type XcmOriginToTransactDispatchOrigin = ( ParentAsSuperuser, // Native signed account converter; this just converts an `AccountId32` origin into a normal // `RuntimeOrigin::Signed` origin of the same 32-byte value. - SignedAccountId32AsNative, + SignedAccountId32AsNative, // Xcm origins can be represented natively under the Xcm pallet's Xcm origin. XcmPassthrough, ); -parameter_types! { - // One XCM operation is 200_000_000 weight, cross-chain transfer ~= 2x of transfer = 3_000_000_000 - pub UnitWeightCost: Weight = Weight::from_parts(200_000_000, 0); - pub const MaxInstructions: u32 = 100; -} - -/// Barrier allowing a top level paid message with DescendOrigin instruction -pub const DEFAULT_PROOF_SIZE: u64 = 64 * 1024; -pub const DEFAULT_REF_TIMR: u64 = 10_000_000_000; -pub struct AllowTopLevelPaidExecutionDescendOriginFirst(PhantomData); -impl> ShouldExecute for AllowTopLevelPaidExecutionDescendOriginFirst { - fn should_execute( - origin: &Location, - message: &mut [Instruction], - max_weight: Weight, - _weight_credit: &mut Properties, - ) -> Result<(), ProcessMessageError> { - log::trace!( - target: "xcm::barriers", - "AllowTopLevelPaidExecutionDescendOriginFirst origin: - {:?}, message: {:?}, max_weight: {:?}, weight_credit: {:?}", - origin, message, max_weight, _weight_credit, - ); - ensure!(T::contains(origin), ProcessMessageError::Unsupported); - let mut iter = message.iter_mut(); - // Make sure the first instruction is DescendOrigin - iter.next() - .filter(|instruction| matches!(instruction, DescendOrigin(_))) - .ok_or(ProcessMessageError::Unsupported)?; - - // Then WithdrawAsset - iter.next() - .filter(|instruction| matches!(instruction, WithdrawAsset(_))) - .ok_or(ProcessMessageError::Unsupported)?; - - // Then BuyExecution - let i = iter.next().ok_or(ProcessMessageError::Unsupported)?; - match i { - BuyExecution { weight_limit: Limited(ref mut weight), .. } => { - if weight.all_gte(max_weight) { - weight.set_ref_time(max_weight.ref_time()); - weight.set_proof_size(max_weight.proof_size()); - }; - }, - BuyExecution { ref mut weight_limit, .. } if weight_limit == &Unlimited => { - *weight_limit = Limited(max_weight); - }, - _ => {}, - }; - - // Then Transact - let i = iter.next().ok_or(ProcessMessageError::Unsupported)?; - match i { - Transact { ref mut require_weight_at_most, .. } => { - let weight = Weight::from_parts(DEFAULT_REF_TIMR, DEFAULT_PROOF_SIZE); - *require_weight_at_most = weight; - Ok(()) - }, - _ => Err(ProcessMessageError::Unsupported), - } - } -} - pub type Barrier = TrailingSetTopicAsId<( // Weight that is paid for may be consumed. TakeWeightCredit, // Expected responses are OK. AllowKnownQueryResponses, - // If the message is one that immediately attemps to pay for execution, then allow it. - AllowTopLevelPaidExecutionFrom, - // Subscriptions for version tracking are OK. - AllowSubscriptionsFrom, - // Barrier allowing a top level paid message with DescendOrigin instruction - AllowTopLevelPaidExecutionDescendOriginFirst, + WithComputedOrigin< + ( + // If the message is one that immediately attemps to pay for execution, then allow it. + AllowTopLevelPaidExecutionFrom, + // Subscriptions for version tracking are OK. + AllowSubscriptionsFrom, + ), + KusamaUniversalLocation, + ConstU32<8>, + >, )>; pub type BifrostAssetTransactor = MultiCurrencyAdapter< Currencies, UnknownTokens, - BifrostAssetMatcher>, + IsNativeConcrete>, AccountId, LocationToAccountId, CurrencyId, - BifrostCurrencyIdConvert, + CurrencyIdConvert, DepositToAlternative, >; @@ -494,11 +263,9 @@ parameter_types! { pub struct ToTreasury; impl TakeRevenue for ToTreasury { fn take_revenue(revenue: Asset) { - if let Asset { id: AssetId(location), fun: xcm::v4::Fungibility::Fungible(amount) } = - revenue - { + if let Asset { id: AssetId(location), fun: Fungible(amount) } = revenue { if let Some(currency_id) = - BifrostCurrencyIdConvert::::convert(location) + CurrencyIdConvert::::convert(location) { let _ = Currencies::deposit(currency_id, &BifrostTreasuryAccount::get(), amount); } @@ -629,38 +396,6 @@ impl Contains for SafeCallFilter { } } -/// Asset filter that allows all assets from a certain location matching asset id. -pub struct AssetPrefixFrom(PhantomData<(Prefix, Origin)>); -impl ContainsPair for AssetPrefixFrom -where - Prefix: Get, - Origin: Get, -{ - fn contains(asset: &Asset, origin: &Location) -> bool { - let loc = Origin::get(); - &loc == origin && - matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } - if asset_loc.starts_with(&Prefix::get())) - } -} - -/// Asset filter that allows native/relay asset if coming from a certain location. -pub struct NativeAssetFrom(PhantomData); -impl> ContainsPair for NativeAssetFrom { - fn contains(asset: &Asset, origin: &Location) -> bool { - let loc = T::get(); - &loc == origin && - matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } - if *asset_loc == Location::from(Parent)) - } -} - -parameter_types! { - /// Location of Asset Hub - pub AssetHubLocation: Location = (Parent, Parachain(1000)).into(); - pub EthereumLocation: Location = Location::new(2, [GlobalConsensus(Ethereum { chain_id: 1 })]); -} - pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type AssetClaims = PolkadotXcm; @@ -674,7 +409,7 @@ impl xcm_executor::Config for XcmConfig { MultiNativeAsset, ); type IsTeleporter = (); - type UniversalLocation = UniversalLocation; + type UniversalLocation = KusamaUniversalLocation; type OriginConverter = XcmOriginToTransactDispatchOrigin; type ResponseHandler = PolkadotXcm; type SubscriptionService = PolkadotXcm; @@ -699,7 +434,7 @@ impl xcm_executor::Config for XcmConfig { } /// Local origins on this chain are allowed to dispatch XCM sends/executions. -pub type LocalOriginToLocation = SignedToAccountId32; +pub type LocalOriginToLocation = SignedToAccountId32; /// The means for routing XCM messages which are not for local execution into the right message /// queues. @@ -718,17 +453,17 @@ parameter_types! { impl pallet_xcm::Config for Runtime { type RuntimeEvent = RuntimeEvent; type ExecuteXcmOrigin = EnsureXcmOrigin; - type UniversalLocation = UniversalLocation; + type UniversalLocation = KusamaUniversalLocation; type SendXcmOrigin = EnsureXcmOrigin; type Weigher = FixedWeightBounds; type XcmExecuteFilter = Nothing; #[cfg(feature = "runtime-benchmarks")] - type XcmExecutor = bifrost_primitives::DoNothingExecuteXcm; + type XcmExecutor = bifrost_primitives::MockXcmExecutor; #[cfg(not(feature = "runtime-benchmarks"))] type XcmExecutor = XcmExecutor; type XcmReserveTransferFilter = Everything; #[cfg(feature = "runtime-benchmarks")] - type XcmRouter = bifrost_primitives::DoNothingRouter; + type XcmRouter = bifrost_primitives::MockXcmRouter; #[cfg(not(feature = "runtime-benchmarks"))] type XcmRouter = XcmRouter; type XcmTeleportFilter = Nothing; @@ -752,10 +487,6 @@ impl cumulus_pallet_xcm::Config for Runtime { type XcmExecutor = XcmExecutor; } -parameter_types! { - pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent; -} - impl cumulus_pallet_xcmp_queue::Config for Runtime { type ChannelInfo = ParachainSystem; type RuntimeEvent = RuntimeEvent; @@ -770,11 +501,6 @@ impl cumulus_pallet_xcmp_queue::Config for Runtime { type MaxPageSize = ConstU32<{ 103 * 1024 }>; } -parameter_types! { - pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; - pub MessageQueueIdleServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; -} - impl pallet_message_queue::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_message_queue::weights::SubstrateWeight; @@ -839,42 +565,25 @@ parameter_type_with_key! { pub struct DustRemovalWhitelist; impl Contains for DustRemovalWhitelist { fn contains(a: &AccountId) -> bool { - AccountIdConversion::::into_account_truncating(&TreasuryPalletId::get()).eq(a) || - AccountIdConversion::::into_account_truncating(&BifrostCrowdloanId::get()) - .eq(a) || AccountIdConversion::::into_account_truncating( - &BifrostSalpLiteCrowdloanId::get(), - ) - .eq(a) || AccountIdConversion::::into_account_truncating( - &LighteningRedeemPalletId::get(), - ) - .eq(a) || AccountIdConversion::::into_account_truncating( - &VsbondAuctionPalletId::get(), - ) - .eq(a) || LiquidityMiningPalletId::get().check_sub_account::(a) || - LiquidityMiningDOTPalletId::get().check_sub_account::(a) || - AccountIdConversion::::into_account_truncating( - &ParachainStakingPalletId::get(), - ) - .eq(a) || AccountIdConversion::::into_account_truncating( - &BifrostVsbondPalletId::get(), - ) - .eq(a) || AccountIdConversion::::into_account_truncating( - &SlpEntrancePalletId::get(), - ) - .eq(a) || AccountIdConversion::::into_account_truncating(&SlpExitPalletId::get()) - .eq(a) || FarmingKeeperPalletId::get().check_sub_account::(a) || + let whitelist: Vec = vec![ + TreasuryPalletId::get().into_account_truncating(), + BifrostCrowdloanId::get().into_account_truncating(), + BifrostVsbondPalletId::get().into_account_truncating(), + SlpEntrancePalletId::get().into_account_truncating(), + SlpExitPalletId::get().into_account_truncating(), + BuybackPalletId::get().into_account_truncating(), + SystemMakerPalletId::get().into_account_truncating(), + ZenklinkFeeAccount::get(), + CommissionPalletId::get().into_account_truncating(), + VsbondAuctionPalletId::get().into_account_truncating(), + ParachainStakingPalletId::get().into_account_truncating(), + SystemStakingPalletId::get().into_account_truncating(), + VBNCConvertPalletId::get().into_account_truncating(), + ]; + whitelist.contains(a) || + FarmingKeeperPalletId::get().check_sub_account::(a) || FarmingRewardIssuerPalletId::get().check_sub_account::(a) || - AccountIdConversion::::into_account_truncating( - &SystemStakingPalletId::get(), - ) - .eq(a) || AccountIdConversion::::into_account_truncating(&BuybackPalletId::get()) - .eq(a) || AccountIdConversion::::into_account_truncating( - &SystemMakerPalletId::get(), - ) - .eq(a) || FeeSharePalletId::get().check_sub_account::(a) || - a.eq(&ZenklinkFeeAccount::get()) || - AccountIdConversion::::into_account_truncating(&CommissionPalletId::get()) - .eq(a) + FeeSharePalletId::get().check_sub_account::(a) } } @@ -910,13 +619,6 @@ impl orml_tokens::Config for Runtime { type CurrencyHooks = CurrencyHooks; } -parameter_types! { - pub SelfLocation: Location = Location::new(1, [Parachain(ParachainInfo::get().into())]); - pub SelfRelativeLocation: Location = Location::here(); - pub const BaseXcmWeight: Weight = Weight::from_parts(1000_000_000u64, 0); - pub const MaxAssetsForTransfer: usize = 2; -} - parameter_type_with_key! { pub ParachainMinFee: |_location: Location| -> Option { Some(u128::MAX) @@ -927,12 +629,12 @@ impl orml_xtokens::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type CurrencyId = CurrencyId; - type CurrencyIdConvert = BifrostCurrencyIdConvert; - type AccountIdToLocation = BifrostAccountIdToLocation; - type UniversalLocation = UniversalLocation; - type SelfLocation = SelfRelativeLocation; + type CurrencyIdConvert = CurrencyIdConvert; + type AccountIdToLocation = AccountIdToLocation; + type UniversalLocation = KusamaUniversalLocation; + type SelfLocation = SelfLocation; #[cfg(feature = "runtime-benchmarks")] - type XcmExecutor = bifrost_primitives::DoNothingExecuteXcm; + type XcmExecutor = bifrost_primitives::MockXcmExecutor; #[cfg(not(feature = "runtime-benchmarks"))] type XcmExecutor = XcmExecutor; type Weigher = FixedWeightBounds; @@ -963,16 +665,16 @@ impl bifrost_xcm_interface::Config for Runtime { type RuntimeEvent = RuntimeEvent; type UpdateOrigin = TechAdminOrCouncil; type MultiCurrency = Currencies; - type RelayNetwork = RelayNetwork; + type RelayNetwork = KusamaNetwork; type RelaychainCurrencyId = RelayCurrencyId; type ParachainSovereignAccount = ParachainAccount; #[cfg(feature = "runtime-benchmarks")] - type XcmExecutor = bifrost_primitives::DoNothingExecuteXcm; + type XcmExecutor = bifrost_primitives::MockXcmExecutor; #[cfg(not(feature = "runtime-benchmarks"))] type XcmExecutor = XcmExecutor; - type AccountIdToLocation = BifrostAccountIdToLocation; + type AccountIdToLocation = AccountIdToLocation; type SalpHelper = Salp; - type ParachainId = SelfParaChainId; + type ParachainId = ParachainInfo; type CallBackTimeOut = ConstU32<10>; type CurrencyIdConvert = AssetIdMaps; } diff --git a/runtime/bifrost-polkadot/Cargo.toml b/runtime/bifrost-polkadot/Cargo.toml index a1c48358f..e79e6fef5 100644 --- a/runtime/bifrost-polkadot/Cargo.toml +++ b/runtime/bifrost-polkadot/Cargo.toml @@ -46,6 +46,7 @@ pallet-proxy = { workspace = true } pallet-ranked-collective = { workspace = true } pallet-referenda = { workspace = true } pallet-scheduler = { workspace = true } +pallet-staking = { workspace = true } pallet-session = { workspace = true } pallet-timestamp = { workspace = true } pallet-tips = { workspace = true } @@ -149,13 +150,14 @@ bifrost-runtime-common = { workspace = true } bifrost-salp = { workspace = true } bifrost-salp-rpc-runtime-api = { workspace = true } bifrost-slp = { workspace = true } +bifrost-slp-v2 = { workspace = true, features = ["polkadot"] } bifrost-slpx = { workspace = true } bifrost-stable-pool = { workspace = true } bifrost-stable-pool-rpc-runtime-api = { workspace = true } bifrost-system-maker = { workspace = true } bifrost-system-staking = { workspace = true } -bifrost-ve-minting = { workspace = true } -bifrost-ve-minting-rpc-runtime-api = { workspace = true } +bb-bnc = { workspace = true } +bb-bnc-rpc-runtime-api = { workspace = true } bifrost-vesting = { workspace = true } bifrost-vstoken-conversion = { workspace = true } bifrost-vtoken-minting = { workspace = true } @@ -266,13 +268,14 @@ std = [ "bifrost-salp-rpc-runtime-api/std", "bifrost-salp/std", "bifrost-slp/std", + "bifrost-slp-v2/std", "bifrost-slpx/std", "bifrost-stable-pool-rpc-runtime-api/std", "bifrost-stable-pool/std", "bifrost-system-maker/std", "bifrost-system-staking/std", - "bifrost-ve-minting-rpc-runtime-api/std", - "bifrost-ve-minting/std", + "bb-bnc-rpc-runtime-api/std", + "bb-bnc/std", "bifrost-vesting/std", "bifrost-vtoken-minting/std", "bifrost-vtoken-voting/std", @@ -321,6 +324,7 @@ runtime-benchmarks = [ "pallet-balances/runtime-benchmarks", "pallet-bounties/runtime-benchmarks", "pallet-indices/runtime-benchmarks", + "pallet-staking/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", @@ -331,9 +335,10 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "bifrost-slp/runtime-benchmarks", + "bifrost-slp-v2/runtime-benchmarks", "bifrost-salp/runtime-benchmarks", "bifrost-vtoken-minting/runtime-benchmarks", - "bifrost-ve-minting/runtime-benchmarks", + "bb-bnc/runtime-benchmarks", "bifrost-cross-in-out/runtime-benchmarks", "bifrost-slpx/runtime-benchmarks", "bifrost-stable-pool/runtime-benchmarks", @@ -357,12 +362,13 @@ try-runtime = [ "bifrost-flexible-fee/try-runtime", "bifrost-salp/try-runtime", "bifrost-slp/try-runtime", + "bifrost-slp-v2/try-runtime", "bifrost-slpx/try-runtime", "bifrost-stable-asset/try-runtime", "bifrost-stable-pool/try-runtime", "bifrost-system-maker/try-runtime", "bifrost-system-staking/try-runtime", - "bifrost-ve-minting/try-runtime", + "bb-bnc/try-runtime", "bifrost-vesting/try-runtime", "bifrost-vstoken-conversion/try-runtime", "bifrost-vtoken-minting/try-runtime", diff --git a/runtime/bifrost-polkadot/src/evm/evm_fee.rs b/runtime/bifrost-polkadot/src/evm/evm_fee.rs index ee4ecae00..01656d02b 100644 --- a/runtime/bifrost-polkadot/src/evm/evm_fee.rs +++ b/runtime/bifrost-polkadot/src/evm/evm_fee.rs @@ -19,10 +19,7 @@ use crate::Currencies; use bifrost_primitives::{AccountFeeCurrency, Balance, CurrencyId}; use bifrost_runtime_common::Ratio; -use frame_support::traits::{ - tokens::{Fortitude, Precision, Preservation}, - Get, OnUnbalanced, TryDrop, -}; +use frame_support::traits::{Get, OnUnbalanced, TryDrop}; use orml_traits::MultiCurrency; use pallet_evm::{AddressMapping, Error, OnChargeEVMTransaction}; use sp_core::{H160, U256}; @@ -76,15 +73,7 @@ where * asset to account * currency */ U256: UniqueSaturatedInto, - MC: frame_support::traits::tokens::fungibles::Mutate< - T::AccountId, - AssetId = CurrencyId, - Balance = Balance, - > + frame_support::traits::tokens::fungibles::Inspect< - T::AccountId, - AssetId = CurrencyId, - Balance = Balance, - >, + MC: MultiCurrency, sp_runtime::AccountId32: From<::AccountId>, { type LiquidityInfo = Option; @@ -94,7 +83,9 @@ where return Ok(None); } let account_id = T::AddressMapping::into_account_id(*who); - let fee_currency = AC::get(&account_id); + + let fee_currency = + AC::get_fee_currency(&account_id, fee).map_err(|_| Error::::BalanceLow)?; let Some((converted, price)) = C::convert((EC::get(), fee_currency, fee.unique_saturated_into())) @@ -107,17 +98,18 @@ where return Err(Error::::WithdrawFailed); } - let burned = MC::burn_from( + log::debug!( + target: "evm", + "Withdrew fee from account {:?} in currency {:?} amount {:?}", + account_id, fee_currency, - &account_id, - converted, - Preservation::Expendable, - Precision::Exact, - Fortitude::Polite, - ) - .map_err(|_| Error::::BalanceLow)?; - - Ok(Some(EvmPaymentInfo { amount: burned, currency_id: fee_currency, price })) + converted + ); + + MC::withdraw(fee_currency, &account_id, converted) + .map_err(|_| Error::::WithdrawFailed)?; + + Ok(Some(EvmPaymentInfo { amount: converted, currency_id: fee_currency, price })) } fn correct_and_deposit_fee( @@ -144,17 +136,11 @@ where // refund to the account that paid the fees. If this fails, the // account might have dropped below the existential balance. In // that case we don't refund anything. - let result = MC::mint_into(paid.currency_id, &account_id, refund_amount); - - let refund_imbalance = if let Ok(amount) = result { - // Ensure that we minted all amount, in case of partial refund for some reason, - // refund the difference back to treasury - debug_assert_eq!(amount, refund_amount); - refund_amount.saturating_sub(amount) - } else { - // If error, we refund the whole amount back to treasury - refund_amount - }; + let refund_imbalance = + match MC::deposit(paid.currency_id, &account_id, refund_amount) { + Ok(_) => 0, + Err(_) => refund_amount, + }; // figure out how much is left to mint back // refund_amount already minted back to account, imbalance is what is left to mint // if any diff --git a/runtime/bifrost-polkadot/src/evm/runner.rs b/runtime/bifrost-polkadot/src/evm/runner.rs index 4ad5c4b7f..4e1e1058c 100644 --- a/runtime/bifrost-polkadot/src/evm/runner.rs +++ b/runtime/bifrost-polkadot/src/evm/runner.rs @@ -64,7 +64,12 @@ where let evm_currency = WethAssetId::get(); let account_id = T::AddressMapping::into_account_id(source); let account_nonce = frame_system::Pallet::::account_nonce(&account_id); - let (balance, b_weight) = B::get_balance_in_currency(evm_currency, &account_id); + + let (balance, b_weight) = B::get_balance_in_currency(evm_currency, &account_id, base_fee) + .map_err(|_| RunnerError { + error: R::Error::from(TransactionValidationError::BalanceTooLow), + weight, + })?; let (source_account, inner_weight) = ( Account { diff --git a/runtime/bifrost-polkadot/src/lib.rs b/runtime/bifrost-polkadot/src/lib.rs index 04c3d0a45..db5bd4b9a 100644 --- a/runtime/bifrost-polkadot/src/lib.rs +++ b/runtime/bifrost-polkadot/src/lib.rs @@ -69,6 +69,7 @@ pub mod constants; mod evm; mod migration; pub mod weights; +use bb_bnc::traits::BbBNCInterface; use bifrost_asset_registry::{AssetIdMaps, FixedRateOfAsset}; pub use bifrost_primitives::{ traits::{ @@ -86,9 +87,8 @@ use bifrost_runtime_common::{ TechnicalCollective, }; use bifrost_slp::QueryId; -use bifrost_ve_minting::traits::VeMintingInterface; use constants::currency::*; -use cumulus_primitives_core::ParaId as CumulusParaId; +use cumulus_primitives_core::AggregateMessageOrigin; use fp_evm::FeeCalculator; use fp_rpc::TransactionStatus; use frame_support::{ @@ -105,12 +105,10 @@ use frame_system::{EnsureRoot, EnsureRootWithSuccess, EnsureSigned}; use hex_literal::hex; use pallet_ethereum::Transaction; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; -// zenlink imports use zenlink_protocol::{ AssetBalance, AssetId as ZenlinkAssetId, LocalAssetHandler, MultiAssetsHandler, PairInfo, PairLpGenerate, ZenlinkMultiAssets, }; -// xcm config pub mod xcm_config; use orml_traits::{currency::MutationHooks, location::RelativeReserveProvider}; use pallet_evm::{GasWeightMapping, Runner}; @@ -124,13 +122,8 @@ use sp_runtime::{ }; use static_assertions::const_assert; use xcm::{v3::MultiLocation, v4::prelude::*}; -pub use xcm_config::{ - parachains, BifrostCurrencyIdConvert, BifrostTreasuryAccount, MultiCurrency, SelfParaChainId, -}; -use xcm_executor::{ - traits::{Properties, QueryHandler}, - XcmExecutor, -}; +pub use xcm_config::{parachains, BifrostTreasuryAccount, MultiCurrency}; +use xcm_executor::{traits::QueryHandler, XcmExecutor}; pub mod governance; use crate::xcm_config::XcmRouter; @@ -139,6 +132,11 @@ use governance::{ TechAdminOrCouncil, }; +use bifrost_primitives::MoonbeamChainId; +#[cfg(feature = "runtime-benchmarks")] +use bifrost_primitives::{MockXcmRouter, MockXcmTransfer}; +use bifrost_runtime_common::currency_converter::CurrencyIdConvert; + /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know /// the specifics of the runtime. They can then be made to be agnostic over specific formats /// of data like extrinsics, allowing for them to continue syncing the network through upgrades @@ -171,7 +169,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("bifrost_polkadot"), impl_name: create_runtime_str!("bifrost_polkadot"), authoring_version: 0, - spec_version: 12001, + spec_version: 13000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -242,8 +240,7 @@ parameter_types! { pub const SystemMakerPalletId: PalletId = PalletId(*b"bf/sysmk"); pub const FeeSharePalletId: PalletId = PalletId(*b"bf/feesh"); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); - pub const VeMintingPalletId: PalletId = PalletId(*b"bf/vemnt"); - pub const IncentivePalletId: PalletId = PalletId(*b"bf/veict"); + pub const IncentivePalletId: PalletId = PalletId(*b"bf/bbict"); pub const FarmingBoostPalletId: PalletId = PalletId(*b"bf/fmbst"); pub const LendMarketPalletId: PalletId = PalletId(*b"bf/ldmkt"); pub const OraclePalletId: PalletId = PalletId(*b"bf/oracl"); @@ -815,10 +812,11 @@ impl pallet_tx_pause::Config for Runtime { parameter_types! { pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); + pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent; } impl cumulus_pallet_parachain_system::Config for Runtime { - type DmpQueue = frame_support::traits::EnqueueWithOrigin; + type DmpQueue = frame_support::traits::EnqueueWithOrigin; type RuntimeEvent = RuntimeEvent; type OnSystemEvent = (); type OutboundXcmpMessageSource = XcmpQueue; @@ -1022,7 +1020,7 @@ pub fn create_x2_multilocation(index: u16, currency_id: CurrencyId) -> MultiLoca _ => { // get parachain id if let Some(location) = - BifrostCurrencyIdConvert::::convert(currency_id) + CurrencyIdConvert::::convert(currency_id) { if let Some(Parachain(para_id)) = location.interior().first() { xcm::v3::Location::new( @@ -1159,7 +1157,7 @@ impl bifrost_slp::Config for Runtime { type WeightInfo = weights::bifrost_slp::BifrostWeight; type VtokenMinting = VtokenMinting; type AccountConverter = SubAccountIndexMultiLocationConvertor; - type ParachainId = SelfParaChainId; + type ParachainId = ParachainInfo; type SubstrateResponseManager = SubstrateResponseManager; type MaxTypeEntryPerBlock = MaxTypeEntryPerBlock; type MaxRefundPerBlock = MaxRefundPerBlock; @@ -1202,7 +1200,7 @@ impl bifrost_farming::Config for Runtime { type RewardIssuer = FarmingRewardIssuerPalletId; type WeightInfo = weights::bifrost_farming::BifrostWeight; type FarmingBoost = FarmingBoostPalletId; - type VeMinting = VeMinting; + type BbBNC = BbBNC; type BlockNumberToBalance = ConvertInto; type WhitelistMaximumLimit = WhitelistMaximumLimit; type GaugeRewardIssuer = FarmingGaugeRewardIssuerPalletId; @@ -1231,7 +1229,7 @@ impl bifrost_system_staking::Config for Runtime { impl bifrost_system_maker::Config for Runtime { type RuntimeEvent = RuntimeEvent; type MultiCurrency = Currencies; - type ControlOrigin = EitherOfDiverse; + type ControlOrigin = TechAdminOrCouncil; type WeightInfo = weights::bifrost_system_maker::BifrostWeight; type DexOperator = ZenlinkProtocol; type CurrencyIdConversion = AssetIdMaps; @@ -1248,6 +1246,7 @@ impl bifrost_fee_share::Config for Runtime { type ControlOrigin = CoreAdminOrCouncil; type WeightInfo = weights::bifrost_fee_share::BifrostWeight; type FeeSharePalletId = FeeSharePalletId; + type PriceFeeder = Prices; } impl bifrost_cross_in_out::Config for Runtime { @@ -1270,7 +1269,7 @@ impl bifrost_slpx::Config for Runtime { type XcmSender = XcmRouter; type CurrencyIdConvert = AssetIdMaps; type TreasuryAccount = BifrostTreasuryAccount; - type ParachainId = SelfParaChainId; + type ParachainId = ParachainInfo; type WeightInfo = weights::bifrost_slpx::BifrostWeight; } @@ -1294,7 +1293,7 @@ impl bifrost_stable_asset::Config for Runtime { type PoolAssetLimit = ConstU32<5>; type SwapExactOverAmount = ConstU128<100>; type WeightInfo = (); - type ListingOrigin = EitherOfDiverse; + type ListingOrigin = TechAdminOrCouncil; type EnsurePoolAssetId = EnsurePoolAssetId; } @@ -1332,7 +1331,7 @@ impl bifrost_vtoken_voting::Config for Runtime { type DerivativeAccount = DerivativeAccountProvider; type RelaychainBlockNumberProvider = RelaychainDataProvider; type VTokenSupplyProvider = VtokenMinting; - type ParachainId = SelfParaChainId; + type ParachainId = ParachainInfo; type MaxVotes = ConstU32<256>; type QueryTimeout = QueryTimeout; type ReferendumCheckInterval = ReferendumCheckInterval; @@ -1417,20 +1416,16 @@ impl bifrost_vtoken_minting::Config for Runtime { type CurrencyIdConversion = AssetIdMaps; type CurrencyIdRegister = AssetIdMaps; type XcmTransfer = XTokens; - type AstarParachainId = ConstU32<2006>; - type MoonbeamParachainId = ConstU32<2004>; - type HydradxParachainId = ConstU32<2034>; - type MantaParachainId = ConstU32<2104>; - type InterlayParachainId = ConstU32<2032>; + type MoonbeamChainId = MoonbeamChainId; type ChannelCommission = ChannelCommission; type MaxLockRecords = ConstU32<100>; type IncentivePoolAccount = IncentivePoolAccount; - type VeMinting = VeMinting; + type BbBNC = BbBNC; type AssetIdMaps = AssetIdMaps; } parameter_types! { - pub const VeMintingTokenType: CurrencyId = CurrencyId::VToken(TokenSymbol::BNC); + pub const BbBNCTokenType: CurrencyId = CurrencyId::VToken(TokenSymbol::BNC); pub const Week: BlockNumber = prod_or_fast!(WEEKS, 10); pub const MaxBlock: BlockNumber = 4 * 365 * DAYS; pub const Multiplier: Balance = 10_u128.pow(12); @@ -1439,14 +1434,14 @@ parameter_types! { pub const MarkupRefreshLimit: u32 = 100; } -impl bifrost_ve_minting::Config for Runtime { +impl bb_bnc::Config for Runtime { type RuntimeEvent = RuntimeEvent; type MultiCurrency = Currencies; type ControlOrigin = TechAdminOrCouncil; - type TokenType = VeMintingTokenType; - type VeMintingPalletId = VeMintingPalletId; + type TokenType = BbBNCTokenType; type IncentivePalletId = IncentivePalletId; - type WeightInfo = weights::bifrost_ve_minting::BifrostWeight; + type BuyBackAccount = BuyBackAccount; + type WeightInfo = weights::bb_bnc::BifrostWeight; type BlockNumberToBalance = ConvertInto; type Week = Week; type MaxBlock = MaxBlock; @@ -1515,8 +1510,8 @@ impl DataFeeder for AggregatedDataProvi impl pallet_prices::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Source = AggregatedDataProvider; - type FeederOrigin = EitherOfDiverse; - type UpdateOrigin = EitherOfDiverse; + type FeederOrigin = TechAdminOrCouncil; + type UpdateOrigin = TechAdminOrCouncil; type RelayCurrency = RelayCurrencyId; type CurrencyIdConvert = AssetIdMaps; type Assets = Currencies; @@ -1584,7 +1579,7 @@ impl bifrost_clouds_convert::Config for Runtime { type RuntimeEvent = RuntimeEvent; type MultiCurrency = Currencies; type CloudsPalletId = CloudsPalletId; - type VeMinting = VeMinting; + type BbBNC = BbBNC; type WeightInfo = weights::bifrost_clouds_convert::BifrostWeight; type LockedBlocks = MaxBlock; } @@ -1592,17 +1587,40 @@ impl bifrost_clouds_convert::Config for Runtime { impl bifrost_buy_back::Config for Runtime { type RuntimeEvent = RuntimeEvent; type MultiCurrency = Currencies; - type ControlOrigin = EitherOfDiverse; + type ControlOrigin = TechAdminOrCouncil; type WeightInfo = weights::bifrost_buy_back::BifrostWeight; type DexOperator = ZenlinkProtocol; - type CurrencyIdConversion = AssetIdMaps; type TreasuryAccount = BifrostTreasuryAccount; - type RelayChainToken = RelayCurrencyId; type BuyBackAccount = BuyBackAccount; type LiquidityAccount = LiquidityAccount; type ParachainId = ParachainInfo; type CurrencyIdRegister = AssetIdMaps; - type VeMinting = VeMinting; + type BbBNC = BbBNC; +} + +impl bifrost_slp_v2::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type ResponseOrigin = EnsureResponse; + type WeightInfo = weights::bifrost_slp_v2::BifrostWeight; + type MultiCurrency = Currencies; + type ControlOrigin = TechAdminOrCouncil; + #[cfg(not(feature = "runtime-benchmarks"))] + type XcmTransfer = XTokens; + #[cfg(feature = "runtime-benchmarks")] + type XcmTransfer = MockXcmTransfer; + #[cfg(not(feature = "runtime-benchmarks"))] + type XcmSender = XcmRouter; + #[cfg(feature = "runtime-benchmarks")] + type XcmSender = MockXcmRouter; + type VtokenMinting = VtokenMinting; + type CurrencyIdConversion = AssetIdMaps; + type RelaychainBlockNumberProvider = RelaychainDataProvider; + type QueryTimeout = QueryTimeout; + type CommissionPalletId = CommissionPalletId; + type ParachainId = ParachainInfo; + type MaxValidators = ConstU32<256>; } // Below is the implementation of tokens manipulation functions other than native token. @@ -1762,7 +1780,7 @@ construct_runtime! { // Third party modules XTokens: orml_xtokens = 70, Tokens: orml_tokens = 71, - Currencies: bifrost_currencies = 72, + Currencies: bifrost_currencies exclude_parts { Call } = 72, UnknownTokens: orml_unknown_tokens = 73, OrmlXcm: orml_xcm = 74, ZenlinkProtocol: zenlink_protocol = 80, @@ -1781,7 +1799,7 @@ construct_runtime! { SystemMaker: bifrost_system_maker = 121, FeeShare: bifrost_fee_share = 122, CrossInOut: bifrost_cross_in_out = 123, - VeMinting: bifrost_ve_minting = 124, + BbBNC: bb_bnc = 124, Slpx: bifrost_slpx = 125, FellowshipCollective: pallet_ranked_collective:: = 126, FellowshipReferenda: pallet_referenda:: = 127, @@ -1796,6 +1814,7 @@ construct_runtime! { ChannelCommission: bifrost_channel_commission = 136, CloudsConvert: bifrost_clouds_convert = 137, BuyBack: bifrost_buy_back = 138, + SlpV2: bifrost_slp_v2 = 139, } } @@ -1863,10 +1882,6 @@ pub type CheckedExtrinsic = /// The payload being signed in transactions. pub type SignedPayload = generic::SignedPayload; -parameter_types! { - pub const CallSwitchgearPalletName: &'static str = "CallSwitchgear"; -} - impl cumulus_pallet_xcmp_queue::migration::v5::V5Config for Runtime { // This must be the same as the `ChannelInfo` from the `Config`: type ChannelList = ParachainSystem; @@ -1887,16 +1902,6 @@ pub mod migrations { pub type Unreleased = ( // permanent migration, do not remove pallet_xcm::migration::MigrateToLatestXcmVersion, - frame_support::migrations::RemovePallet< - CallSwitchgearPalletName, - ::DbWeight, - >, - cumulus_pallet_xcmp_queue::migration::v5::MigrateV4ToV5, - crate::migration::opengov::RankedCollectiveV1< - Runtime, - governance::fellowship::FellowshipCollectiveInstance, - >, - crate::migration::genesis_evm_storage::GenesisEVMStorage, ); } @@ -1973,8 +1978,9 @@ extern crate frame_benchmarking; #[cfg(feature = "runtime-benchmarks")] mod benches { define_benchmarks!( - [bifrost_ve_minting, VeMinting] + [bb_bnc, BbBNC] [bifrost_buy_back, BuyBack] + [bifrost_slp_v2, SlpV2] ); } @@ -2462,25 +2468,25 @@ impl fp_rpc::EthereumRuntimeRPCApi for Runtime { } } - impl bifrost_ve_minting_rpc_runtime_api::VeMintingRuntimeApi for Runtime { + impl bb_bnc_rpc_runtime_api::BbBNCRuntimeApi for Runtime { fn balance_of( who: AccountId, t: Option, ) -> Balance{ - VeMinting::balance_of(&who, t).unwrap_or(Zero::zero()) + BbBNC::balance_of(&who, t).unwrap_or(Zero::zero()) } fn total_supply( t: bifrost_primitives::BlockNumber, ) -> Balance{ - VeMinting::total_supply(t).unwrap_or(Zero::zero()) + BbBNC::total_supply(t).unwrap_or(Zero::zero()) } fn find_block_epoch( block: bifrost_primitives::BlockNumber, max_epoch: U256, ) -> U256{ - VeMinting::find_block_epoch(block, max_epoch) + BbBNC::find_block_epoch(block, max_epoch) } } diff --git a/runtime/bifrost-polkadot/src/weights/bifrost_ve_minting.rs b/runtime/bifrost-polkadot/src/weights/bb_bnc.rs similarity index 51% rename from runtime/bifrost-polkadot/src/weights/bifrost_ve_minting.rs rename to runtime/bifrost-polkadot/src/weights/bb_bnc.rs index ae92ae128..a10ad217d 100644 --- a/runtime/bifrost-polkadot/src/weights/bifrost_ve_minting.rs +++ b/runtime/bifrost-polkadot/src/weights/bb_bnc.rs @@ -22,7 +22,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for bifrost_ve_minting +//! Autogenerated weights for bb_bnc //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev //! DATE: 2023-09-14, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` @@ -36,12 +36,12 @@ // --chain=bifrost-polkadot-local // --steps=50 // --repeat=20 -// --pallet=bifrost_ve_minting +// --pallet=bb_bnc // --extrinsic=* // --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./runtime/bifrost-polkadot/src/weights/bifrost_ve_minting.rs +// --output=./runtime/bifrost-polkadot/src/weights/bb_bnc.rs // --template=./weight-template/runtime-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -51,11 +51,11 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; -/// Weight functions for bifrost_ve_minting. +/// Weight functions for bb_bnc. pub struct BifrostWeight(PhantomData); -impl bifrost_ve_minting::WeightInfo for BifrostWeight { - // Storage: VeMinting VeConfigs (r:1 w:1) - // Proof Skipped: VeMinting VeConfigs (max_values: Some(1), max_size: None, mode: Measured) +impl bb_bnc::WeightInfo for BifrostWeight { + // Storage: BbBNC VeConfigs (r:1 w:1) + // Proof Skipped: BbBNC VeConfigs (max_values: Some(1), max_size: None, mode: Measured) // Storage: System Number (r:1 w:0) // Proof: System Number (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) // Storage: System ExecutionPhase (r:1 w:0) @@ -73,14 +73,14 @@ impl bifrost_ve_minting::WeightInfo for BifrostWeight bifrost_ve_minting::WeightInfo for BifrostWeight Weight { // Proof Size summary in bytes: // Measured: `1439` @@ -118,14 +118,14 @@ impl bifrost_ve_minting::WeightInfo for BifrostWeight bifrost_ve_minting::WeightInfo for BifrostWeight Weight { // Proof Size summary in bytes: // Measured: `2083` @@ -163,30 +163,30 @@ impl bifrost_ve_minting::WeightInfo for BifrostWeight bifrost_ve_minting::WeightInfo for BifrostWeight bifrost_ve_minting::WeightInfo for BifrostWeight Weight { // Proof Size summary in bytes: // Measured: `2059` @@ -247,24 +247,24 @@ impl bifrost_ve_minting::WeightInfo for BifrostWeight bifrost_ve_minting::WeightInfo for BifrostWeight bifrost_ve_minting::WeightInfo for BifrostWeight bifrost_ve_minting::WeightInfo for BifrostWeight Weight { // Proof Size summary in bytes: // Measured: `213` @@ -327,16 +327,16 @@ impl bifrost_ve_minting::WeightInfo for BifrostWeight bifrost_ve_minting::WeightInfo for BifrostWeight Weight { // Proof Size summary in bytes: // Measured: `2260` @@ -381,14 +381,14 @@ impl bifrost_ve_minting::WeightInfo for BifrostWeight bifrost_ve_minting::WeightInfo for BifrostWeight Weight { // Proof Size summary in bytes: // Measured: `2725` @@ -435,16 +435,16 @@ impl bifrost_ve_minting::WeightInfo for BifrostWeight bifrost_ve_minting::WeightInfo for BifrostWeight Weight { // Proof Size summary in bytes: // Measured: `2525` @@ -483,36 +483,36 @@ impl bifrost_ve_minting::WeightInfo for BifrostWeight Weight { // Proof Size summary in bytes: // Measured: `1687` diff --git a/runtime/bifrost-polkadot/src/weights/bifrost_fee_share.rs b/runtime/bifrost-polkadot/src/weights/bifrost_fee_share.rs index 2050da409..1e2478564 100644 --- a/runtime/bifrost-polkadot/src/weights/bifrost_fee_share.rs +++ b/runtime/bifrost-polkadot/src/weights/bifrost_fee_share.rs @@ -127,4 +127,18 @@ impl bifrost_fee_share::WeightInfo for BifrostWeight .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `FeeShare::DistributionInfos` (r:1 w:0) + /// Proof: `FeeShare::DistributionInfos` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `FeeShare::DollarStandardInfos` (r:0 w:1) + /// Proof: `FeeShare::DollarStandardInfos` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn set_usd_config() -> Weight { + // Proof Size summary in bytes: + // Measured: `94` + // Estimated: `3559` + // Minimum execution time: 9_077_000 picoseconds. + Weight::from_parts(9_408_000, 0) + .saturating_add(Weight::from_parts(0, 3559)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/runtime/bifrost-polkadot/src/weights/bifrost_slp_v2.rs b/runtime/bifrost-polkadot/src/weights/bifrost_slp_v2.rs new file mode 100644 index 000000000..b7bd7ff5b --- /dev/null +++ b/runtime/bifrost-polkadot/src/weights/bifrost_slp_v2.rs @@ -0,0 +1,351 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Autogenerated weights for bifrost_slp_v2 +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-09-11, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! HOSTNAME: `bifrost-jenkins`, CPU: `Intel(R) Xeon(R) CPU E5-26xx v4` +//! WASM-EXECUTION: Compiled, CHAIN: Some("bifrost-polkadot-local"), DB CACHE: 1024 + +// Executed Command: +// ./target/release/bifrost +// benchmark +// pallet +// --chain=bifrost-polkadot-local +// --steps=50 +// --repeat=20 +// --pallet=bifrost_slp_v2 +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --header=./HEADER-GPL3 +// --output=./weight.rs +// --template +// ./weight-template/runtime-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions for bifrost_slp_v2. +pub struct BifrostWeight(PhantomData); +impl bifrost_slp_v2::WeightInfo for BifrostWeight { + // Storage: `SlpV2::NextDelegatorIndexByStakingProtocol` (r:1 w:1) + // Proof: `SlpV2::NextDelegatorIndexByStakingProtocol` (`max_values`: None, `max_size`: Some(19), added: 2494, mode: `MaxEncodedLen`) + // Storage: `ParachainInfo::ParachainId` (r:1 w:0) + // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:1 w:1) + // Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:1) + // Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `System::Number` (r:1 w:0) + // Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::ExecutionPhase` (r:1 w:0) + // Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + // Storage: `System::EventCount` (r:1 w:1) + // Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::Events` (r:1 w:1) + // Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + // Storage: `SlpV2::LedgerByStakingProtocolAndDelegator` (r:0 w:1) + // Proof: `SlpV2::LedgerByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(252), added: 2727, mode: `MaxEncodedLen`) + fn add_delegator() -> Weight { + // Proof Size summary in bytes: + // Measured: `341` + // Estimated: `3533` + // Minimum execution time: 53_863 nanoseconds. + Weight::from_parts(54_653_000, 3533) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) + } + // Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:1) + // Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `System::Number` (r:1 w:0) + // Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::ExecutionPhase` (r:1 w:0) + // Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + // Storage: `System::EventCount` (r:1 w:1) + // Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::Events` (r:1 w:1) + // Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + // Storage: `SlpV2::LedgerByStakingProtocolAndDelegator` (r:0 w:1) + // Proof: `SlpV2::LedgerByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(252), added: 2727, mode: `MaxEncodedLen`) + // Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:0 w:1) + // Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `SlpV2::ValidatorsByStakingProtocolAndDelegator` (r:0 w:1) + // Proof: `SlpV2::ValidatorsByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(8772), added: 11247, mode: `MaxEncodedLen`) + fn remove_delegator() -> Weight { + // Proof Size summary in bytes: + // Measured: `432` + // Estimated: `3533` + // Minimum execution time: 44_302 nanoseconds. + Weight::from_parts(45_092_000, 3533) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(6)) + } + // Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:0) + // Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:1 w:0) + // Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `SlpV2::ValidatorsByStakingProtocolAndDelegator` (r:1 w:1) + // Proof: `SlpV2::ValidatorsByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(8772), added: 11247, mode: `MaxEncodedLen`) + // Storage: `System::Number` (r:1 w:0) + // Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::ExecutionPhase` (r:1 w:0) + // Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + // Storage: `System::EventCount` (r:1 w:1) + // Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::Events` (r:1 w:1) + // Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn add_validator() -> Weight { + // Proof Size summary in bytes: + // Measured: `487` + // Estimated: `12237` + // Minimum execution time: 45_532 nanoseconds. + Weight::from_parts(46_472_000, 12237) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(3)) + } + // Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:0) + // Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:1 w:0) + // Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `SlpV2::ValidatorsByStakingProtocolAndDelegator` (r:1 w:1) + // Proof: `SlpV2::ValidatorsByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(8772), added: 11247, mode: `MaxEncodedLen`) + // Storage: `System::Number` (r:1 w:0) + // Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::ExecutionPhase` (r:1 w:0) + // Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + // Storage: `System::EventCount` (r:1 w:1) + // Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::Events` (r:1 w:1) + // Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn remove_validator() -> Weight { + // Proof Size summary in bytes: + // Measured: `598` + // Estimated: `12237` + // Minimum execution time: 46_892 nanoseconds. + Weight::from_parts(48_157_000, 12237) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(3)) + } + // Storage: `SlpV2::ConfigurationByStakingProtocol` (r:1 w:1) + // Proof: `SlpV2::ConfigurationByStakingProtocol` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + // Storage: `System::Number` (r:1 w:0) + // Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::ExecutionPhase` (r:1 w:0) + // Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + // Storage: `System::EventCount` (r:1 w:1) + // Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::Events` (r:1 w:1) + // Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_protocol_configuration() -> Weight { + // Proof Size summary in bytes: + // Measured: `238` + // Estimated: `3567` + // Minimum execution time: 29_559 nanoseconds. + Weight::from_parts(30_338_000, 3567) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + // Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:0) + // Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:1 w:0) + // Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `SlpV2::LedgerByStakingProtocolAndDelegator` (r:1 w:1) + // Proof: `SlpV2::LedgerByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(252), added: 2727, mode: `MaxEncodedLen`) + // Storage: `System::Number` (r:1 w:0) + // Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::ExecutionPhase` (r:1 w:0) + // Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + // Storage: `System::EventCount` (r:1 w:1) + // Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::Events` (r:1 w:1) + // Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_ledger() -> Weight { + // Proof Size summary in bytes: + // Measured: `545` + // Estimated: `3717` + // Minimum execution time: 47_747 nanoseconds. + Weight::from_parts(48_586_000, 3717) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(3)) + } + // Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:0) + // Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:1 w:0) + // Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `Tokens::Accounts` (r:1 w:0) + // Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(118), added: 2593, mode: `MaxEncodedLen`) + // Storage: `System::Number` (r:1 w:0) + // Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::ExecutionPhase` (r:1 w:0) + // Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + // Storage: `System::EventCount` (r:1 w:1) + // Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::Events` (r:1 w:1) + // Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn transfer_to() -> Weight { + // Proof Size summary in bytes: + // Measured: `942` + // Estimated: `3583` + // Minimum execution time: 51_620 nanoseconds. + Weight::from_parts(52_770_000, 3583) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(2)) + } + // Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:0) + // Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:1 w:0) + // Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `SlpV2::ConfigurationByStakingProtocol` (r:1 w:0) + // Proof: `SlpV2::ConfigurationByStakingProtocol` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + // Storage: `System::Number` (r:1 w:0) + // Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::ExecutionPhase` (r:1 w:0) + // Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + // Storage: `System::EventCount` (r:1 w:1) + // Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::Events` (r:1 w:1) + // Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn transfer_back() -> Weight { + // Proof Size summary in bytes: + // Measured: `596` + // Estimated: `3567` + // Minimum execution time: 57_783 nanoseconds. + Weight::from_parts(59_016_000, 3567) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(2)) + } + // Storage: `ParachainSystem::ValidationData` (r:1 w:0) + // Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + // Storage: `ParachainSystem::LastRelayChainBlockNumber` (r:1 w:0) + // Proof: `ParachainSystem::LastRelayChainBlockNumber` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + // Storage: `SlpV2::ConfigurationByStakingProtocol` (r:1 w:0) + // Proof: `SlpV2::ConfigurationByStakingProtocol` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + // Storage: `SlpV2::LastUpdateOngoingTimeUnitBlockNumber` (r:1 w:1) + // Proof: `SlpV2::LastUpdateOngoingTimeUnitBlockNumber` (`max_values`: None, `max_size`: Some(21), added: 2496, mode: `MaxEncodedLen`) + // Storage: `VtokenMinting::OngoingTimeUnit` (r:1 w:1) + // Proof: `VtokenMinting::OngoingTimeUnit` (`max_values`: None, `max_size`: Some(27), added: 2502, mode: `MaxEncodedLen`) + // Storage: `System::Number` (r:1 w:0) + // Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::ExecutionPhase` (r:1 w:0) + // Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + // Storage: `System::EventCount` (r:1 w:1) + // Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::Events` (r:1 w:1) + // Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn update_ongoing_time_unit() -> Weight { + // Proof Size summary in bytes: + // Measured: `560` + // Estimated: `3567` + // Minimum execution time: 45_649 nanoseconds. + Weight::from_parts(47_962_000, 3567) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(4)) + } + // Storage: `SlpV2::ConfigurationByStakingProtocol` (r:1 w:0) + // Proof: `SlpV2::ConfigurationByStakingProtocol` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::ValidationData` (r:1 w:0) + // Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + // Storage: `ParachainSystem::LastRelayChainBlockNumber` (r:1 w:0) + // Proof: `ParachainSystem::LastRelayChainBlockNumber` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + // Storage: `SlpV2::LastUpdateTokenExchangeRateBlockNumber` (r:1 w:1) + // Proof: `SlpV2::LastUpdateTokenExchangeRateBlockNumber` (`max_values`: None, `max_size`: Some(70), added: 2545, mode: `MaxEncodedLen`) + // Storage: `VtokenMinting::TokenPool` (r:1 w:1) + // Proof: `VtokenMinting::TokenPool` (`max_values`: None, `max_size`: Some(38), added: 2513, mode: `MaxEncodedLen`) + // Storage: `SlpV2::LedgerByStakingProtocolAndDelegator` (r:1 w:1) + // Proof: `SlpV2::LedgerByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(252), added: 2727, mode: `MaxEncodedLen`) + // Storage: `System::Number` (r:1 w:0) + // Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::ExecutionPhase` (r:1 w:0) + // Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + // Storage: `System::EventCount` (r:1 w:1) + // Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::Events` (r:1 w:1) + // Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn update_token_exchange_rate() -> Weight { + // Proof Size summary in bytes: + // Measured: `755` + // Estimated: `3717` + // Minimum execution time: 62_204 nanoseconds. + Weight::from_parts(63_446_000, 3717) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(5)) + } + // Storage: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (r:1 w:0) + // Proof: `SlpV2::DelegatorIndexByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (r:1 w:0) + // Proof: `SlpV2::DelegatorByStakingProtocolAndDelegatorIndex` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + // Storage: `System::Number` (r:1 w:0) + // Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) + // Proof: `PolkadotXcm::QueryCounter` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + // Storage: `SlpV2::ConfigurationByStakingProtocol` (r:1 w:0) + // Proof: `SlpV2::ConfigurationByStakingProtocol` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + // Storage: `System::ExecutionPhase` (r:1 w:0) + // Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + // Storage: `System::EventCount` (r:1 w:1) + // Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::Events` (r:1 w:1) + // Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + // Storage: `SlpV2::PendingStatusByQueryId` (r:0 w:1) + // Proof: `SlpV2::PendingStatusByQueryId` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + // Storage: `PolkadotXcm::Queries` (r:0 w:1) + // Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn astar_dapp_staking() -> Weight { + // Proof Size summary in bytes: + // Measured: `836` + // Estimated: `3567` + // Minimum execution time: 72_646 nanoseconds. + Weight::from_parts(73_892_000, 3567) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) + } + // Storage: `SlpV2::PendingStatusByQueryId` (r:1 w:0) + // Proof: `SlpV2::PendingStatusByQueryId` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + // Storage: `SlpV2::LedgerByStakingProtocolAndDelegator` (r:1 w:1) + // Proof: `SlpV2::LedgerByStakingProtocolAndDelegator` (`max_values`: None, `max_size`: Some(252), added: 2727, mode: `MaxEncodedLen`) + // Storage: `System::Number` (r:1 w:0) + // Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::ExecutionPhase` (r:1 w:0) + // Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) + // Storage: `System::EventCount` (r:1 w:1) + // Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `System::Events` (r:1 w:1) + // Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn notify_astar_dapp_staking() -> Weight { + // Proof Size summary in bytes: + // Measured: `567` + // Estimated: `3717` + // Minimum execution time: 40_876 nanoseconds. + Weight::from_parts(41_668_000, 3717) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} \ No newline at end of file diff --git a/runtime/bifrost-polkadot/src/weights/bifrost_slpx.rs b/runtime/bifrost-polkadot/src/weights/bifrost_slpx.rs index 5cc4a3e80..cc9f6ce45 100644 --- a/runtime/bifrost-polkadot/src/weights/bifrost_slpx.rs +++ b/runtime/bifrost-polkadot/src/weights/bifrost_slpx.rs @@ -127,18 +127,36 @@ impl bifrost_slpx::WeightInfo for BifrostWeight { .saturating_add(T::DbWeight::get().reads(16)) .saturating_add(T::DbWeight::get().writes(8)) } - // Storage: `Slpx::WhitelistAccountId` (r:1 w:0) - // Proof: `Slpx::WhitelistAccountId` (`max_values`: None, `max_size`: Some(338), added: 2813, mode: `MaxEncodedLen`) - // Storage: `Slpx::OrderQueue` (r:1 w:1) - // Proof: `Slpx::OrderQueue` (`max_values`: Some(1), `max_size`: Some(203002), added: 203497, mode: `MaxEncodedLen`) + // Storage: Slpx WhitelistAccountId (r:1 w:0) + // Proof: Slpx WhitelistAccountId (max_values: None, max_size: Some(338), added: 2813, mode: MaxEncodedLen) + // Storage: Tokens Accounts (r:4 w:4) + // Proof: Tokens Accounts (max_values: None, max_size: Some(118), added: 2593, mode: MaxEncodedLen) + // Storage: Slpx ExecutionFee (r:1 w:0) + // Proof: Slpx ExecutionFee (max_values: None, max_size: Some(46), added: 2521, mode: MaxEncodedLen) + // Storage: AssetRegistry CurrencyMetadatas (r:1 w:0) + // Proof Skipped: AssetRegistry CurrencyMetadatas (max_values: None, max_size: None, mode: Measured) + // Storage: System Account (r:3 w:2) + // Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + // Storage: VtokenMinting MinimumMint (r:1 w:0) + // Proof: VtokenMinting MinimumMint (max_values: None, max_size: Some(38), added: 2513, mode: MaxEncodedLen) + // Storage: VtokenMinting TokenPool (r:1 w:1) + // Proof: VtokenMinting TokenPool (max_values: None, max_size: Some(38), added: 2513, mode: MaxEncodedLen) + // Storage: Tokens TotalIssuance (r:1 w:1) + // Proof: Tokens TotalIssuance (max_values: None, max_size: Some(38), added: 2513, mode: MaxEncodedLen) + // Storage: VtokenMinting Fees (r:1 w:0) + // Proof: VtokenMinting Fees (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + // Storage: AssetRegistry CurrencyIdToLocations (r:1 w:0) + // Proof Skipped: AssetRegistry CurrencyIdToLocations (max_values: None, max_size: None, mode: Measured) + // Storage: ParachainInfo ParachainId (r:1 w:0) + // Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) fn mint_with_channel_id() -> Weight { // Proof Size summary in bytes: - // Measured: `81` - // Estimated: `204487` - // Minimum execution time: 12_000 nanoseconds. - Weight::from_parts(13_000_000, 204487) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `2442` + // Estimated: `11362` + // Minimum execution time: 355_230 nanoseconds. + Weight::from_parts(360_766_000, 11362) + .saturating_add(T::DbWeight::get().reads(16)) + .saturating_add(T::DbWeight::get().writes(8)) } // Storage: Slpx WhitelistAccountId (r:1 w:0) // Proof: Slpx WhitelistAccountId (max_values: None, max_size: Some(338), added: 2813, mode: MaxEncodedLen) diff --git a/runtime/bifrost-polkadot/src/weights/mod.rs b/runtime/bifrost-polkadot/src/weights/mod.rs index 2dfce402e..5ba0dd1b6 100644 --- a/runtime/bifrost-polkadot/src/weights/mod.rs +++ b/runtime/bifrost-polkadot/src/weights/mod.rs @@ -20,6 +20,7 @@ //! A list of the different weight modules for our runtime. +pub mod bb_bnc; pub mod bifrost_asset_registry; pub mod bifrost_buy_back; pub mod bifrost_channel_commission; @@ -31,11 +32,11 @@ pub mod bifrost_fee_share; pub mod bifrost_flexible_fee; pub mod bifrost_salp; pub mod bifrost_slp; +pub mod bifrost_slp_v2; pub mod bifrost_slpx; pub mod bifrost_stable_pool; pub mod bifrost_system_maker; pub mod bifrost_system_staking; -pub mod bifrost_ve_minting; pub mod bifrost_vesting; pub mod bifrost_vstoken_conversion; pub mod bifrost_vtoken_minting; diff --git a/runtime/bifrost-polkadot/src/xcm_config.rs b/runtime/bifrost-polkadot/src/xcm_config.rs index b9ba1c7ed..9c43feb13 100644 --- a/runtime/bifrost-polkadot/src/xcm_config.rs +++ b/runtime/bifrost-polkadot/src/xcm_config.rs @@ -18,26 +18,32 @@ use super::*; use bifrost_asset_registry::AssetIdMaps; +use bifrost_currencies::BasicCurrencyAdapter; use bifrost_primitives::{ - currency::WETH_TOKEN_ID, AccountId, CurrencyId, CurrencyIdMapping, TokenSymbol, DOT_TOKEN_ID, - GLMR_TOKEN_ID, + currency::WETH_TOKEN_ID, AccountId, AccountIdToLocation, AssetHubLocation, AssetPrefixFrom, + CurrencyId, CurrencyIdMapping, EthereumLocation, NativeAssetFrom, PolkadotNetwork, + PolkadotUniversalLocation, SelfLocation, TokenSymbol, DOT_TOKEN_ID, +}; +use bifrost_runtime_common::currency_adapter::{ + BifrostDropAssets, DepositToAlternative, MultiCurrencyAdapter, }; pub use bifrost_xcm_interface::traits::{parachains, XcmBaseWeight}; use cumulus_primitives_core::AggregateMessageOrigin; pub use cumulus_primitives_core::ParaId; use frame_support::{ - ensure, - sp_runtime::traits::{CheckedConversion, Convert}, - traits::{ContainsPair, Get, ProcessMessageError, TransformOrigin}, + sp_runtime::traits::Convert, + traits::{Get, TransformOrigin}, }; -use orml_traits::location::Reserve; pub use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key, MultiCurrency}; +use orml_xcm_support::{IsNativeConcrete, MultiNativeAsset}; use pallet_xcm::XcmPassthrough; -use parity_scale_codec::{Decode, Encode}; +use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling}; +use parity_scale_codec::Encode; pub use polkadot_parachain_primitives::primitives::Sibling; use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery; use sp_core::bounded::BoundedVec; -use sp_std::{convert::TryFrom, marker::PhantomData}; +use sp_std::convert::TryFrom; +use xcm::v4::{Asset, AssetId, Location}; pub use xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, @@ -47,157 +53,23 @@ pub use xcm_builder::{ }; use xcm_builder::{ DescribeAllTerminal, DescribeFamily, FrameTransactionalProcessor, HashedDescription, - TrailingSetTopicAsId, -}; -use xcm_executor::traits::{MatchesFungible, ShouldExecute}; - -// orml imports -use bifrost_currencies::BasicCurrencyAdapter; -use bifrost_runtime_common::currency_adapter::{ - BifrostDropAssets, DepositToAlternative, MultiCurrencyAdapter, + TrailingSetTopicAsId, WithComputedOrigin, }; -use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling}; -use xcm::v4::{Asset, AssetId, InteriorLocation, Location}; - -/// Bifrost Asset Matcher -pub struct BifrostAssetMatcher( - PhantomData<(CurrencyId, CurrencyIdConvert)>, -); - -impl MatchesFungible - for BifrostAssetMatcher -where - CurrencyIdConvert: Convert>, - Amount: TryFrom, -{ - fn matches_fungible(a: &Asset) -> Option { - if let (Fungible(ref amount), AssetId(ref location)) = (&a.fun, &a.id) { - if CurrencyIdConvert::convert(location.clone()).is_some() { - return CheckedConversion::checked_from(*amount); - } - } - None - } -} - -/// A `FilterAssetLocation` implementation. Filters multi native assets whose -/// reserve is same with `origin`. -pub struct MultiNativeAsset(PhantomData); -impl ContainsPair for MultiNativeAsset -where - ReserveProvider: Reserve, -{ - fn contains(asset: &Asset, origin: &Location) -> bool { - if let Some(ref reserve) = ReserveProvider::reserve(asset) { - if reserve == origin { - return true; - } - } - false - } -} - -fn native_currency_location(id: CurrencyId) -> Location { - Location::new(0, [Junction::from(BoundedVec::try_from(id.encode()).unwrap())]) -} - -impl> Convert> for BifrostCurrencyIdConvert { - fn convert(asset: Asset) -> Option { - if let Asset { id: AssetId(id), fun: xcm::v4::Fungibility::Fungible(_) } = asset { - Self::convert(id) - } else { - None - } - } -} - -pub struct BifrostAccountIdToLocation; -impl Convert for BifrostAccountIdToLocation { - fn convert(account: AccountId) -> Location { - [AccountId32 { network: None, id: account.into() }].into() - } -} - -pub struct BifrostCurrencyIdConvert(PhantomData); -impl> Convert> for BifrostCurrencyIdConvert { - fn convert(id: CurrencyId) -> Option { - use CurrencyId::*; - use TokenSymbol::*; - - if let Some(id) = AssetIdMaps::::get_location(id) { - return Some(id); - } - - match id { - Token2(DOT_TOKEN_ID) => Some(Location::parent()), - Native(BNC) => Some(native_currency_location(id)), - // Moonbeam Native token - Token2(GLMR_TOKEN_ID) => Some(Location::new( - 1, - [ - Parachain(parachains::moonbeam::ID), - PalletInstance(parachains::moonbeam::PALLET_ID.into()), - ], - )), - _ => None, - } - } -} - -impl> Convert> for BifrostCurrencyIdConvert { - fn convert(location: Location) -> Option { - use CurrencyId::*; - use TokenSymbol::*; - - if location == Location::parent() { - return Some(Token2(DOT_TOKEN_ID)); - } - - if let Some(currency_id) = AssetIdMaps::::get_currency_id(location.clone()) { - return Some(currency_id); - } - - match &location.unpack() { - (0, [Parachain(id), PalletInstance(index)]) - if (*id == parachains::moonbeam::ID) && - (*index == parachains::moonbeam::PALLET_ID) => - Some(Token2(GLMR_TOKEN_ID)), - (0, [Parachain(id), GeneralKey { data, length }]) - if *id == u32::from(ParachainInfo::parachain_id()) => - { - let key = &data[..*length as usize]; - if let Ok(currency_id) = CurrencyId::decode(&mut &key[..]) { - match currency_id { - Native(BNC) => Some(currency_id), - _ => None, - } - } else { - None - } - }, - (0, [GeneralKey { data, length }]) => { - // decode the general key - let key = &data[..*length as usize]; - if let Ok(currency_id) = CurrencyId::decode(&mut &key[..]) { - match currency_id { - Native(BNC) => Some(currency_id), - _ => None, - } - } else { - None - } - }, - _ => None, - } - } -} parameter_types! { - pub const DotLocation: Location = Location::parent(); - pub const RelayNetwork: NetworkId = Polkadot; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub SelfParaChainId: CumulusParaId = ParachainInfo::parachain_id(); - pub UniversalLocation: InteriorLocation = [GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())].into(); + // Maximum weight assigned to MessageQueue pallet to execute messages when the block is on_initialize + pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; + // Maximum weight assigned to MessageQueue pallet to execute messages when the block is on_idle + pub MessageQueueIdleServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; + // XTokens pallet BaseXcmWeight, Actually weight for an XCM message is `T::BaseXcmWeight + T::Weigher::weight(&msg)`. + pub const BaseXcmWeight: Weight = Weight::from_parts(1000_000_000u64, 0); + // XTokens pallet supports maximum number of assets to be transferred at a time + pub const MaxAssetsForTransfer: usize = 2; + // One XCM operation is 200_000_000 weight, cross-chain transfer ~= 2x of transfer = 3_000_000_000 + pub const UnitWeightCost: Weight = Weight::from_parts(200_000_000, 0); + // Maximum number of instructions that can be executed in one XCM message + pub const MaxInstructions: u32 = 100; } /// Type for specifying how a `Location` can be converted into an `AccountId`. This is used @@ -209,7 +81,7 @@ pub type LocationToAccountId = ( // Sibling parachain origins convert to AccountId via the `ParaId::into`. SiblingParachainConvertsVia, // Straight up local `AccountId32` origins just alias directly to `AccountId`. - AccountId32Aliases, + AccountId32Aliases, // Foreign locations alias into accounts according to a hash of their standard description. HashedDescription>, ); @@ -233,95 +105,36 @@ pub type XcmOriginToTransactDispatchOrigin = ( ParentAsSuperuser, // Native signed account converter; this just converts an `AccountId32` origin into a normal // `RuntimeOrigin::Signed` origin of the same 32-byte value. - SignedAccountId32AsNative, + SignedAccountId32AsNative, // Xcm origins can be represented natively under the Xcm pallet's Xcm origin. XcmPassthrough, ); -parameter_types! { - // One XCM operation is 200_000_000 weight, cross-chain transfer ~= 2x of transfer = 3_000_000_000 - pub UnitWeightCost: Weight = Weight::from_parts(200_000_000, 0); - pub const MaxInstructions: u32 = 100; -} - -/// Barrier allowing a top level paid message with DescendOrigin instruction -pub const DEFAULT_PROOF_SIZE: u64 = 64 * 1024; -pub const DEFAULT_REF_TIMR: u64 = 10_000_000_000; -pub struct AllowTopLevelPaidExecutionDescendOriginFirst(PhantomData); -impl> ShouldExecute for AllowTopLevelPaidExecutionDescendOriginFirst { - fn should_execute( - origin: &Location, - message: &mut [Instruction], - max_weight: Weight, - _weight_credit: &mut Properties, - ) -> Result<(), ProcessMessageError> { - log::trace!( - target: "xcm::barriers", - "AllowTopLevelPaidExecutionDescendOriginFirst origin: - {:?}, message: {:?}, max_weight: {:?}, weight_credit: {:?}", - origin, message, max_weight, _weight_credit, - ); - ensure!(T::contains(origin), ProcessMessageError::Unsupported); - let mut iter = message.iter_mut(); - // Make sure the first instruction is DescendOrigin - iter.next() - .filter(|instruction| matches!(instruction, DescendOrigin(_))) - .ok_or(ProcessMessageError::Unsupported)?; - - // Then WithdrawAsset - iter.next() - .filter(|instruction| matches!(instruction, WithdrawAsset(_))) - .ok_or(ProcessMessageError::Unsupported)?; - - // Then BuyExecution - let i = iter.next().ok_or(ProcessMessageError::Unsupported)?; - match i { - BuyExecution { weight_limit: Limited(ref mut weight), .. } => { - if weight.all_gte(max_weight) { - weight.set_ref_time(max_weight.ref_time()); - weight.set_proof_size(max_weight.proof_size()); - }; - }, - BuyExecution { ref mut weight_limit, .. } if weight_limit == &Unlimited => { - *weight_limit = Limited(max_weight); - }, - _ => {}, - }; - - // Then Transact - let i = iter.next().ok_or(ProcessMessageError::Unsupported)?; - match i { - Transact { ref mut require_weight_at_most, .. } => { - let weight = Weight::from_parts(DEFAULT_REF_TIMR, DEFAULT_PROOF_SIZE); - *require_weight_at_most = weight; - Ok(()) - }, - _ => Err(ProcessMessageError::Unsupported), - } - } -} - pub type Barrier = TrailingSetTopicAsId<( // Weight that is paid for may be consumed. TakeWeightCredit, // Expected responses are OK. AllowKnownQueryResponses, - // If the message is one that immediately attemps to pay for execution, then allow it. - AllowTopLevelPaidExecutionFrom, - // Subscriptions for version tracking are OK. - AllowSubscriptionsFrom, - // Barrier allowing a top level paid message with DescendOrigin instruction - AllowTopLevelPaidExecutionDescendOriginFirst, + WithComputedOrigin< + ( + // If the message is one that immediately attemps to pay for execution, then allow it. + AllowTopLevelPaidExecutionFrom, + // Subscriptions for version tracking are OK. + AllowSubscriptionsFrom, + ), + PolkadotUniversalLocation, + ConstU32<8>, + >, )>; pub type BifrostAssetTransactor = MultiCurrencyAdapter< Currencies, UnknownTokens, - BifrostAssetMatcher>, + IsNativeConcrete>, AccountId, LocationToAccountId, CurrencyId, - BifrostCurrencyIdConvert, + CurrencyIdConvert, DepositToAlternative, >; @@ -369,11 +182,9 @@ parameter_types! { pub struct ToTreasury; impl TakeRevenue for ToTreasury { fn take_revenue(revenue: Asset) { - if let Asset { id: AssetId(location), fun: xcm::v4::Fungibility::Fungible(amount) } = - revenue - { + if let Asset { id: AssetId(location), fun: Fungible(amount) } = revenue { if let Some(currency_id) = - BifrostCurrencyIdConvert::::convert(location) + CurrencyIdConvert::::convert(location) { let _ = Currencies::deposit(currency_id, &BifrostTreasuryAccount::get(), amount); } @@ -458,11 +269,11 @@ impl Contains for SafeCallFilter { bifrost_vstoken_conversion::Call::vsbond_convert_to_vstoken { .. } | bifrost_vstoken_conversion::Call::vstoken_convert_to_vsbond { .. } ) | - RuntimeCall::VeMinting( - bifrost_ve_minting::Call::increase_amount { .. } | - bifrost_ve_minting::Call::increase_unlock_time { .. } | - bifrost_ve_minting::Call::withdraw { .. } | - bifrost_ve_minting::Call::get_rewards { .. } + RuntimeCall::BbBNC( + bb_bnc::Call::increase_amount { .. } | + bb_bnc::Call::increase_unlock_time { .. } | + bb_bnc::Call::withdraw { .. } | + bb_bnc::Call::get_rewards { .. } ) | RuntimeCall::VtokenMinting( bifrost_vtoken_minting::Call::mint { .. } | @@ -484,38 +295,6 @@ impl Contains for SafeCallFilter { } } -/// Asset filter that allows all assets from a certain location matching asset id. -pub struct AssetPrefixFrom(PhantomData<(Prefix, Origin)>); -impl ContainsPair for AssetPrefixFrom -where - Prefix: Get, - Origin: Get, -{ - fn contains(asset: &Asset, origin: &Location) -> bool { - let loc = Origin::get(); - &loc == origin && - matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } - if asset_loc.starts_with(&Prefix::get())) - } -} - -/// Asset filter that allows native/relay asset if coming from a certain location. -pub struct NativeAssetFrom(PhantomData); -impl> ContainsPair for NativeAssetFrom { - fn contains(asset: &Asset, origin: &Location) -> bool { - let loc = T::get(); - &loc == origin && - matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } - if *asset_loc == Location::from(Parent)) - } -} - -parameter_types! { - /// Location of Asset Hub - pub AssetHubLocation: Location = (Parent, Parachain(1000)).into(); - pub EthereumLocation: Location = Location::new(2, [GlobalConsensus(NetworkId::Ethereum { chain_id: 1 })]); -} - pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type AssetClaims = PolkadotXcm; @@ -529,7 +308,7 @@ impl xcm_executor::Config for XcmConfig { MultiNativeAsset, ); type IsTeleporter = (); - type UniversalLocation = UniversalLocation; + type UniversalLocation = PolkadotUniversalLocation; type OriginConverter = XcmOriginToTransactDispatchOrigin; type ResponseHandler = PolkadotXcm; type SubscriptionService = PolkadotXcm; @@ -554,7 +333,7 @@ impl xcm_executor::Config for XcmConfig { } /// Local origins on this chain are allowed to dispatch XCM sends/executions. -pub type LocalOriginToLocation = SignedToAccountId32; +pub type LocalOriginToLocation = SignedToAccountId32; /// The means for routing XCM messages which are not for local execution into the right message /// queues. @@ -573,14 +352,14 @@ parameter_types! { impl pallet_xcm::Config for Runtime { type RuntimeEvent = RuntimeEvent; type ExecuteXcmOrigin = EnsureXcmOrigin; - type UniversalLocation = UniversalLocation; + type UniversalLocation = PolkadotUniversalLocation; type SendXcmOrigin = EnsureXcmOrigin; type Weigher = FixedWeightBounds; type XcmExecuteFilter = Nothing; type XcmExecutor = XcmExecutor; type XcmReserveTransferFilter = Everything; #[cfg(feature = "runtime-benchmarks")] - type XcmRouter = bifrost_primitives::DoNothingRouter; + type XcmRouter = MockXcmRouter; #[cfg(not(feature = "runtime-benchmarks"))] type XcmRouter = XcmRouter; type XcmTeleportFilter = Nothing; @@ -604,10 +383,6 @@ impl cumulus_pallet_xcm::Config for Runtime { type XcmExecutor = XcmExecutor; } -parameter_types! { - pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent; -} - impl cumulus_pallet_xcmp_queue::Config for Runtime { type ChannelInfo = ParachainSystem; type RuntimeEvent = RuntimeEvent; @@ -622,11 +397,6 @@ impl cumulus_pallet_xcmp_queue::Config for Runtime { type MaxPageSize = ConstU32<{ 103 * 1024 }>; } -parameter_types! { - pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; - pub MessageQueueIdleServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; -} - impl pallet_message_queue::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_message_queue::weights::SubstrateWeight; @@ -677,28 +447,23 @@ parameter_type_with_key! { pub struct DustRemovalWhitelist; impl Contains for DustRemovalWhitelist { fn contains(a: &AccountId) -> bool { - AccountIdConversion::::into_account_truncating(&TreasuryPalletId::get()).eq(a) || - AccountIdConversion::::into_account_truncating(&BifrostCrowdloanId::get()) - .eq(a) || AccountIdConversion::::into_account_truncating( - &BifrostVsbondPalletId::get(), - ) - .eq(a) || AccountIdConversion::::into_account_truncating( - &SlpEntrancePalletId::get(), - ) - .eq(a) || AccountIdConversion::::into_account_truncating(&SlpExitPalletId::get()) - .eq(a) || FarmingKeeperPalletId::get().check_sub_account::(a) || + let whitelist: Vec = vec![ + TreasuryPalletId::get().into_account_truncating(), + BifrostCrowdloanId::get().into_account_truncating(), + BifrostVsbondPalletId::get().into_account_truncating(), + SlpEntrancePalletId::get().into_account_truncating(), + SlpExitPalletId::get().into_account_truncating(), + BuybackPalletId::get().into_account_truncating(), + SystemMakerPalletId::get().into_account_truncating(), + ZenklinkFeeAccount::get(), + CommissionPalletId::get().into_account_truncating(), + BuyBackAccount::get().into_account_truncating(), + LiquidityAccount::get().into_account_truncating(), + ]; + whitelist.contains(a) || + FarmingKeeperPalletId::get().check_sub_account::(a) || FarmingRewardIssuerPalletId::get().check_sub_account::(a) || - AccountIdConversion::::into_account_truncating(&BuybackPalletId::get()) - .eq(a) || AccountIdConversion::::into_account_truncating( - &SystemMakerPalletId::get(), - ) - .eq(a) || FeeSharePalletId::get().check_sub_account::(a) || - a.eq(&ZenklinkFeeAccount::get()) || - AccountIdConversion::::into_account_truncating(&CommissionPalletId::get()) - .eq(a) || AccountIdConversion::::into_account_truncating(&BuyBackAccount::get()) - .eq(a) || - AccountIdConversion::::into_account_truncating(&LiquidityAccount::get()) - .eq(a) + FeeSharePalletId::get().check_sub_account::(a) } } @@ -734,13 +499,6 @@ impl orml_tokens::Config for Runtime { type CurrencyHooks = CurrencyHooks; } -parameter_types! { - pub SelfLocation: Location = Location::new(1, [Parachain(ParachainInfo::get().into())]); - pub SelfRelativeLocation: Location = Location::here(); - pub const BaseXcmWeight: Weight = Weight::from_parts(1000_000_000u64, 0); - pub const MaxAssetsForTransfer: usize = 2; -} - parameter_type_with_key! { pub ParachainMinFee: |_location: Location| -> Option { Some(u128::MAX) @@ -751,10 +509,10 @@ impl orml_xtokens::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type CurrencyId = CurrencyId; - type CurrencyIdConvert = BifrostCurrencyIdConvert; - type AccountIdToLocation = BifrostAccountIdToLocation; - type UniversalLocation = UniversalLocation; - type SelfLocation = SelfRelativeLocation; + type CurrencyIdConvert = CurrencyIdConvert; + type AccountIdToLocation = AccountIdToLocation; + type UniversalLocation = PolkadotUniversalLocation; + type SelfLocation = SelfLocation; type XcmExecutor = XcmExecutor; type Weigher = FixedWeightBounds; type BaseXcmWeight = BaseXcmWeight; @@ -783,13 +541,13 @@ impl bifrost_xcm_interface::Config for Runtime { type RuntimeEvent = RuntimeEvent; type UpdateOrigin = TechAdminOrCouncil; type MultiCurrency = Currencies; - type RelayNetwork = RelayNetwork; + type RelayNetwork = PolkadotNetwork; type RelaychainCurrencyId = RelayCurrencyId; type ParachainSovereignAccount = ParachainAccount; type XcmExecutor = XcmExecutor; - type AccountIdToLocation = BifrostAccountIdToLocation; + type AccountIdToLocation = AccountIdToLocation; type SalpHelper = Salp; - type ParachainId = SelfParaChainId; + type ParachainId = ParachainInfo; type CallBackTimeOut = ConstU32<10>; type CurrencyIdConvert = AssetIdMaps; } diff --git a/runtime/common/src/currency_adapter.rs b/runtime/common/src/currency_adapter.rs index a928942cd..82f5d48af 100644 --- a/runtime/common/src/currency_adapter.rs +++ b/runtime/common/src/currency_adapter.rs @@ -1,3 +1,21 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + use frame_support::traits::Get; use orml_xcm_support::UnknownAsset as UnknownAssetT; use parity_scale_codec::FullCodec; diff --git a/runtime/common/src/currency_converter.rs b/runtime/common/src/currency_converter.rs new file mode 100644 index 000000000..fd2276e04 --- /dev/null +++ b/runtime/common/src/currency_converter.rs @@ -0,0 +1,59 @@ +// This file is part of Bifrost. + +// Copyright (C) Liebi Technologies PTE. LTD. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use bifrost_asset_registry::AssetIdMaps; +use bifrost_primitives::{CurrencyId, CurrencyIdMapping}; +use cumulus_primitives_core::ParaId; +use frame_support::traits::Get; +use sp_runtime::traits::Convert; +use sp_std::{marker::PhantomData, prelude::*}; +use xcm::{ + latest::{AssetId, Location}, + prelude::Fungible, + v4::Asset, +}; + +pub struct CurrencyIdConvert(PhantomData<(T, R)>); +/// Convert CurrencyId to Location +impl, R: bifrost_asset_registry::Config> Convert> + for CurrencyIdConvert +{ + fn convert(id: CurrencyId) -> Option { + AssetIdMaps::::get_location(id) + } +} +/// Convert Location to CurrencyId +impl, R: bifrost_asset_registry::Config> Convert> + for CurrencyIdConvert +{ + fn convert(location: Location) -> Option { + AssetIdMaps::::get_currency_id(location.clone()) + } +} +/// Convert Asset to CurrencyId +impl, R: bifrost_asset_registry::Config> Convert> + for CurrencyIdConvert +{ + fn convert(asset: Asset) -> Option { + if let Asset { id: AssetId(id), fun: Fungible(_) } = asset { + Self::convert(id) + } else { + None + } + } +} diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 9c5a0b7c7..4b44c00e4 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -31,6 +31,7 @@ use sp_runtime::{traits::Bounded, FixedPointNumber, Perquintill}; pub mod constants; pub mod currency_adapter; +pub mod currency_converter; pub mod price; pub mod ratio; diff --git a/runtime/common/src/price.rs b/runtime/common/src/price.rs index 9b0747d18..cbdbc3483 100644 --- a/runtime/common/src/price.rs +++ b/runtime/common/src/price.rs @@ -20,7 +20,10 @@ use frame_support::{ pallet_prelude::Get, traits::tokens::{Fortitude, Preservation}, }; -use sp_runtime::{helpers_128bit::multiply_by_rational_with_rounding, traits::Convert, Rounding}; +use sp_core::U256; +use sp_runtime::{ + helpers_128bit::multiply_by_rational_with_rounding, traits::Convert, DispatchError, Rounding, +}; use sp_std::marker::PhantomData; use xcm::latest::Weight; @@ -67,21 +70,27 @@ where >, { type Output = (Balance, Weight); - - fn get_balance_in_currency(to_currency: CurrencyId, account: &T::AccountId) -> Self::Output { - let from_currency = AC::get(account); + type Error = DispatchError; + + fn get_balance_in_currency( + to_currency: CurrencyId, + account: &T::AccountId, + fee: U256, + ) -> Result { + let from_currency = AC::get_fee_currency(account, fee) + .map_err(|_| DispatchError::Other("Get Currency Error."))?; let account_balance = I::reducible_balance(from_currency, account, Preservation::Preserve, Fortitude::Polite); let price_weight = T::DbWeight::get().reads(2); // 1 read to get currency and 1 read to get balance if from_currency == to_currency { - return (account_balance, price_weight); + return Ok((account_balance, price_weight)); } let Some((converted, _)) = C::convert((from_currency, to_currency, account_balance)) else { - return (0, price_weight); + return Ok((0, price_weight)); }; - (converted, price_weight) + Ok((converted, price_weight)) } }