diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 9aa1b30dee..f400138b27 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -27,10 +27,12 @@ jobs: - uses: actions/checkout@v3 with: submodules: recursive + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Login to GitHub Container Registry - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} @@ -47,10 +49,14 @@ jobs: type=ref,event=branch type=ref,event=pr type=sha + - name: Change Dockerfile to support multi-platform + run: | + sed -i 's/FROM /FROM --platform=$BUILDPLATFORM /g' scripts/Dockerfile - name: Build and push Docker image - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v3 with: context: . + platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/Cargo.lock b/Cargo.lock index eaa389acc3..acc4051ab6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,7 +14,7 @@ dependencies = [ [[package]] name = "acala" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-cli", "acala-service", @@ -24,7 +24,7 @@ dependencies = [ [[package]] name = "acala-cli" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-inspect", "acala-service", @@ -51,7 +51,7 @@ dependencies = [ [[package]] name = "acala-inspect" -version = "2.6.4" +version = "2.7.0" dependencies = [ "clap 3.1.18", "derive_more", @@ -67,7 +67,7 @@ dependencies = [ [[package]] name = "acala-primitives" -version = "2.6.4" +version = "2.7.0" dependencies = [ "bstringify", "enumflags2 0.6.4", @@ -93,7 +93,7 @@ dependencies = [ [[package]] name = "acala-rpc" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "evm-rpc", @@ -118,7 +118,7 @@ dependencies = [ [[package]] name = "acala-runtime" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "cumulus-pallet-aura-ext", @@ -233,7 +233,7 @@ dependencies = [ [[package]] name = "acala-service" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "acala-rpc", @@ -2678,7 +2678,7 @@ checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" [[package]] name = "e2e-tests" -version = "2.6.4" +version = "2.7.0" dependencies = [ "test-service", ] @@ -2697,7 +2697,7 @@ dependencies = [ [[package]] name = "ecosystem-compound-cash" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -2714,7 +2714,7 @@ dependencies = [ [[package]] name = "ecosystem-renvm-bridge" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -2736,7 +2736,7 @@ dependencies = [ [[package]] name = "ecosystem-starport" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -3024,7 +3024,7 @@ dependencies = [ [[package]] name = "evm-rpc" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -4327,7 +4327,7 @@ dependencies = [ [[package]] name = "karura-runtime" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "cumulus-pallet-aura-ext", @@ -5352,7 +5352,7 @@ dependencies = [ [[package]] name = "mandala-runtime" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "acala-service", @@ -5641,7 +5641,7 @@ dependencies = [ [[package]] name = "module-aggregated-dex" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -5663,7 +5663,7 @@ dependencies = [ [[package]] name = "module-asset-registry" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -5685,13 +5685,11 @@ dependencies = [ "sp-runtime", "sp-std", "xcm", - "xcm-builder", - "xcm-executor", ] [[package]] name = "module-auction-manager" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -5715,7 +5713,7 @@ dependencies = [ [[package]] name = "module-cdp-engine" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -5744,7 +5742,7 @@ dependencies = [ [[package]] name = "module-cdp-treasury" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -5768,7 +5766,7 @@ dependencies = [ [[package]] name = "module-collator-selection" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-benchmarking", @@ -5794,7 +5792,7 @@ dependencies = [ [[package]] name = "module-currencies" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -5821,7 +5819,7 @@ dependencies = [ [[package]] name = "module-dex" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -5841,7 +5839,7 @@ dependencies = [ [[package]] name = "module-dex-oracle" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-benchmarking", @@ -5861,7 +5859,7 @@ dependencies = [ [[package]] name = "module-earning" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -5881,7 +5879,7 @@ dependencies = [ [[package]] name = "module-emergency-shutdown" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -5904,7 +5902,7 @@ dependencies = [ [[package]] name = "module-evm" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "env_logger", @@ -5943,7 +5941,7 @@ dependencies = [ [[package]] name = "module-evm-accounts" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -5966,7 +5964,7 @@ dependencies = [ [[package]] name = "module-evm-bridge" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "ethereum-types", @@ -5993,7 +5991,7 @@ dependencies = [ [[package]] name = "module-evm-rpc-runtime-api" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "sp-api", @@ -6004,7 +6002,7 @@ dependencies = [ [[package]] name = "module-evm-utility" -version = "2.6.4" +version = "2.7.0" dependencies = [ "ethereum", "evm", @@ -6016,7 +6014,7 @@ dependencies = [ [[package]] name = "module-evm-utility-macro" -version = "2.6.4" +version = "2.7.0" dependencies = [ "module-evm-utility", "proc-macro2", @@ -6026,7 +6024,7 @@ dependencies = [ [[package]] name = "module-example" -version = "2.6.4" +version = "2.7.0" dependencies = [ "frame-support", "frame-system", @@ -6040,7 +6038,7 @@ dependencies = [ [[package]] name = "module-homa" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-benchmarking", @@ -6063,7 +6061,7 @@ dependencies = [ [[package]] name = "module-homa-lite" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "cumulus-primitives-core", @@ -6090,7 +6088,7 @@ dependencies = [ [[package]] name = "module-homa-validator-list" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -6112,7 +6110,7 @@ dependencies = [ [[package]] name = "module-honzon" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -6137,7 +6135,7 @@ dependencies = [ [[package]] name = "module-honzon-bridge" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -6158,7 +6156,7 @@ dependencies = [ [[package]] name = "module-idle-scheduler" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -6175,7 +6173,7 @@ dependencies = [ [[package]] name = "module-incentives" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -6196,7 +6194,7 @@ dependencies = [ [[package]] name = "module-loans" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -6218,7 +6216,7 @@ dependencies = [ [[package]] name = "module-nft" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-benchmarking", @@ -6243,7 +6241,7 @@ dependencies = [ [[package]] name = "module-nominees-election" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -6264,7 +6262,7 @@ dependencies = [ [[package]] name = "module-prices" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -6283,7 +6281,7 @@ dependencies = [ [[package]] name = "module-relaychain" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "cumulus-primitives-core", @@ -6301,7 +6299,7 @@ dependencies = [ [[package]] name = "module-session-manager" -version = "2.6.4" +version = "2.7.0" dependencies = [ "frame-support", "frame-system", @@ -6318,7 +6316,7 @@ dependencies = [ [[package]] name = "module-support" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -6335,7 +6333,7 @@ dependencies = [ [[package]] name = "module-transaction-pause" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -6354,7 +6352,7 @@ dependencies = [ [[package]] name = "module-transaction-payment" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "frame-support", @@ -6376,13 +6374,11 @@ dependencies = [ "sp-runtime", "sp-std", "xcm", - "xcm-builder", - "xcm-executor", ] [[package]] name = "module-xcm-interface" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "cumulus-primitives-core", @@ -10627,7 +10623,7 @@ dependencies = [ [[package]] name = "runtime-common" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "cumulus-pallet-parachain-system", @@ -10635,6 +10631,7 @@ dependencies = [ "frame-support", "frame-system", "hex-literal", + "log", "module-asset-registry", "module-cdp-engine", "module-cdp-treasury", @@ -10686,7 +10683,7 @@ dependencies = [ [[package]] name = "runtime-integration-tests" -version = "2.6.4" +version = "2.7.0" dependencies = [ "acala-primitives", "acala-runtime", diff --git a/README.md b/README.md index 09d0a73afc..7b334378b8 100644 --- a/README.md +++ b/README.md @@ -213,7 +213,10 @@ yarn # generate docker-compose.yml and genesis # NOTE: If the docker image is not the latest, need to download it manually. # e.g.: docker pull acala/karura-node:latest -yarn run start generate +# karura testnet: +yarn start generate +# karura-bifrost testnet: +yarn start generate --config=karura-bifrost.yml # start relaychain and parachain cd output diff --git a/ecosystem-modules/compound-cash/Cargo.toml b/ecosystem-modules/compound-cash/Cargo.toml index d0bacc05f0..ae4d48c31c 100644 --- a/ecosystem-modules/compound-cash/Cargo.toml +++ b/ecosystem-modules/compound-cash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ecosystem-compound-cash" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/ecosystem-modules/ren/renvm-bridge/Cargo.toml b/ecosystem-modules/ren/renvm-bridge/Cargo.toml index d49ed74be5..07aaca5c1d 100644 --- a/ecosystem-modules/ren/renvm-bridge/Cargo.toml +++ b/ecosystem-modules/ren/renvm-bridge/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ecosystem-renvm-bridge" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/ecosystem-modules/starport/Cargo.toml b/ecosystem-modules/starport/Cargo.toml index 175e4655ad..24cc419cb1 100644 --- a/ecosystem-modules/starport/Cargo.toml +++ b/ecosystem-modules/starport/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ecosystem-starport" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/inspect/Cargo.toml b/inspect/Cargo.toml index f2e32588e3..edc0084a5b 100644 --- a/inspect/Cargo.toml +++ b/inspect/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "acala-inspect" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/launch/config.yml b/launch/config.yml index a2a170a199..bcea69e3f3 100644 --- a/launch/config.yml +++ b/launch/config.yml @@ -1,5 +1,5 @@ relaychain: - image: parity/polkadot:v0.9.18 + image: parity/polkadot:v0.9.22 chain: rococo-local runtimeGenesisConfig: configuration: @@ -18,7 +18,7 @@ relaychain: - name: charlie parachains: -- image: acala/karura-node:2.5.0 +- image: acala/karura-node:2.7.0 chain: base: karura-dev collators: diff --git a/launch/karura-bifrost.yml b/launch/karura-bifrost.yml new file mode 100644 index 0000000000..b81490df79 --- /dev/null +++ b/launch/karura-bifrost.yml @@ -0,0 +1,72 @@ +relaychain: + image: parity/polkadot:v0.9.22 + chain: rococo-local + runtimeGenesisConfig: + configuration: + config: + validation_upgrade_cooldown: 10 + validation_upgrade_delay: 10 + env: + RUST_LOG: parachain::candidate-backing=trace,parachain::candidate-selection=trace,parachain::pvf=trace,parachain::collator-protocol=trace,parachain::provisioner=trace + flags: + - --rpc-methods=unsafe + - --wasm-execution=compiled + - --execution=wasm + nodes: + - name: alice + - name: bob + - name: charlie + +parachains: +- image: acala/karura-node:2.7.0 + chain: + base: karura-dev + collators: + - alice + - bob + - charlie + sudo: alice + id: 2000 + parachain: true + flags: + - --rpc-methods=unsafe + - --force-authoring + - --wasm-execution=compiled + - --execution=wasm + relaychainFlags: + - --wasm-execution=compiled + - --execution=wasm + env: + RUST_LOG: sc_basic_authorship=trace,cumulus-consensus=trace,cumulus-collator=trace,collator_protocol=trace,collation_generation=trace,aura=debug + volumePath: /acala/data + nodes: + - flags: + - --alice + - flags: + - --bob + - flags: + - --charlie +- image: bifrostnetwork/bifrost:bifrost-v0.9.44 + chain: + base: bifrost-local + sudo: alice + id: 3000 + parachain: true + flags: + - --rpc-methods=unsafe + - --force-authoring + - --wasm-execution=compiled + - --execution=wasm + relaychainFlags: + - --wasm-execution=compiled + - --execution=wasm + env: + RUST_LOG: sc_basic_authorship=trace,cumulus-consensus=trace,cumulus-collator=trace,collator_protocol=trace,collation_generation=trace,aura=debug + volumePath: /data + nodes: + - flags: + - --alice + - flags: + - --bob + - flags: + - --charlie diff --git a/launch/package.json b/launch/package.json index 424c9d6fbe..b42a5ff959 100644 --- a/launch/package.json +++ b/launch/package.json @@ -7,6 +7,6 @@ "start": "node_modules/@open-web3/parachain-launch/bin/parachain-launch" }, "dependencies": { - "@open-web3/parachain-launch": "^1.0.6" + "@open-web3/parachain-launch": "^1.2.1" } } diff --git a/launch/yarn.lock b/launch/yarn.lock index 2dd86ff9f6..c971c256e7 100644 --- a/launch/yarn.lock +++ b/launch/yarn.lock @@ -2,240 +2,379 @@ # yarn lockfile v1 -"@babel/runtime@^7.15.3", "@babel/runtime@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a" - integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw== +"@babel/runtime@^7.17.8": + version "7.18.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.3.tgz#c7b654b57f6f63cf7f8b418ac9ca04408c4579f4" + integrity sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug== dependencies: regenerator-runtime "^0.13.4" -"@open-web3/parachain-launch@^1.0.6": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@open-web3/parachain-launch/-/parachain-launch-1.0.6.tgz#e8660fb408570165bd6ff578b0744c7f2961c039" - integrity sha512-sZ+HB+v7cPpWpyKj3d83r9yT2yPr5Luz1J8ftVXp6t8kuPbldYWgOHYlMeOqK0vgYI7sPZkOPNrCb9j4rrgC5A== - dependencies: - "@polkadot/api" "^5.6.1" - "@polkadot/keyring" "^7.2.1" - "@polkadot/util" "^7.2.1" - "@polkadot/util-crypto" "^7.2.1" +"@noble/hashes@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.0.0.tgz#d5e38bfbdaba174805a4e649f13be9a9ed3351ae" + integrity sha512-DZVbtY62kc3kkBtMHqwCOfXrT/hnoORy5BJ4+HU1IR59X0KWAOqsfzQPcUl/lQLlG7qXbe/fZ3r/emxtAl+sqg== + +"@noble/secp256k1@1.5.5": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.5.5.tgz#315ab5745509d1a8c8e90d0bdf59823ccf9bcfc3" + integrity sha512-sZ1W6gQzYnu45wPrWx8D3kwI2/U29VYTx9OjbDAd7jwRItJ0cSTMPRL/C8AWZFn9kWFLQGqEXVEE86w4Z8LpIQ== + +"@open-web3/parachain-launch@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@open-web3/parachain-launch/-/parachain-launch-1.2.1.tgz#39dbc077c4ae2063ce25eb5a8a00f0ab0f5fa225" + integrity sha512-zpKUP/TX41e+e59532M/P7mZpjW6A75QlS9TfPrrG0AZarSPlVvDajYJyXQ6U3p7mi2Onk6AsgJ54KFmIXVf+A== + dependencies: + "@polkadot/api" "^7.15.1" + "@polkadot/keyring" "^8.4.1" + "@polkadot/util" "^8.4.1" + "@polkadot/util-crypto" "^8.4.1" lodash "^4.17.21" readline-sync "^1.4.10" - shelljs "^0.8.4" + shelljs "^0.8.5" yaml "^1.10.2" - yargs "^17.0.1" - -"@polkadot/api-derive@5.8.3": - version "5.8.3" - resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-5.8.3.tgz#56915bddce9ebe09137d8999c1cd39447c4dda74" - integrity sha512-+bO8Dap3LknoxEP5X6IpIueU9wuLHC9EVNE/1PYIabiwOeMKA3TQR2yAPDnd6GhAc9mg/M0zl+zkzkYHfJ9X8g== - dependencies: - "@babel/runtime" "^7.15.4" - "@polkadot/api" "5.8.3" - "@polkadot/rpc-core" "5.8.3" - "@polkadot/types" "5.8.3" - "@polkadot/util" "^7.3.1" - "@polkadot/util-crypto" "^7.3.1" - rxjs "^7.3.0" - -"@polkadot/api@5.8.3", "@polkadot/api@^5.6.1": - version "5.8.3" - resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-5.8.3.tgz#36440c47e6daf6bd71f5af66768fe6703f134028" - integrity sha512-O7sOUTNfMl0loHwK+WisJH36qw/EACeK9pPPh4bk9Gftda4j0JbGYSUnf59F9QjddkkwstOXbbQSRVM6JTQ7Yw== - dependencies: - "@babel/runtime" "^7.15.4" - "@polkadot/api-derive" "5.8.3" - "@polkadot/keyring" "^7.3.1" - "@polkadot/rpc-core" "5.8.3" - "@polkadot/rpc-provider" "5.8.3" - "@polkadot/types" "5.8.3" - "@polkadot/types-known" "5.8.3" - "@polkadot/util" "^7.3.1" - "@polkadot/util-crypto" "^7.3.1" + yargs "^17.4.0" + +"@polkadot/api-augment@7.15.1": + version "7.15.1" + resolved "https://registry.yarnpkg.com/@polkadot/api-augment/-/api-augment-7.15.1.tgz#120b766feeaa96996f1c6717a5261c2e0845c1e0" + integrity sha512-7csQLS6zuYuGq7W1EkTBz1ZmxyRvx/Qpz7E7zPSwxmY8Whb7Yn2effU9XF0eCcRpyfSW8LodF8wMmLxGYs1OaQ== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/api-base" "7.15.1" + "@polkadot/rpc-augment" "7.15.1" + "@polkadot/types" "7.15.1" + "@polkadot/types-augment" "7.15.1" + "@polkadot/types-codec" "7.15.1" + "@polkadot/util" "^8.7.1" + +"@polkadot/api-base@7.15.1": + version "7.15.1" + resolved "https://registry.yarnpkg.com/@polkadot/api-base/-/api-base-7.15.1.tgz#7567595be68431cc4085c48b18ba66933ff7b4d9" + integrity sha512-UlhLdljJPDwGpm5FxOjvJNFTxXMRFaMuVNx6EklbuetbBEJ/Amihhtj0EJRodxQwtZ4ZtPKYKt+g+Dn7OJJh4g== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/rpc-core" "7.15.1" + "@polkadot/types" "7.15.1" + "@polkadot/util" "^8.7.1" + rxjs "^7.5.5" + +"@polkadot/api-derive@7.15.1": + version "7.15.1" + resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-7.15.1.tgz#450542bb7d848013225d6c8480648340e5ee6a61" + integrity sha512-CsOQppksQBaa34L1fWRzmfQQpoEBwfH0yTTQxgj3h7rFYGVPxEKGeFjo1+IgI2vXXvOO73Z8E4H/MnbxvKrs1Q== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/api" "7.15.1" + "@polkadot/api-augment" "7.15.1" + "@polkadot/api-base" "7.15.1" + "@polkadot/rpc-core" "7.15.1" + "@polkadot/types" "7.15.1" + "@polkadot/types-codec" "7.15.1" + "@polkadot/util" "^8.7.1" + "@polkadot/util-crypto" "^8.7.1" + rxjs "^7.5.5" + +"@polkadot/api@7.15.1", "@polkadot/api@^7.15.1": + version "7.15.1" + resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-7.15.1.tgz#24eaeaa8ffbc6f30ff3d9846a816a18a688ceb8b" + integrity sha512-z0z6+k8+R9ixRMWzfsYrNDnqSV5zHKmyhTCL0I7+1I081V18MJTCFUKubrh0t1gD0/FCt3U9Ibvr4IbtukYLrQ== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/api-augment" "7.15.1" + "@polkadot/api-base" "7.15.1" + "@polkadot/api-derive" "7.15.1" + "@polkadot/keyring" "^8.7.1" + "@polkadot/rpc-augment" "7.15.1" + "@polkadot/rpc-core" "7.15.1" + "@polkadot/rpc-provider" "7.15.1" + "@polkadot/types" "7.15.1" + "@polkadot/types-augment" "7.15.1" + "@polkadot/types-codec" "7.15.1" + "@polkadot/types-create" "7.15.1" + "@polkadot/types-known" "7.15.1" + "@polkadot/util" "^8.7.1" + "@polkadot/util-crypto" "^8.7.1" eventemitter3 "^4.0.7" - rxjs "^7.3.0" - -"@polkadot/keyring@^7.2.1", "@polkadot/keyring@^7.3.1": - version "7.3.1" - resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-7.3.1.tgz#bf36115cfb395567bec9cf13c8e3fc0fb39c802a" - integrity sha512-3lbwIjUql8yjs6AR2fMdCgmTc5D9ne7+y2jqHmGjyzVQFz1w1jiHb+N38L0pwl9/23UxmzC3aVvHLfl3gEGSIQ== - dependencies: - "@babel/runtime" "^7.15.3" - "@polkadot/util" "7.3.1" - "@polkadot/util-crypto" "7.3.1" - -"@polkadot/networks@7.3.1", "@polkadot/networks@^7.3.1": - version "7.3.1" - resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-7.3.1.tgz#4d4f7269ff9c285363946175ca95d6aaa08bdacc" - integrity sha512-sK9TyVf1aAWy84usKjNqb6rNiy4UB6cK3iM+bfltzrLHdchjAMPdxMqULNBL8MXjrnuzPpTtsdkGFqp5P69oIQ== - dependencies: - "@babel/runtime" "^7.15.3" - -"@polkadot/rpc-core@5.8.3": - version "5.8.3" - resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-5.8.3.tgz#a9a489c8ba1cf2779a7dc76b96195386c44d77f8" - integrity sha512-/QMPb1uCXJLxHTAG/KVr0TWkJ1tgwB8xOB0Fe57tFaFmQ8bq4e08iHUVH1nzpyKAS35kGhov+W7YqdJffFL9vQ== - dependencies: - "@babel/runtime" "^7.15.4" - "@polkadot/rpc-provider" "5.8.3" - "@polkadot/types" "5.8.3" - "@polkadot/util" "^7.3.1" - rxjs "^7.3.0" - -"@polkadot/rpc-provider@5.8.3": - version "5.8.3" - resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-5.8.3.tgz#7097e2a9e5a3dfa5e525dec030d6a5595ae7cd2a" - integrity sha512-wJ18uzwG6PpgZ3My6C3puqvxXGsTwFXzeYoGZOH1Yj6CEZIufiTedN6AUqoWx2OQIPj0QPf9ZX9bWahpjDhUSA== - dependencies: - "@babel/runtime" "^7.15.4" - "@polkadot/types" "5.8.3" - "@polkadot/util" "^7.3.1" - "@polkadot/util-crypto" "^7.3.1" - "@polkadot/x-fetch" "^7.3.1" - "@polkadot/x-global" "^7.3.1" - "@polkadot/x-ws" "^7.3.1" + rxjs "^7.5.5" + +"@polkadot/keyring@^8.4.1", "@polkadot/keyring@^8.7.1": + version "8.7.1" + resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-8.7.1.tgz#07cf6d6ee351dcf70fbf965b1d6d96c5025ae1b8" + integrity sha512-t6ZgQVC+nQT7XwbWtEhkDpiAzxKVJw8Xd/gWdww6xIrawHu7jo3SGB4QNdPgkf8TvDHYAAJiupzVQYAlOIq3GA== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/util" "8.7.1" + "@polkadot/util-crypto" "8.7.1" + +"@polkadot/networks@8.7.1", "@polkadot/networks@^8.7.1": + version "8.7.1" + resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-8.7.1.tgz#26c2ec6158c985bb77c510d98a3ab1c7e049f89c" + integrity sha512-8xAmhDW0ry5EKcEjp6VTuwoTm0DdDo/zHsmx88P6sVL87gupuFsL+B6TrsYLl8GcaqxujwrOlKB+CKTUg7qFKg== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/util" "8.7.1" + "@substrate/ss58-registry" "^1.17.0" + +"@polkadot/rpc-augment@7.15.1": + version "7.15.1" + resolved "https://registry.yarnpkg.com/@polkadot/rpc-augment/-/rpc-augment-7.15.1.tgz#391a42a9c3e553335a2a544598a717b47654ad6e" + integrity sha512-sK0+mphN7nGz/eNPsshVi0qd0+N0Pqxuebwc1YkUGP0f9EkDxzSGp6UjGcSwWVaAtk9WZZ1MpK1Jwb/2GrKV7Q== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/rpc-core" "7.15.1" + "@polkadot/types" "7.15.1" + "@polkadot/types-codec" "7.15.1" + "@polkadot/util" "^8.7.1" + +"@polkadot/rpc-core@7.15.1": + version "7.15.1" + resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-7.15.1.tgz#47855cf05bd2f8dbf87d9f1f77343114e61c664a" + integrity sha512-4Sb0e0PWmarCOizzxQAE1NQSr5z0n+hdkrq3+aPohGu9Rh4PodG+OWeIBy7Ov/3GgdhNQyBLG+RiVtliXecM3g== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/rpc-augment" "7.15.1" + "@polkadot/rpc-provider" "7.15.1" + "@polkadot/types" "7.15.1" + "@polkadot/util" "^8.7.1" + rxjs "^7.5.5" + +"@polkadot/rpc-provider@7.15.1": + version "7.15.1" + resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-7.15.1.tgz#a213de907a6f4f480c3c819aa95e4e60d4247f84" + integrity sha512-n0RWfSaD/r90JXeJkKry1aGZwJeBUUiMpXUQ9Uvp6DYBbYEDs0fKtWLpdT3PdFrMbe5y3kwQmNLxwe6iF4+mzg== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/keyring" "^8.7.1" + "@polkadot/types" "7.15.1" + "@polkadot/types-support" "7.15.1" + "@polkadot/util" "^8.7.1" + "@polkadot/util-crypto" "^8.7.1" + "@polkadot/x-fetch" "^8.7.1" + "@polkadot/x-global" "^8.7.1" + "@polkadot/x-ws" "^8.7.1" + "@substrate/connect" "0.7.0-alpha.0" eventemitter3 "^4.0.7" - -"@polkadot/types-known@5.8.3": - version "5.8.3" - resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-5.8.3.tgz#c666ba5493bdca346f8bc4f690cbff62468ef1f9" - integrity sha512-C02xTOfr8u/hPszaGcBVhZdYgPw+rc3SMU9vbe4hziq5VGTinhfX0Sy6Ixa+GO7f31nJVIYyuLCeglCfN0rgFQ== - dependencies: - "@babel/runtime" "^7.15.4" - "@polkadot/networks" "^7.3.1" - "@polkadot/types" "5.8.3" - "@polkadot/util" "^7.3.1" - -"@polkadot/types@5.8.3": - version "5.8.3" - resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-5.8.3.tgz#9f37fe9a2dc30491bae671ba4e31e6d1a3c626ed" - integrity sha512-iSVCk7Ja8WjLOpjPtZRo9Gaz9AS/b722LH3wWo91TSMT11Vz/lYCWlagNc1nVez6sRsJoEXjD7pKA0ga0t78Lw== - dependencies: - "@babel/runtime" "^7.15.4" - "@polkadot/util" "^7.3.1" - "@polkadot/util-crypto" "^7.3.1" - rxjs "^7.3.0" - -"@polkadot/util-crypto@7.3.1", "@polkadot/util-crypto@^7.2.1", "@polkadot/util-crypto@^7.3.1": - version "7.3.1" - resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-7.3.1.tgz#a597145b061eddaafd69adc6c1ce19224542307f" - integrity sha512-sR+BxlV2Da0xfQcCXQTz+ohTaagixM+qYHytaQzilytbKHgYIyvnOyk5wFrHDNFzcLuXo15AbULa3TCoNDvh5Q== - dependencies: - "@babel/runtime" "^7.15.3" - "@polkadot/networks" "7.3.1" - "@polkadot/util" "7.3.1" - "@polkadot/wasm-crypto" "^4.2.1" - "@polkadot/x-randomvalues" "7.3.1" - base-x "^3.0.8" - base64-js "^1.5.1" - blakejs "^1.1.1" - bn.js "^4.12.0" - create-hash "^1.2.0" + mock-socket "^9.1.2" + nock "^13.2.4" + +"@polkadot/types-augment@7.15.1": + version "7.15.1" + resolved "https://registry.yarnpkg.com/@polkadot/types-augment/-/types-augment-7.15.1.tgz#437047f961b8d29e5ffd4fd59cd35f0e6374750b" + integrity sha512-aqm7xT/66TCna0I2utpIekoquKo0K5pnkA/7WDzZ6gyD8he2h0IXfe8xWjVmuyhjxrT/C/7X1aUF2Z0xlOCwzQ== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/types" "7.15.1" + "@polkadot/types-codec" "7.15.1" + "@polkadot/util" "^8.7.1" + +"@polkadot/types-codec@7.15.1": + version "7.15.1" + resolved "https://registry.yarnpkg.com/@polkadot/types-codec/-/types-codec-7.15.1.tgz#c0155867efd3ae35e15fea6a8aab49c2c63988fa" + integrity sha512-nI11dT7FGaeDd/fKPD8iJRFGhosOJoyjhZ0gLFFDlKCaD3AcGBRTTY8HFJpP/5QXXhZzfZsD93fVKrosnegU0Q== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/util" "^8.7.1" + +"@polkadot/types-create@7.15.1": + version "7.15.1" + resolved "https://registry.yarnpkg.com/@polkadot/types-create/-/types-create-7.15.1.tgz#ec4cafa314a82a25a109f0f52207e9169fc9b003" + integrity sha512-+HiaHn7XOwP0kv/rVdORlVkNuMoxuvt+jd67A/CeEreJiXqRLu+S61Mdk7wi6719PTaOal1hTDFfyGrtUd8FSQ== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/types-codec" "7.15.1" + "@polkadot/util" "^8.7.1" + +"@polkadot/types-known@7.15.1": + version "7.15.1" + resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-7.15.1.tgz#71dbf0835a48cdc97d0f50b0000298687e29818d" + integrity sha512-LMcNP0CxT84DqAKV62/qDeeIVIJCR5yzE9b+9AsYhyfhE4apwxjrThqZA7K0CF56bOdQJSexAerYB/jwk2IijA== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/networks" "^8.7.1" + "@polkadot/types" "7.15.1" + "@polkadot/types-codec" "7.15.1" + "@polkadot/types-create" "7.15.1" + "@polkadot/util" "^8.7.1" + +"@polkadot/types-support@7.15.1": + version "7.15.1" + resolved "https://registry.yarnpkg.com/@polkadot/types-support/-/types-support-7.15.1.tgz#9c274759647dd89d46ea9cf74d593bcedcd85527" + integrity sha512-FIK251ffVo+NaUXLlaJeB5OvT7idDd3uxaoBM6IwsS87rzt2CcWMyCbu0uX89AHZUhSviVx7xaBxfkGEqMePWA== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/util" "^8.7.1" + +"@polkadot/types@7.15.1": + version "7.15.1" + resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-7.15.1.tgz#fb78886f4437fbc472e01019846fb1f229d2a177" + integrity sha512-KawZVS+eLR1D6O7c/P5cSUwr6biM9Qd2KwKtJIO8l1Mrxp7r+y2tQnXSSXVAd6XPdb3wVMhnIID+NW3W99TAnQ== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/keyring" "^8.7.1" + "@polkadot/types-augment" "7.15.1" + "@polkadot/types-codec" "7.15.1" + "@polkadot/types-create" "7.15.1" + "@polkadot/util" "^8.7.1" + "@polkadot/util-crypto" "^8.7.1" + rxjs "^7.5.5" + +"@polkadot/util-crypto@8.7.1", "@polkadot/util-crypto@^8.4.1", "@polkadot/util-crypto@^8.7.1": + version "8.7.1" + resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-8.7.1.tgz#f9fcca2895b5f160ce1c2faa0aa3054cc7aa4655" + integrity sha512-TaSuJ2aNrB5sYK7YXszkEv24nYJKRFqjF2OrggoMg6uYxUAECvTkldFnhtgeizMweRMxJIBu6bMHlSIutbWgjw== + dependencies: + "@babel/runtime" "^7.17.8" + "@noble/hashes" "1.0.0" + "@noble/secp256k1" "1.5.5" + "@polkadot/networks" "8.7.1" + "@polkadot/util" "8.7.1" + "@polkadot/wasm-crypto" "^5.1.1" + "@polkadot/x-bigint" "8.7.1" + "@polkadot/x-randomvalues" "8.7.1" + "@scure/base" "1.0.0" ed2curve "^0.3.0" - elliptic "^6.5.4" - hash.js "^1.1.7" - js-sha3 "^0.8.0" - scryptsy "^2.1.0" tweetnacl "^1.0.3" - xxhashjs "^0.2.2" - -"@polkadot/util@7.3.1", "@polkadot/util@^7.2.1", "@polkadot/util@^7.3.1": - version "7.3.1" - resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-7.3.1.tgz#1a33a8d4ef2dcbc3e14a9a919f30bb16360a6fae" - integrity sha512-fjz5yjgZgfgRXZw9zMufmPBHhjAVtk/M2+lgl1a6Fck43Q4TG2Ux1haXMlaoe37cFeh8XgDAzDEQVIYBIPy6sg== - dependencies: - "@babel/runtime" "^7.15.3" - "@polkadot/x-textdecoder" "7.3.1" - "@polkadot/x-textencoder" "7.3.1" - "@types/bn.js" "^4.11.6" - bn.js "^4.12.0" - camelcase "^6.2.0" + +"@polkadot/util@8.7.1", "@polkadot/util@^8.4.1", "@polkadot/util@^8.7.1": + version "8.7.1" + resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-8.7.1.tgz#27fe93bf7b8345276f10cfe9c0380510cd4584f6" + integrity sha512-XjY1bTo7V6OvOCe4yn8H2vifeuBciCy0gq0k5P1tlGUQLI/Yt0hvDmxcA0FEPtqg8CL+rYRG7WXGPVNjkrNvyQ== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/x-bigint" "8.7.1" + "@polkadot/x-global" "8.7.1" + "@polkadot/x-textdecoder" "8.7.1" + "@polkadot/x-textencoder" "8.7.1" + "@types/bn.js" "^5.1.0" + bn.js "^5.2.0" ip-regex "^4.3.0" -"@polkadot/wasm-crypto-asmjs@^4.2.1": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-4.2.1.tgz#6b7eae1c011709f8042dfd30872a5fc5e9e021c0" - integrity sha512-ON9EBpTNDCI3QRUmuQJIegYoAcwvxDaNNA7uwKTaEEStu8LjCIbQxbt4WbOBYWI0PoUpl4iIluXdT3XZ3V3jXA== +"@polkadot/wasm-crypto-asmjs@^5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-5.1.1.tgz#6648e9c6f627501f61aef570e110022f2be1eff2" + integrity sha512-1WBwc2G3pZMKW1T01uXzKE30Sg22MXmF3RbbZiWWk3H2d/Er4jZQRpjumxO5YGWan+xOb7HQQdwnrUnrPgbDhg== dependencies: - "@babel/runtime" "^7.15.3" + "@babel/runtime" "^7.17.8" -"@polkadot/wasm-crypto-wasm@^4.2.1": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-4.2.1.tgz#2a86f9b405e7195c3f523798c6ce4afffd19737e" - integrity sha512-Rs2CKiR4D+2hKzmKBfPNYxcd2E8NfLWia0av4fgicjT9YsWIWOGQUi9AtSOfazPOR9FrjxKJy+chQxAkcfKMnQ== +"@polkadot/wasm-crypto-wasm@^5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-5.1.1.tgz#dc371755a05fe93f87a2754a2bcf1ff42e4bb541" + integrity sha512-F9PZ30J2S8vUNl2oY7Myow5Xsx5z5uNVpnNlJwlmY8IXBvyucvyQ4HSdhJsrbs4W1BfFc0mHghxgp0FbBCnf/Q== dependencies: - "@babel/runtime" "^7.15.3" + "@babel/runtime" "^7.17.8" -"@polkadot/wasm-crypto@^4.2.1": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-4.2.1.tgz#4d09402f5ac71a90962fb58cbe4b1707772a4fb6" - integrity sha512-C/A/QnemOilRTLnM0LfhPY2N/x3ZFd1ihm9sXYyuh98CxtekSVYI9h4IJ5Jrgz5imSUHgvt9oJLqJ5GbWQV/Zg== +"@polkadot/wasm-crypto@^5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-5.1.1.tgz#d1f8a0da631028ba904c374c1e8496ab3ba4636b" + integrity sha512-JCcAVfH8DhYuEyd4oX1ouByxhou0TvpErKn8kHjtzt7+tRoFi0nzWlmK4z49vszsV3JJgXxV81i10C0BYlwTcQ== dependencies: - "@babel/runtime" "^7.15.3" - "@polkadot/wasm-crypto-asmjs" "^4.2.1" - "@polkadot/wasm-crypto-wasm" "^4.2.1" + "@babel/runtime" "^7.17.8" + "@polkadot/wasm-crypto-asmjs" "^5.1.1" + "@polkadot/wasm-crypto-wasm" "^5.1.1" -"@polkadot/x-fetch@^7.3.1": - version "7.3.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-7.3.1.tgz#d6a63d3bdebd3e058deb4507d6dbae782a44c8bf" - integrity sha512-QnwP2RxWEUtnHE+1Iy2T49D4s5F8XH4bCyGqhbpZZdMym+cc+9zifBRQ+B5BIpTqICFFFbbhUvnvBSC9nS8bvg== +"@polkadot/x-bigint@8.7.1": + version "8.7.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-8.7.1.tgz#a496225def32e98c430c76b91c1579f48acf501a" + integrity sha512-ClkhgdB/KqcAKk3zA6Qw8wBL6Wz67pYTPkrAtImpvoPJmR+l4RARauv+MH34JXMUNlNb3aUwqN6lq2Z1zN+mJg== dependencies: - "@babel/runtime" "^7.15.3" - "@polkadot/x-global" "7.3.1" - "@types/node-fetch" "^2.5.12" - node-fetch "^2.6.1" + "@babel/runtime" "^7.17.8" + "@polkadot/x-global" "8.7.1" -"@polkadot/x-global@7.3.1", "@polkadot/x-global@^7.3.1": - version "7.3.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-7.3.1.tgz#6e6f9d3347748bd885754c7367f08441a6b7dc6d" - integrity sha512-Tx2xGyrNLsV+hjfKsAWA03VUnkQGyCeaff6vE7Fi9iZo/4L4BdrQKhJgQrX8PQuOhrcv1B1GDuaYiXr7dwBR1g== +"@polkadot/x-fetch@^8.7.1": + version "8.7.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-8.7.1.tgz#dc866e7aa87c39b2e64c87f734b8fbaf1b9190e1" + integrity sha512-ygNparcalYFGbspXtdtZOHvNXZBkNgmNO+um9C0JYq74K5OY9/be93uyfJKJ8JcRJtOqBfVDsJpbiRkuJ1PRfg== dependencies: - "@babel/runtime" "^7.15.3" + "@babel/runtime" "^7.17.8" + "@polkadot/x-global" "8.7.1" + "@types/node-fetch" "^2.6.1" + node-fetch "^2.6.7" -"@polkadot/x-randomvalues@7.3.1": - version "7.3.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-7.3.1.tgz#120c64147ce9bebee9e18e6c72cb91cc4d91d7e1" - integrity sha512-WtOTsjpp0+VIV+GY7IrELVznv78+IQ96UW5rf2i3AUIoouB1z9VrzJu/MCN7zoRQ9OAWpNoGxdAwzRDm9UL3+g== +"@polkadot/x-global@8.7.1", "@polkadot/x-global@^8.7.1": + version "8.7.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-8.7.1.tgz#b972044125a4fe059f4aef7c15a4e22d18179095" + integrity sha512-WOgUor16IihgNVdiTVGAWksYLUAlqjmODmIK1cuWrLOZtV1VBomWcb3obkO9sh5P6iWziAvCB/i+L0vnTN9ZCA== dependencies: - "@babel/runtime" "^7.15.3" - "@polkadot/x-global" "7.3.1" + "@babel/runtime" "^7.17.8" -"@polkadot/x-textdecoder@7.3.1": - version "7.3.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-7.3.1.tgz#e7ffc566483dce42b72c340bbaa1e76bbc5b2d3d" - integrity sha512-AkGrJ8C8kLvs7uxKMMqkBZmUbm8k3CBvq7FLnfUaQQXha4/3G3u+g3UqSTJ8+nETwRrfpjAVS77fmFx+6Nkxng== +"@polkadot/x-randomvalues@8.7.1": + version "8.7.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-8.7.1.tgz#b7cc358c2a6d20f7e7798d45d1d5c7ac8c9ab4f2" + integrity sha512-njt17MlfN6yNyNEti7fL12lr5qM6A1aSGkWKVuqzc7XwSBesifJuW4km5u6r2gwhXjH2eHDv9SoQ7WXu8vrrkg== dependencies: - "@babel/runtime" "^7.15.3" - "@polkadot/x-global" "7.3.1" + "@babel/runtime" "^7.17.8" + "@polkadot/x-global" "8.7.1" -"@polkadot/x-textencoder@7.3.1": - version "7.3.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-7.3.1.tgz#8c08dacdac677d7a8e021437ce2b31d90a041519" - integrity sha512-1yePbvbQ9U9ScRilQ/aH6CwgoSG8njH27XVzRR7WnulAMKbF3IvHgU56IlBZneHIojAy252yp2ldBG09PDIXeg== +"@polkadot/x-textdecoder@8.7.1": + version "8.7.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-8.7.1.tgz#b706ef98d5a033d02c633009fb8dab4a4f9d7d55" + integrity sha512-ia0Ie2zi4VdQdNVD2GE2FZzBMfX//hEL4w546RMJfZM2LqDS674LofHmcyrsv5zscLnnRyCxZC1+J2dt+6MDIA== dependencies: - "@babel/runtime" "^7.15.3" - "@polkadot/x-global" "7.3.1" + "@babel/runtime" "^7.17.8" + "@polkadot/x-global" "8.7.1" -"@polkadot/x-ws@^7.3.1": - version "7.3.1" - resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-7.3.1.tgz#bc4bcfd3a5ebec7c6b57bdbc718a68699b87f7ca" - integrity sha512-JltBHm2GqmS/hPIbak3wzqHRTz5k3yQOdYPOsj2gAs5twe7fJwJOJp0InfpNCknX4Cn9+WBIjNZUNLZ6bO+MkQ== +"@polkadot/x-textencoder@8.7.1": + version "8.7.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-8.7.1.tgz#7820e30081e8e0a607c1c27b9e3486d82d1a723e" + integrity sha512-XDO0A27Xy+eJCKSxENroB8Dcnl+UclGG4ZBei+P/BqZ9rsjskUyd2Vsl6peMXAcsxwOE7g0uTvujoGM8jpKOXw== dependencies: - "@babel/runtime" "^7.15.3" - "@polkadot/x-global" "7.3.1" - "@types/websocket" "^1.0.4" + "@babel/runtime" "^7.17.8" + "@polkadot/x-global" "8.7.1" + +"@polkadot/x-ws@^8.7.1": + version "8.7.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-8.7.1.tgz#501c63c575e04bba68bdc32448e2c9b692f0411e" + integrity sha512-Mt0tcNzGXyKnN3DQ06alkv+JLtTfXWu6zSypFrrKHSQe3u79xMQ1nSicmpT3gWLhIa8YF+8CYJXMrqaXgCnDhw== + dependencies: + "@babel/runtime" "^7.17.8" + "@polkadot/x-global" "8.7.1" + "@types/websocket" "^1.0.5" websocket "^1.0.34" -"@types/bn.js@^4.11.6": - version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" - integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== +"@scure/base@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.0.0.tgz#109fb595021de285f05a7db6806f2f48296fcee7" + integrity sha512-gIVaYhUsy+9s58m/ETjSJVKHhKTBMmcRb9cEV5/5dwvfDlfORjKrFsDeDHWRrm6RjcPvCLZFwGJjAjLj1gg4HA== + +"@substrate/connect-extension-protocol@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@substrate/connect-extension-protocol/-/connect-extension-protocol-1.0.0.tgz#d452beda84b3ebfcf0e88592a4695e729a91e858" + integrity sha512-nFVuKdp71hMd/MGlllAOh+a2hAqt8m6J2G0aSsS/RcALZexxF9jodbFc62ni8RDtJboeOfXAHhenYOANvJKPIg== + +"@substrate/connect@0.7.0-alpha.0": + version "0.7.0-alpha.0" + resolved "https://registry.yarnpkg.com/@substrate/connect/-/connect-0.7.0-alpha.0.tgz#df605f4e808b58d146ad0272a79b2c4b870459a5" + integrity sha512-fvO7w++M8R95R/pGJFW9+cWOt8OYnnTfgswxtlPqSgzqX4tta8xcNQ51crC72FcL5agwSGkA1gc2/+eyTj7O8A== + dependencies: + "@substrate/connect-extension-protocol" "^1.0.0" + "@substrate/smoldot-light" "0.6.8" + eventemitter3 "^4.0.7" + +"@substrate/smoldot-light@0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@substrate/smoldot-light/-/smoldot-light-0.6.8.tgz#e626e25cd2386824f1164e7d7dda7258580c36e4" + integrity sha512-9lVwbG6wrtss0sd6013BJGe4WN4taujsGG49pwyt1Lj36USeL2Sb164TTUxmZF/g2NQEqDPwPROBdekQ2gFmgg== + dependencies: + buffer "^6.0.1" + pako "^2.0.4" + websocket "^1.0.32" + +"@substrate/ss58-registry@^1.17.0": + version "1.22.0" + resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.22.0.tgz#d115bc5dcab8c0f5800e05e4ef265949042b13ec" + integrity sha512-IKqrPY0B3AeIXEc5/JGgEhPZLy+SmVyQf+k0SIGcNSTqt1GLI3gQFEOFwSScJdem+iYZQUrn6YPPxC3TpdSC3A== + +"@types/bn.js@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" + integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== dependencies: "@types/node" "*" -"@types/node-fetch@^2.5.12": - version "2.5.12" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.12.tgz#8a6f779b1d4e60b7a57fb6fd48d84fb545b9cc66" - integrity sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw== +"@types/node-fetch@^2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.1.tgz#8f127c50481db65886800ef496f20bbf15518975" + integrity sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA== dependencies: "@types/node" "*" form-data "^3.0.0" @@ -245,14 +384,14 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-15.14.0.tgz#74dbf254fb375551a9d2a71faf6b9dbc2178dc53" integrity sha512-um/+/ip3QZmwLfIkWZSNtQIJNVAqrJ92OkLMeuZrjZMTAJniI7fh8N8OICyDhAJ2mzgk/fmYFo72jRr5HyZ1EQ== -"@types/websocket@^1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.4.tgz#1dc497280d8049a5450854dd698ee7e6ea9e60b8" - integrity sha512-qn1LkcFEKK8RPp459jkjzsfpbsx36BBt3oC3pITYtkoBw/aVX+EZFa5j3ThCRTNpLFvIMr5dSTD4RaMdilIOpA== +"@types/websocket@^1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.5.tgz#3fb80ed8e07f88e51961211cd3682a3a4a81569c" + integrity sha512-NbsqiNX9CnEfC1Z0Vf4mE1SgAJ07JnRYcNex7AJ9zAVzmiGHmjKFEk7O4TJIsgv2B1sLEb6owKFZrACwdYngsQ== dependencies: "@types/node" "*" -ansi-regex@^5.0.0: +ansi-regex@^5.0.0, ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== @@ -274,27 +413,15 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base-x@^3.0.8: - version "3.0.8" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d" - integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.5.1: +base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -blakejs@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.1.tgz#bf313053978b2cd4c444a48795710be05c785702" - integrity sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg== - -bn.js@^4.11.9, bn.js@^4.12.0: - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== +bn.js@^5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== brace-expansion@^1.1.7: version "1.1.11" @@ -304,10 +431,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= +buffer@^6.0.1: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" bufferutil@^4.0.1: version "4.0.3" @@ -316,19 +446,6 @@ bufferutil@^4.0.1: dependencies: node-gyp-build "^4.2.0" -camelcase@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" - integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== - -cipher-base@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -362,22 +479,6 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -cuint@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.2.2.tgz#408086d409550c2631155619e9fa7bcadc3b991b" - integrity sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs= - d@1, d@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" @@ -393,6 +494,13 @@ debug@^2.2.0: dependencies: ms "2.0.0" +debug@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -405,19 +513,6 @@ ed2curve@^0.3.0: dependencies: tweetnacl "1.x.x" -elliptic@^6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" - emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -509,31 +604,10 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== inflight@^1.0.4: version "1.0.6" @@ -543,7 +617,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: +inherits@2: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -575,25 +649,16 @@ is-typedarray@^1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -js-sha3@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== +json-stringify-safe@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - mime-db@1.48.0: version "1.48.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" @@ -606,16 +671,6 @@ mime-types@^2.1.12: dependencies: mime-db "1.48.0" -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -623,17 +678,37 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +mock-socket@^9.1.2: + version "9.1.5" + resolved "https://registry.yarnpkg.com/mock-socket/-/mock-socket-9.1.5.tgz#2c4e44922ad556843b6dfe09d14ed8041fa2cdeb" + integrity sha512-3DeNIcsQixWHHKk6NdoBhWI4t1VMj5/HzfnI1rE/pLl5qKx7+gd4DNA07ehTaZ6MoUU053si6Hd+YtiM/tQZfg== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + next-tick@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= -node-fetch@^2.6.1: +nock@^13.2.4: + version "13.2.7" + resolved "https://registry.yarnpkg.com/nock/-/nock-13.2.7.tgz#c93933b61df42f4f4b3a07fde946a4e209c0c168" + integrity sha512-R6NUw7RIPtKwgK7jskuKoEi4VFMqIHtV2Uu9K/Uegc4TA5cqe+oNMYslZcUmnVNQCTG6wcSqUBaGTDd7sq5srg== + dependencies: + debug "^4.1.0" + json-stringify-safe "^5.0.1" + lodash "^4.17.21" + propagate "^2.0.0" + +node-fetch@^2.6.7: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== @@ -652,6 +727,11 @@ once@^1.3.0: dependencies: wrappy "1" +pako@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.4.tgz#6cebc4bbb0b6c73b0d5b8d7e8476e2b2fbea576d" + integrity sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -662,14 +742,10 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" +propagate@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45" + integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag== readline-sync@^1.4.10: version "1.4.10" @@ -702,40 +778,14 @@ resolve@^1.1.6: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -rxjs@^7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.3.0.tgz#39fe4f3461dc1e50be1475b2b85a0a88c1e938c6" - integrity sha512-p2yuGIg9S1epc3vrjKf6iVb3RCaAYjYskkO+jHIaV0IjOPlJop4UnodOoFb2xeNwlguqLYvGw1b1McillYb5Gw== +rxjs@^7.5.5: + version "7.5.5" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.5.tgz#2ebad89af0f560f460ad5cc4213219e1f7dd4e9f" + integrity sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw== dependencies: - tslib "~2.1.0" - -safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + tslib "^2.1.0" -scryptsy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-2.1.0.tgz#8d1e8d0c025b58fdd25b6fa9a0dc905ee8faa790" - integrity sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w== - -sha.js@^2.4.0: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shelljs@^0.8.4: +shelljs@^0.8.5: version "0.8.5" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== @@ -753,12 +803,14 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== +string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: - safe-buffer "~5.2.0" + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" strip-ansi@^6.0.0: version "6.0.0" @@ -767,6 +819,13 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" @@ -777,10 +836,10 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= -tslib@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== +tslib@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== tweetnacl@1.x.x, tweetnacl@^1.0.3: version "1.0.3" @@ -811,17 +870,12 @@ utf-8-validate@^5.0.2: dependencies: node-gyp-build "^4.2.0" -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= -websocket@^1.0.34: +websocket@^1.0.32, websocket@^1.0.34: version "1.0.34" resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== @@ -855,13 +909,6 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -xxhashjs@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/xxhashjs/-/xxhashjs-0.2.2.tgz#8a6251567621a1c46a5ae204da0249c7f8caa9d8" - integrity sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw== - dependencies: - cuint "^0.2.2" - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" @@ -877,20 +924,20 @@ yaml@^1.10.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== +yargs-parser@^21.0.0: + version "21.0.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35" + integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg== -yargs@^17.0.1: - version "17.0.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.0.1.tgz#6a1ced4ed5ee0b388010ba9fd67af83b9362e0bb" - integrity sha512-xBBulfCc8Y6gLFcrPvtqKz9hz8SO0l1Ni8GgDekvBX2ro0HRQImDGnikfc33cgzcYUSncapnNcZDjVFIH3f6KQ== +yargs@^17.4.0: + version "17.5.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" + integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== dependencies: cliui "^7.0.2" escalade "^3.1.1" get-caller-file "^2.0.5" require-directory "^2.1.1" - string-width "^4.2.0" + string-width "^4.2.3" y18n "^5.0.5" - yargs-parser "^20.2.2" + yargs-parser "^21.0.0" diff --git a/modules/aggregated-dex/Cargo.toml b/modules/aggregated-dex/Cargo.toml index 50169508e3..b315b4ddae 100644 --- a/modules/aggregated-dex/Cargo.toml +++ b/modules/aggregated-dex/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-aggregated-dex" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" @@ -18,9 +18,9 @@ support = { package = "module-support", path = "../support", default-features = primitives = { package = "acala-primitives", path = "../../primitives", default-features = false } nutsfinance-stable-asset = { path = "../../ecosystem-modules/stable-asset/lib/stable-asset", version = "0.1.0", default-features = false } module-dex = { package = "module-dex", path = "../dex", default-features = false } +orml-tokens = { path = "../../orml/tokens", default-features = false } [dev-dependencies] -orml-tokens = { path = "../../orml/tokens" } sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.22" } sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.22" } pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.22" } @@ -36,6 +36,7 @@ std = [ "frame-system/std", "sp-std/std", "orml-traits/std", + "orml-tokens/std", "support/std", "primitives/std", "nutsfinance-stable-asset/std", diff --git a/modules/aggregated-dex/src/lib.rs b/modules/aggregated-dex/src/lib.rs index ace34fb9fc..af678d9976 100644 --- a/modules/aggregated-dex/src/lib.rs +++ b/modules/aggregated-dex/src/lib.rs @@ -25,6 +25,7 @@ use frame_support::{pallet_prelude::*, transactional}; use frame_system::pallet_prelude::*; use nutsfinance_stable_asset::{traits::StableAsset as StableAssetT, PoolTokenIndex, StableAssetPoolId}; +use orml_tokens::ConvertBalance; use primitives::{Balance, CurrencyId}; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; @@ -75,6 +76,8 @@ pub mod module { #[pallet::constant] type SwapPathLimit: Get; + type RebaseTokenAmountConvertor: ConvertBalance; + type WeightInfo: WeightInfo; } @@ -124,8 +127,8 @@ pub mod module { pub fn swap_with_exact_supply( origin: OriginFor, paths: Vec, - supply_amount: Balance, - min_target_amount: Balance, + #[pallet::compact] supply_amount: Balance, + #[pallet::compact] min_target_amount: Balance, ) -> DispatchResult { let who = ensure_signed(origin)?; let paths: BoundedVec = @@ -134,6 +137,26 @@ pub mod module { Ok(()) } + #[pallet::weight(::WeightInfo::swap_with_exact_supply( + paths.iter().fold(0, |u, swap_path| match swap_path { + SwapPath::Dex(v) => u + (v.len() as u32), + SwapPath::Taiga(_, _, _) => u + 1 + }) + ))] + #[transactional] + pub fn swap_with_exact_target( + origin: OriginFor, + paths: Vec, + #[pallet::compact] target_amount: Balance, + #[pallet::compact] max_supply_amount: Balance, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + let paths: BoundedVec = + paths.try_into().map_err(|_| Error::::InvalidSwapPath)?; + let _ = Self::do_aggregated_swap(&who, &paths, SwapLimit::ExactTarget(max_supply_amount, target_amount))?; + Ok(()) + } + /// Update the aggregated swap paths for AggregatedSwap to swap TokenA to TokenB. /// /// Requires `GovernanceOrigin` @@ -169,6 +192,110 @@ pub mod module { } impl Pallet { + fn taiga_get_best_route( + supply_currency_id: CurrencyId, + target_currency_id: CurrencyId, + supply_amount: Balance, + ) -> Option<(StableAssetPoolId, PoolTokenIndex, PoolTokenIndex, Balance)> { + T::StableAsset::get_best_route( + supply_currency_id, + target_currency_id, + T::RebaseTokenAmountConvertor::convert_balance(supply_amount, supply_currency_id), + ) + .map(|(pool_id, input_index, output_index, output_amount)| { + ( + pool_id, + input_index, + output_index, + T::RebaseTokenAmountConvertor::convert_balance_back(output_amount, target_currency_id), + ) + }) + } + + fn taiga_get_swap_input_amount( + pool_id: StableAssetPoolId, + input_asset_index: PoolTokenIndex, + output_asset_index: PoolTokenIndex, + output_amount: Balance, + ) -> Option<(Balance, Balance)> { + let pool_info = T::StableAsset::pool(pool_id)?; + let input_currency_id = pool_info.assets.get(input_asset_index as usize)?; + let output_currency_id = pool_info.assets.get(output_asset_index as usize)?; + + T::StableAsset::get_swap_input_amount( + pool_id, + input_asset_index, + output_asset_index, + T::RebaseTokenAmountConvertor::convert_balance(output_amount, *output_currency_id), + ) + .map(|swap_result| { + ( + T::RebaseTokenAmountConvertor::convert_balance_back(swap_result.dx, *input_currency_id), + T::RebaseTokenAmountConvertor::convert_balance_back(swap_result.dy, *output_currency_id), + ) + }) + } + + fn taiga_get_swap_output_amount( + pool_id: StableAssetPoolId, + input_asset_index: PoolTokenIndex, + output_asset_index: PoolTokenIndex, + input_amount: Balance, + ) -> Option<(Balance, Balance)> { + let pool_info = T::StableAsset::pool(pool_id)?; + let input_currency_id = pool_info.assets.get(input_asset_index as usize)?; + let output_currency_id = pool_info.assets.get(output_asset_index as usize)?; + + T::StableAsset::get_swap_output_amount( + pool_id, + input_asset_index, + output_asset_index, + T::RebaseTokenAmountConvertor::convert_balance(input_amount, *input_currency_id), + ) + .map(|swap_result| { + ( + T::RebaseTokenAmountConvertor::convert_balance_back(swap_result.dx, *input_currency_id), + T::RebaseTokenAmountConvertor::convert_balance_back(swap_result.dy, *output_currency_id), + ) + }) + } + + fn taiga_swap( + who: &T::AccountId, + pool_id: StableAssetPoolId, + input_asset_index: PoolTokenIndex, + output_asset_index: PoolTokenIndex, + input_amount: Balance, + min_output_amount: Balance, + ) -> sp_std::result::Result<(Balance, Balance), DispatchError> { + let pool_info = T::StableAsset::pool(pool_id).ok_or(Error::::InvalidPoolId)?; + let asset_length = pool_info.assets.len() as u32; + let input_currency_id = pool_info + .assets + .get(input_asset_index as usize) + .ok_or(Error::::InvalidTokenIndex)?; + let output_currency_id = pool_info + .assets + .get(output_asset_index as usize) + .ok_or(Error::::InvalidTokenIndex)?; + + T::StableAsset::swap( + who, + pool_id, + input_asset_index, + output_asset_index, + T::RebaseTokenAmountConvertor::convert_balance(input_amount, *input_currency_id), + T::RebaseTokenAmountConvertor::convert_balance(min_output_amount, *output_currency_id), + asset_length, + ) + .map(|(dx, dy)| { + ( + T::RebaseTokenAmountConvertor::convert_balance_back(dx, *input_currency_id), + T::RebaseTokenAmountConvertor::convert_balance_back(dy, *output_currency_id), + ) + }) + } + fn check_swap_paths(paths: &[SwapPath]) -> sp_std::result::Result<(CurrencyId, CurrencyId), DispatchError> { ensure!(!paths.is_empty(), Error::::InvalidSwapPath); let mut supply_currency_id: Option = None; @@ -247,13 +374,14 @@ impl Pallet { } SwapPath::Taiga(pool_id, supply_asset_index, target_asset_index) => { // use the output of the previous swap as input. - output_amount = T::StableAsset::get_swap_output_amount( + let (_, actual_output_amount) = Self::taiga_get_swap_output_amount( *pool_id, *supply_asset_index, *target_asset_index, output_amount, - ) - .map(|swap_result| swap_result.dy)?; + )?; + + output_amount = actual_output_amount; } } } @@ -277,13 +405,15 @@ impl Pallet { input_amount = supply_amount; } SwapPath::Taiga(pool_id, supply_asset_index, target_asset_index) => { - input_amount = T::StableAsset::get_swap_input_amount( + // calculate the input amount + let (actual_input_amount, _) = Self::taiga_get_swap_input_amount( *pool_id, *supply_asset_index, *target_asset_index, input_amount, - ) - .map(|swap_result| swap_result.dx)?; + )?; + + input_amount = actual_input_amount; } } } @@ -328,18 +458,14 @@ impl Pallet { output_amount = actual_target; } SwapPath::Taiga(pool_id, supply_asset_index, target_asset_index) => { - let pool_info = T::StableAsset::pool(*pool_id).ok_or(Error::::InvalidPoolId)?; - let asset_length = pool_info.assets.len() as u32; - // use the output of the previous swap as input. - let (_, actual_target) = T::StableAsset::swap( + let (_, actual_target) = Self::taiga_swap( who, *pool_id, *supply_asset_index, *target_asset_index, output_amount, Zero::zero(), - asset_length, )?; output_amount = actual_target; @@ -353,43 +479,12 @@ impl Pallet { Ok((exact_supply_amount, output_amount)) } // Calculate the supply amount first, then execute swap with ExactSupply - SwapLimit::ExactTarget(max_supply_amount, exact_target_amount) => { - let mut input_amount: Balance = exact_target_amount; - - for path in paths.iter().rev() { - match path { - SwapPath::Dex(dex_path) => { - // calculate the supply amount - let (supply_amount, _) = T::DEX::get_swap_amount( - dex_path, - SwapLimit::ExactTarget(Balance::max_value(), input_amount), - ) - .ok_or(Error::::CannotSwap)?; - - input_amount = supply_amount; - } - SwapPath::Taiga(pool_id, supply_asset_index, target_asset_index) => { - let swap_result = T::StableAsset::get_swap_input_amount( - *pool_id, - *supply_asset_index, - *target_asset_index, - input_amount, - ) - .ok_or(Error::::CannotSwap)?; - - input_amount = swap_result.dx; - } - } - } - - // the result must meet the SwapLimit. - ensure!( - !input_amount.is_zero() && input_amount <= max_supply_amount, - Error::::CannotSwap - ); + SwapLimit::ExactTarget(_max_supply_amount, exact_target_amount) => { + let (supply_amount, _) = + Self::get_aggregated_swap_amount(paths, swap_limit).ok_or(Error::::CannotSwap)?; // actually swap by `ExactSupply` limit - Self::do_aggregated_swap(who, paths, SwapLimit::ExactSupply(input_amount, exact_target_amount)) + Self::do_aggregated_swap(who, paths, SwapLimit::ExactSupply(supply_amount, exact_target_amount)) } } } @@ -434,6 +529,10 @@ impl Swap for DexSwap { /// Swap by Taiga pool. pub struct TaigaSwap(PhantomData); impl Swap for TaigaSwap { + // !!! Note: if ths limit is `ExactTarget` and the `max_supply_amount` will cause overflow in + // StableAsset, will return `None`. Because the `get_best_route` of StableAsset treats it as the + // actual input amount. However, it will fail so will not cause loss. Maybe need to modiry + // StableAsset impl to avoid this risk. fn get_swap_amount( supply_currency_id: CurrencyId, target_currency_id: CurrencyId, @@ -442,25 +541,30 @@ impl Swap for TaigaSwap { match limit { SwapLimit::ExactSupply(supply_amount, min_target_amount) => { let (pool_id, input_index, output_index, _) = - T::StableAsset::get_best_route(supply_currency_id, target_currency_id, supply_amount)?; + Pallet::::taiga_get_best_route(supply_currency_id, target_currency_id, supply_amount)?; - if let Some(swap_result) = - T::StableAsset::get_swap_output_amount(pool_id, input_index, output_index, supply_amount) + if let Some((input_amount, output_amount)) = + Pallet::::taiga_get_swap_output_amount(pool_id, input_index, output_index, supply_amount) { - if swap_result.dy >= min_target_amount { - return Some((swap_result.dx, swap_result.dy)); + if output_amount >= min_target_amount { + return Some((input_amount, output_amount)); } } } SwapLimit::ExactTarget(max_supply_amount, target_amount) => { let (pool_id, input_index, output_index, _) = - T::StableAsset::get_best_route(supply_currency_id, target_currency_id, max_supply_amount)?; + Pallet::::taiga_get_best_route(supply_currency_id, target_currency_id, max_supply_amount)?; - if let Some(swap_result) = - T::StableAsset::get_swap_input_amount(pool_id, input_index, output_index, target_amount) + if let Some((input_amount, _)) = + Pallet::::taiga_get_swap_input_amount(pool_id, input_index, output_index, target_amount) { - if !swap_result.dx.is_zero() && swap_result.dx <= max_supply_amount { - return Some((swap_result.dx, swap_result.dy)); + if !input_amount.is_zero() && input_amount <= max_supply_amount { + // actually swap by `ExactSupply` limit + return Self::get_swap_amount( + supply_currency_id, + target_currency_id, + SwapLimit::ExactSupply(input_amount, target_amount), + ); } } } @@ -486,22 +590,18 @@ impl Swap for TaigaSwap { }; let (pool_id, input_index, output_index, _) = - T::StableAsset::get_best_route(supply_currency_id, target_currency_id, min_target_amount) + Pallet::::taiga_get_best_route(supply_currency_id, target_currency_id, supply_amount) .ok_or(Error::::CannotSwap)?; - let pool_info = T::StableAsset::pool(pool_id).ok_or(Error::::InvalidPoolId)?; - let asset_length = pool_info.assets.len() as u32; - - let (actual_supply, actual_target) = T::StableAsset::swap( + let (actual_supply, actual_target) = Pallet::::taiga_swap( who, pool_id, input_index, output_index, supply_amount, min_target_amount, - asset_length, )?; - ensure!(actual_target >= min_target_amount, Error::::CannotSwap); + ensure!(actual_target >= min_target_amount, Error::::CannotSwap); Ok((actual_supply, actual_target)) } } diff --git a/modules/aggregated-dex/src/mock.rs b/modules/aggregated-dex/src/mock.rs index ee99fd7da8..4bb4c93fdd 100644 --- a/modules/aggregated-dex/src/mock.rs +++ b/modules/aggregated-dex/src/mock.rs @@ -22,17 +22,16 @@ use super::*; use frame_support::{ - ord_parameter_types, parameter_types, - traits::{ConstU32, ConstU64, Everything, Nothing}, + match_types, ord_parameter_types, parameter_types, + traits::{ConstU128, ConstU32, ConstU64, Everything, Nothing}, PalletId, }; -use frame_system::{EnsureSignedBy, RawOrigin}; -use nutsfinance_stable_asset::{RedeemProportionResult, StableAssetPoolInfo, SwapResult}; +use frame_system::EnsureSignedBy; pub use orml_traits::{parameter_type_with_key, MultiCurrency}; use primitives::{Amount, TokenSymbol, TradingPair}; use sp_runtime::{ testing::{Header, H256}, - traits::IdentityLookup, + traits::{Bounded, IdentityLookup}, AccountId32, FixedPointNumber, }; pub use support::ExchangeRate; @@ -122,340 +121,82 @@ impl module_dex::Config for Runtime { type OnLiquidityPoolUpdated = (); } -#[derive(Clone)] -pub struct TaigaSwapStatus { - pub currency_id_0: CurrencyId, - pub currency_id_1: CurrencyId, - pub stable_asset_id: CurrencyId, - pub exchange_rate_1_for_0: ExchangeRate, +pub struct EnsurePoolAssetId; +impl nutsfinance_stable_asset::traits::ValidateAssetId for EnsurePoolAssetId { + fn validate(currency_id: CurrencyId) -> bool { + matches!(currency_id, CurrencyId::StableAssetPoolToken(_)) + } } -pub struct MockStableAsset; -impl StableAssetT for MockStableAsset { +pub struct ConvertBalanceHoma; +impl orml_tokens::ConvertBalance for ConvertBalanceHoma { type AssetId = CurrencyId; - type AtLeast64BitUnsigned = Balance; - type Balance = Balance; - type AccountId = AccountId; - type BlockNumber = BlockNumber; - - fn pool_count() -> StableAssetPoolId { - unimplemented!() - } - - fn pool( - _id: StableAssetPoolId, - ) -> Option> { - TaigaConfig::get().map(|taiga_config| StableAssetPoolInfo { - pool_asset: taiga_config.stable_asset_id, - assets: vec![taiga_config.currency_id_0, taiga_config.currency_id_1], - precisions: vec![], - mint_fee: Default::default(), - swap_fee: Default::default(), - redeem_fee: Default::default(), - total_supply: Default::default(), - a: Default::default(), - a_block: Default::default(), - future_a: Default::default(), - future_a_block: Default::default(), - balances: Default::default(), - fee_recipient: BOB, - account_id: BOB, - yield_recipient: BOB, - precision: Default::default(), - }) - } - - fn create_pool( - _pool_asset: Self::AssetId, - _assets: Vec, - _precisions: Vec, - _mint_fee: Self::Balance, - _swap_fee: Self::Balance, - _redeem_fee: Self::Balance, - _initial_a: Self::Balance, - _fee_recipient: Self::AccountId, - _yield_recipient: Self::AccountId, - _precision: Self::Balance, - ) -> DispatchResult { - unimplemented!() - } - - fn mint( - _who: &Self::AccountId, - _pool_id: StableAssetPoolId, - _amounts: Vec, - _min_mint_amount: Self::Balance, - ) -> DispatchResult { - unimplemented!() - } - fn swap( - who: &Self::AccountId, - _pool_id: StableAssetPoolId, - i: PoolTokenIndex, - j: PoolTokenIndex, - dx: Self::Balance, - min_dy: Self::Balance, - _asset_length: u32, - ) -> sp_std::result::Result<(Self::Balance, Self::Balance), DispatchError> { - if let Some(taiga_config) = TaigaConfig::get() { - let (supply_currency_id, target_currency_id, swap_exchange_rate) = match (i, j) { - (0, 1) => ( - taiga_config.currency_id_0, - taiga_config.currency_id_1, - taiga_config.exchange_rate_1_for_0, - ), - (1, 0) => ( - taiga_config.currency_id_1, - taiga_config.currency_id_0, - taiga_config.exchange_rate_1_for_0.reciprocal().unwrap(), - ), - _ => return Err(Error::::CannotSwap.into()), - }; - let actual_target = swap_exchange_rate.saturating_mul_int(dx); - ensure!(actual_target >= min_dy, Error::::CannotSwap); - - Tokens::withdraw(supply_currency_id, who, dx)?; - Tokens::deposit(target_currency_id, who, actual_target)?; - - Ok((dx, actual_target)) - } else { - Err(Error::::CannotSwap.into()) + fn convert_balance(balance: Balance, asset_id: CurrencyId) -> Balance { + match asset_id { + LDOT => ExchangeRate::saturating_from_rational(1, 10) + .checked_mul_int(balance) + .unwrap_or(Bounded::max_value()), + _ => balance, } } - fn redeem_proportion( - _who: &Self::AccountId, - _pool_id: StableAssetPoolId, - _amount: Self::Balance, - _min_redeem_amounts: Vec, - ) -> DispatchResult { - unimplemented!() - } - - fn redeem_single( - _who: &Self::AccountId, - _pool_id: StableAssetPoolId, - _amount: Self::Balance, - _i: PoolTokenIndex, - _min_redeem_amount: Self::Balance, - _asset_length: u32, - ) -> DispatchResult { - unimplemented!() - } - - fn redeem_multi( - _who: &Self::AccountId, - _pool_id: StableAssetPoolId, - _amounts: Vec, - _max_redeem_amount: Self::Balance, - ) -> DispatchResult { - unimplemented!() - } - - fn collect_fee( - _pool_id: StableAssetPoolId, - _pool_info: &mut StableAssetPoolInfo< - Self::AssetId, - Self::Balance, - Self::Balance, - Self::AccountId, - Self::BlockNumber, - >, - ) -> DispatchResult { - unimplemented!() - } - - fn update_balance( - _pool_id: StableAssetPoolId, - _pool_info: &mut StableAssetPoolInfo< - Self::AssetId, - Self::Balance, - Self::Balance, - Self::AccountId, - Self::BlockNumber, - >, - ) -> DispatchResult { - unimplemented!() - } - - fn collect_yield( - _pool_id: StableAssetPoolId, - _pool_info: &mut StableAssetPoolInfo< - Self::AssetId, - Self::Balance, - Self::Balance, - Self::AccountId, - Self::BlockNumber, - >, - ) -> DispatchResult { - unimplemented!() - } - - fn modify_a(_pool_id: StableAssetPoolId, _a: Self::Balance, _future_a_block: Self::BlockNumber) -> DispatchResult { - unimplemented!() - } - - fn get_collect_yield_amount( - _pool_info: &StableAssetPoolInfo< - Self::AssetId, - Self::Balance, - Self::Balance, - Self::AccountId, - Self::BlockNumber, - >, - ) -> Option> { - unimplemented!() - } - - fn get_balance_update_amount( - _pool_info: &StableAssetPoolInfo< - Self::AssetId, - Self::Balance, - Self::Balance, - Self::AccountId, - Self::BlockNumber, - >, - ) -> Option> { - unimplemented!() - } - - fn get_redeem_proportion_amount( - _pool_info: &StableAssetPoolInfo< - Self::AssetId, - Self::Balance, - Self::Balance, - Self::AccountId, - Self::BlockNumber, - >, - _amount_bal: Self::Balance, - ) -> Option> { - unimplemented!() - } - - fn get_best_route( - input_asset: Self::AssetId, - output_asset: Self::AssetId, - input_amount: Self::Balance, - ) -> Option<(StableAssetPoolId, PoolTokenIndex, PoolTokenIndex, Self::Balance)> { - TaigaConfig::get().and_then(|taiga_config| { - if input_asset == taiga_config.currency_id_0 && output_asset == taiga_config.currency_id_1 { - Some(( - 0, - 0, - 1, - taiga_config.exchange_rate_1_for_0.saturating_mul_int(input_amount), - )) - } else if output_asset == taiga_config.currency_id_0 && input_asset == taiga_config.currency_id_1 { - Some(( - 0, - 1, - 0, - taiga_config - .exchange_rate_1_for_0 - .reciprocal() - .unwrap() - .saturating_mul_int(input_amount), - )) - } else { - None - } - }) - } - - fn get_swap_output_amount( - _pool_id: StableAssetPoolId, - input_index: PoolTokenIndex, - output_index: PoolTokenIndex, - dx_bal: Self::Balance, - ) -> Option> { - TaigaConfig::get().and_then(|taiga_config| { - let input_to_output_rate = match (input_index, output_index) { - (0, 1) => taiga_config.exchange_rate_1_for_0, - (1, 0) => taiga_config.exchange_rate_1_for_0.reciprocal().unwrap(), - _ => return None, - }; - let target_amount = input_to_output_rate.saturating_mul_int(dx_bal); - - Some(SwapResult { - dx: dx_bal, - dy: target_amount, - ..Default::default() - }) - }) - } - - fn get_swap_input_amount( - _pool_id: StableAssetPoolId, - input_index: PoolTokenIndex, - output_index: PoolTokenIndex, - dy_bal: Self::Balance, - ) -> Option> { - TaigaConfig::get().and_then(|taiga_config| { - let output_to_input_rate = match (input_index, output_index) { - (0, 1) => taiga_config.exchange_rate_1_for_0.reciprocal().unwrap(), - (1, 0) => taiga_config.exchange_rate_1_for_0, - _ => return None, - }; - let supply_amount = output_to_input_rate.saturating_mul_int(dy_bal); - - Some(SwapResult { - dx: supply_amount, - dy: dy_bal, - ..Default::default() - }) - }) + fn convert_balance_back(balance: Balance, asset_id: CurrencyId) -> Balance { + match asset_id { + LDOT => ExchangeRate::saturating_from_rational(10, 1) + .checked_mul_int(balance) + .unwrap_or(Bounded::max_value()), + _ => balance, + } } } -pub fn set_taiga_swap(currency_id_0: CurrencyId, currency_id_1: CurrencyId, exchange_rate_1_for_0: ExchangeRate) { - TaigaConfig::set(Some(TaigaSwapStatus { - currency_id_0, - currency_id_1, - stable_asset_id: STABLE_ASSET, - exchange_rate_1_for_0, - })); +match_types! { + pub type IsLiquidToken: impl Contains = { + CurrencyId::Token(TokenSymbol::LDOT) + }; } -pub fn set_dex_swap_joint_list(joints: Vec>) { - DexSwapJointList::set(joints); +type RebaseTokens = orml_tokens::Combiner< + AccountId, + IsLiquidToken, + orml_tokens::Mapper, + Tokens, +>; + +parameter_types! { + pub const StableAssetPalletId: PalletId = PalletId(*b"nuts/sta"); } -pub fn inject_liquidity( - currency_id_a: CurrencyId, - currency_id_b: CurrencyId, - max_amount_a: Balance, - max_amount_b: Balance, -) -> Result<(), &'static str> { - // set balance - Tokens::deposit(currency_id_a, &BOB, max_amount_a)?; - Tokens::deposit(currency_id_b, &BOB, max_amount_b)?; - - let _ = Dex::enable_trading_pair(RawOrigin::Signed(BOB.clone()).into(), currency_id_a, currency_id_b); - Dex::add_liquidity( - RawOrigin::Signed(BOB).into(), - currency_id_a, - currency_id_b, - max_amount_a, - max_amount_b, - Default::default(), - false, - )?; - - Ok(()) +impl nutsfinance_stable_asset::Config for Runtime { + type Event = Event; + type AssetId = CurrencyId; + type Balance = Balance; + type Assets = RebaseTokens; + type PalletId = StableAssetPalletId; + + type AtLeast64BitUnsigned = u128; + type FeePrecision = ConstU128<10_000_000_000>; // 10 decimals + type APrecision = ConstU128<100>; // 2 decimals + type PoolAssetLimit = ConstU32<5>; + type SwapExactOverAmount = ConstU128<100>; + type WeightInfo = (); + type ListingOrigin = EnsureSignedBy; + type EnsurePoolAssetId = EnsurePoolAssetId; } parameter_types! { pub static DexSwapJointList: Vec> = vec![]; - pub static TaigaConfig: Option = None; + pub const GetLiquidCurrencyId: CurrencyId = LDOT; } impl Config for Runtime { type DEX = Dex; - type StableAsset = MockStableAsset; + type StableAsset = StableAsset; type GovernanceOrigin = EnsureSignedBy; type DexSwapJointList = DexSwapJointList; type SwapPathLimit = ConstU32<3>; + type RebaseTokenAmountConvertor = ConvertBalanceHoma; type WeightInfo = (); } @@ -472,6 +213,7 @@ frame_support::construct_runtime!( AggregatedDex: aggregated_dex::{Pallet, Call, Storage}, Dex: module_dex::{Pallet, Call, Storage, Config, Event}, Tokens: orml_tokens::{Pallet, Storage, Event, Config}, + StableAsset: nutsfinance_stable_asset::{Pallet, Call, Storage, Event}, } ); diff --git a/modules/aggregated-dex/src/tests.rs b/modules/aggregated-dex/src/tests.rs index 3d5e06417c..26c826ed5a 100644 --- a/modules/aggregated-dex/src/tests.rs +++ b/modules/aggregated-dex/src/tests.rs @@ -23,7 +23,92 @@ use super::*; use frame_support::{assert_noop, assert_ok}; use mock::*; -use sp_runtime::{traits::BadOrigin, FixedPointNumber}; +use nutsfinance_stable_asset::traits::StableAsset as StableAssetT; +use sp_runtime::traits::BadOrigin; + +fn set_dex_swap_joint_list(joints: Vec>) { + DexSwapJointList::set(joints); +} + +fn inject_liquidity( + currency_id_a: CurrencyId, + currency_id_b: CurrencyId, + max_amount_a: Balance, + max_amount_b: Balance, +) -> Result<(), &'static str> { + // set balance + Tokens::deposit(currency_id_a, &BOB, max_amount_a)?; + Tokens::deposit(currency_id_b, &BOB, max_amount_b)?; + + let _ = Dex::enable_trading_pair(Origin::signed(BOB.clone()), currency_id_a, currency_id_b); + Dex::add_liquidity( + Origin::signed(BOB), + currency_id_a, + currency_id_b, + max_amount_a, + max_amount_b, + Default::default(), + false, + )?; + + Ok(()) +} + +fn inital_taiga_dot_ldot_pool() -> DispatchResult { + ::create_pool( + STABLE_ASSET, + vec![DOT, LDOT], + vec![1u128, 1u128], + 0, + 0, + 0, + 3000u128, + BOB, + BOB, + 10_000_000_000u128, + )?; + + Tokens::deposit(DOT, &BOB, 100_000_000_000u128)?; + Tokens::deposit(LDOT, &BOB, 1_000_000_000_000u128)?; + + ::mint(&BOB, 0, vec![100_000_000_000u128, 100_000_000_000u128], 0)?; + + Ok(()) +} + +#[test] +fn rebase_token_amount_convert_work() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(inital_taiga_dot_ldot_pool()); + + assert_eq!( + AggregatedDex::taiga_get_best_route(DOT, LDOT, 100_000_000u128), + Some((0, 0, 1, 999_983_600u128)) + ); + assert_eq!( + AggregatedDex::taiga_get_best_route(LDOT, DOT, 1_000_000_000u128), + Some((0, 1, 0, 99_998_360u128)) + ); + + assert_eq!( + AggregatedDex::taiga_get_swap_input_amount(0, 0, 1, 999_983_600u128), + Some((100_000_098u128, 999_983_600u128)) + ); + assert_eq!( + AggregatedDex::taiga_get_swap_output_amount(0, 0, 1, 100_000_000u128), + Some((100_000_000u128, 999_983_600u128)) + ); + + assert_eq!(Tokens::free_balance(DOT, &ALICE), 100_000_000_000u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 0); + assert_eq!( + AggregatedDex::taiga_swap(&ALICE, 0, 0, 1, 100_000_000u128, 0), + Ok((100_000_000u128, 999_983_600u128)) + ); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 99_900_000_000u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 999_983_600u128); + }); +} #[test] fn dex_swap_get_swap_amount_work() { @@ -148,36 +233,44 @@ fn taiga_swap_get_swap_amount_work() { None ); - set_taiga_swap(DOT, LDOT, ExchangeRate::saturating_from_rational(10, 1)); + assert_ok!(inital_taiga_dot_ldot_pool()); assert_eq!( TaigaSwap::::get_swap_amount(DOT, AUSD, SwapLimit::ExactSupply(1_000_000_000u128, 0)), None ); assert_eq!( TaigaSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactSupply(1_000_000_000u128, 0)), - Some((1_000_000_000u128, 10_000_000_000u128)) + Some((1_000_000_000u128, 9_998_360_750u128)) ); assert_eq!( TaigaSwap::::get_swap_amount( DOT, LDOT, - SwapLimit::ExactSupply(1_000_000_000u128, 10_000_000_001u128) + SwapLimit::ExactSupply(1_000_000_000u128, 9_998_360_751u128) ), None ); assert_eq!( - TaigaSwap::::get_swap_amount(DOT, AUSD, SwapLimit::ExactTarget(u128::MAX, 10_000_000_000u128)), + TaigaSwap::::get_swap_amount( + DOT, + AUSD, + SwapLimit::ExactTarget(10_000_000_000u128, 10_000_000_000u128) + ), None ); assert_eq!( - TaigaSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactTarget(u128::MAX, 10_000_000_000u128)), - Some((1_000_000_000u128, 10_000_000_000u128)) + TaigaSwap::::get_swap_amount( + DOT, + LDOT, + SwapLimit::ExactTarget(2_000_000_000u128, 9_998_360_750u128) + ), + Some((1_000_000_098u128, 9_998_361_730u128)) ); assert_eq!( TaigaSwap::::get_swap_amount( DOT, LDOT, - SwapLimit::ExactTarget(999_999_999u128, 10_000_000_000u128) + SwapLimit::ExactTarget(1_000_000_097u128, 9_998_360_750u128) ), None ); @@ -185,9 +278,9 @@ fn taiga_swap_get_swap_amount_work() { TaigaSwap::::get_swap_amount( LDOT, DOT, - SwapLimit::ExactTarget(100_000_000_000u128, 1_000_000_001u128) + SwapLimit::ExactTarget(100_000_000_000u128, 1_000_000_000u128) ), - Some((10_000_000_010u128, 1_000_000_001u128)) + Some((10_001_640_760u128, 1_000_000_098u128)) ); }); } @@ -196,64 +289,58 @@ fn taiga_swap_get_swap_amount_work() { fn taiga_swap_swap_work() { ExtBuilder::default().build().execute_with(|| { assert_noop!( - TaigaSwap::::swap( - &ALICE, - LDOT, - DOT, - SwapLimit::ExactSupply(1_000_000_000u128, 10_000_000_001u128) - ), + TaigaSwap::::swap(&ALICE, DOT, LDOT, SwapLimit::ExactSupply(1_000_000_000u128, 0)), Error::::CannotSwap ); assert_noop!( TaigaSwap::::swap( &ALICE, - LDOT, DOT, - SwapLimit::ExactTarget(1_000_000_000u128, 10_000_000_001u128) + LDOT, + SwapLimit::ExactTarget(10_000_000_000u128, 9_998_360_750u128) ), Error::::CannotSwap ); - set_taiga_swap(DOT, LDOT, ExchangeRate::saturating_from_rational(10, 1)); + assert_ok!(inital_taiga_dot_ldot_pool()); assert_eq!(Tokens::free_balance(DOT, &ALICE), 100_000_000_000u128); assert_eq!(Tokens::free_balance(LDOT, &ALICE), 0); - assert_ok!(TaigaSwap::::swap( - &ALICE, - DOT, - LDOT, - SwapLimit::ExactSupply(1_000_000_000u128, 10_000_000_000u128) - )); + assert_eq!( + TaigaSwap::::swap(&ALICE, DOT, LDOT, SwapLimit::ExactSupply(1_000_000_000u128, 0)), + Ok((1_000_000_000u128, 9_998_360_750u128)) + ); assert_eq!(Tokens::free_balance(DOT, &ALICE), 99_000_000_000u128); - assert_eq!(Tokens::free_balance(LDOT, &ALICE), 10_000_000_000u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 9_998_360_750u128); assert_noop!( TaigaSwap::::swap( &ALICE, DOT, LDOT, - SwapLimit::ExactSupply(1_000_000_000u128, 10_000_000_001u128) + SwapLimit::ExactSupply(1_000_000_000u128, 10_000_000_000u128) ), - Error::::CannotSwap + nutsfinance_stable_asset::Error::::SwapUnderMin ); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 99_000_000_000u128); - assert_eq!(Tokens::free_balance(LDOT, &ALICE), 10_000_000_000u128); - assert_ok!(TaigaSwap::::swap( - &ALICE, - DOT, - LDOT, - SwapLimit::ExactTarget(10_000_000_000u128, 10_000_000_000u128) - )); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 98_000_000_000u128); - assert_eq!(Tokens::free_balance(LDOT, &ALICE), 20_000_000_000u128); + assert_eq!( + TaigaSwap::::swap( + &ALICE, + DOT, + LDOT, + SwapLimit::ExactTarget(2_000_000_000u128, 10_000_000_000u128) + ), + Ok((1_000_492_274u128, 10_000_000_980u128)) + ); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 97_999_507_726u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 19_998_361_730u128); assert_noop!( TaigaSwap::::swap( &ALICE, DOT, LDOT, - SwapLimit::ExactTarget(999_999_999u128, 10_000_000_000u128) + SwapLimit::ExactTarget(1_000_000_000u128, 10_000_000_000u128) ), Error::::CannotSwap ); @@ -276,50 +363,66 @@ fn either_dex_or_taiga_swap_get_swap_amount_work() { None ); assert_eq!( - DexSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactTarget(u128::MAX, 10_000_000_000u128)), + DexSwap::::get_swap_amount( + DOT, + LDOT, + SwapLimit::ExactTarget(2_000_000_000u128, 10_000_000_000u128) + ), None ); assert_eq!( - TaigaSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactTarget(u128::MAX, 10_000_000_000u128)), + TaigaSwap::::get_swap_amount( + DOT, + LDOT, + SwapLimit::ExactTarget(2_000_000_000u128, 10_000_000_000u128) + ), None ); assert_eq!( EitherDexOrTaigaSwap::::get_swap_amount( DOT, LDOT, - SwapLimit::ExactTarget(u128::MAX, 10_000_000_000u128) + SwapLimit::ExactTarget(2_000_000_000u128, 10_000_000_000u128) ), None ); - set_taiga_swap(DOT, LDOT, ExchangeRate::saturating_from_rational(10, 1)); + assert_ok!(inital_taiga_dot_ldot_pool()); assert_eq!( DexSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactSupply(1_000_000_000u128, 0)), None ); assert_eq!( TaigaSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactSupply(1_000_000_000u128, 0)), - Some((1_000_000_000u128, 10_000_000_000u128)) + Some((1_000_000_000u128, 9_998_360_750u128)) ); assert_eq!( EitherDexOrTaigaSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactSupply(1_000_000_000u128, 0)), - Some((1_000_000_000u128, 10_000_000_000u128)) + Some((1_000_000_000u128, 9_998_360_750u128)) ); assert_eq!( - DexSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactTarget(u128::MAX, 10_000_000_000u128)), + DexSwap::::get_swap_amount( + DOT, + LDOT, + SwapLimit::ExactTarget(2_000_000_000u128, 10_000_000_000u128) + ), None ); assert_eq!( - TaigaSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactTarget(u128::MAX, 10_000_000_000u128)), - Some((1_000_000_000u128, 10_000_000_000u128)) + TaigaSwap::::get_swap_amount( + DOT, + LDOT, + SwapLimit::ExactTarget(2_000_000_000u128, 10_000_000_000u128) + ), + Some((1_000_164_076u128, 10_000_000_980u128)) ); assert_eq!( EitherDexOrTaigaSwap::::get_swap_amount( DOT, LDOT, - SwapLimit::ExactTarget(u128::MAX, 10_000_000_000u128) + SwapLimit::ExactTarget(2_000_000_000u128, 10_000_000_000u128) ), - Some((1_000_000_000u128, 10_000_000_000u128)) + Some((1_000_164_076u128, 10_000_000_980u128)) ); assert_ok!(inject_liquidity(DOT, LDOT, 1_000_000_000u128, 30_000_000_000u128)); @@ -329,7 +432,7 @@ fn either_dex_or_taiga_swap_get_swap_amount_work() { ); assert_eq!( TaigaSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactSupply(1_000_000_000u128, 0)), - Some((1_000_000_000u128, 10_000_000_000u128)) + Some((1_000_000_000u128, 9_998_360_750u128)) ); assert_eq!( EitherDexOrTaigaSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactSupply(1_000_000_000u128, 0)), @@ -339,7 +442,7 @@ fn either_dex_or_taiga_swap_get_swap_amount_work() { DexSwap::::get_swap_amount( DOT, LDOT, - SwapLimit::ExactTarget(1_000_000_000u128, 10_000_000_000u128) + SwapLimit::ExactTarget(2_000_000_000u128, 10_000_000_000u128) ), Some((500_000_001u128, 10_000_000_000u128)) ); @@ -347,15 +450,15 @@ fn either_dex_or_taiga_swap_get_swap_amount_work() { TaigaSwap::::get_swap_amount( DOT, LDOT, - SwapLimit::ExactTarget(1_000_000_000u128, 10_000_000_000u128) + SwapLimit::ExactTarget(2_000_000_000u128, 10_000_000_000u128) ), - Some((1_000_000_000u128, 10_000_000_000u128)) + Some((1_000_164_076u128, 10_000_000_980u128)) ); assert_eq!( EitherDexOrTaigaSwap::::get_swap_amount( DOT, LDOT, - SwapLimit::ExactTarget(1_000_000_000u128, 10_000_000_000u128) + SwapLimit::ExactTarget(2_000_000_000u128, 10_000_000_000u128) ), Some((500_000_001u128, 10_000_000_000u128)) ); @@ -366,27 +469,35 @@ fn either_dex_or_taiga_swap_get_swap_amount_work() { ); assert_eq!( TaigaSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactSupply(10_000_000_000u128, 0)), - Some((10_000_000_000u128, 100_000_000_000u128)) + Some((10_000_000_000u128, 99_834_740_530u128)) ); assert_eq!( EitherDexOrTaigaSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactSupply(10_000_000_000u128, 0)), - Some((10_000_000_000u128, 100_000_000_000u128)) + Some((10_000_000_000u128, 99_834_740_530u128)) ); assert_eq!( - DexSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactTarget(u128::MAX, 30_000_000_000u128)), + DexSwap::::get_swap_amount( + DOT, + LDOT, + SwapLimit::ExactTarget(10_000_000_000u128, 30_000_000_000u128) + ), None ); assert_eq!( - TaigaSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactTarget(u128::MAX, 30_000_000_000u128)), - Some((3_000_000_000u128, 30_000_000_000u128)) + TaigaSwap::::get_swap_amount( + DOT, + LDOT, + SwapLimit::ExactTarget(10_000_000_000u128, 30_000_000_000u128) + ), + Some((3_001_477_523u128, 30_000_000_980u128)) ); assert_eq!( EitherDexOrTaigaSwap::::get_swap_amount( DOT, LDOT, - SwapLimit::ExactTarget(u128::MAX, 30_000_000_000u128) + SwapLimit::ExactTarget(10_000_000_000u128, 30_000_000_000u128) ), - Some((3_000_000_000u128, 30_000_000_000u128)) + Some((3_001_477_523u128, 30_000_000_980u128)) ); }); } @@ -403,12 +514,12 @@ fn either_dex_or_taiga_swap_swap_work() { &ALICE, DOT, LDOT, - SwapLimit::ExactTarget(u128::MAX, 10_000_000_000u128) + SwapLimit::ExactTarget(2_000_000_000u128, 10_000_000_000u128) ), Error::::CannotSwap ); - set_taiga_swap(DOT, LDOT, ExchangeRate::saturating_from_rational(10, 1)); + assert_ok!(inital_taiga_dot_ldot_pool()); assert_eq!(Tokens::free_balance(DOT, &ALICE), 100_000_000_000u128); assert_eq!(Tokens::free_balance(LDOT, &ALICE), 0); @@ -417,55 +528,55 @@ fn either_dex_or_taiga_swap_swap_work() { &ALICE, DOT, LDOT, - SwapLimit::ExactSupply(1_000_000_000u128, 10_000_000_001u128) + SwapLimit::ExactSupply(1_000_000_000u128, 10_000_000_000u128) ), Error::::CannotSwap ); - assert_ok!(EitherDexOrTaigaSwap::::swap( - &ALICE, - DOT, - LDOT, - SwapLimit::ExactSupply(1_000_000_000u128, 10_000_000_000u128) - )); + assert_eq!( + EitherDexOrTaigaSwap::::swap( + &ALICE, + DOT, + LDOT, + SwapLimit::ExactSupply(1_000_000_000u128, 9_000_000_000u128) + ), + Ok((1_000_000_000u128, 9_998_360_750u128)) + ); assert_eq!(Tokens::free_balance(DOT, &ALICE), 99_000_000_000u128); - assert_eq!(Tokens::free_balance(LDOT, &ALICE), 10_000_000_000u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 9_998_360_750u128); assert_noop!( EitherDexOrTaigaSwap::::swap( &ALICE, DOT, LDOT, - SwapLimit::ExactTarget(999_999_999u128, 10_000_000_000u128) + SwapLimit::ExactTarget(1_000_000_000u128, 9_998_360_750u128) ), Error::::CannotSwap ); - assert_ok!(EitherDexOrTaigaSwap::::swap( - &ALICE, - DOT, - LDOT, - SwapLimit::ExactTarget(1_000_000_000u128, 10_000_000_000u128) - )); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 98_000_000_000u128); - assert_eq!(Tokens::free_balance(LDOT, &ALICE), 20_000_000_000u128); + assert_eq!( + EitherDexOrTaigaSwap::::swap( + &ALICE, + DOT, + LDOT, + SwapLimit::ExactTarget(2_000_000_000u128, 10_000_000_000u128) + ), + Ok((1_000_492_274u128, 10_000_000_980u128)) + ); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 97_999_507_726u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 19_998_361_730u128); assert_ok!(inject_liquidity(DOT, LDOT, 100_000_000_000u128, 2_000_000_000_000u128)); - assert_ok!(EitherDexOrTaigaSwap::::swap( - &ALICE, - DOT, - LDOT, - SwapLimit::ExactSupply(1_000_000_000u128, 10_000_000_000u128) - )); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 97_000_000_000u128); - assert_eq!(Tokens::free_balance(LDOT, &ALICE), 39_801_980_198u128); - - assert_ok!(EitherDexOrTaigaSwap::::swap( - &ALICE, - DOT, - LDOT, - SwapLimit::ExactTarget(1_000_000_000u128, 10_000_000_000u128) - )); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 964_873_611_73u128); - assert_eq!(Tokens::free_balance(LDOT, &ALICE), 49_801_980_198u128); + assert_eq!( + EitherDexOrTaigaSwap::::swap( + &ALICE, + DOT, + LDOT, + SwapLimit::ExactSupply(1_000_000_000u128, 10_000_000_000u128) + ), + Ok((1_000_000_000u128, 19_801_980_198u128)) + ); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 96_999_507_726u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 39_800_341_928u128); }); } @@ -499,7 +610,7 @@ fn check_swap_paths_work() { Error::::InvalidSwapPath ); - set_taiga_swap(DOT, LDOT, ExchangeRate::saturating_from_rational(10, 1)); + assert_ok!(inital_taiga_dot_ldot_pool()); assert_ok!(AggregatedDex::check_swap_paths(&vec![SwapPath::Taiga(0, 0, 1)])); assert_noop!( AggregatedDex::check_swap_paths(&vec![SwapPath::Taiga(0, 2, 0)]), @@ -589,32 +700,32 @@ fn get_aggregated_swap_amount_work() { None ); - set_taiga_swap(DOT, LDOT, ExchangeRate::saturating_from_rational(10, 1)); + assert_ok!(inital_taiga_dot_ldot_pool()); assert_eq!( AggregatedDex::get_aggregated_swap_amount( &vec![SwapPath::Taiga(0, 0, 1)], SwapLimit::ExactSupply(1_000_000_000u128, 0) ), - Some((1_000_000_000u128, 10_000_000_000u128)) + Some((1_000_000_000u128, 9_998_360_750u128)) ); assert_eq!( AggregatedDex::get_aggregated_swap_amount( &vec![SwapPath::Taiga(0, 0, 1)], - SwapLimit::ExactSupply(1_000_000_000u128, 10_000_000_001u128) + SwapLimit::ExactSupply(1_000_000_000u128, 10_000_000_000u128) ), None ); assert_eq!( AggregatedDex::get_aggregated_swap_amount( &vec![SwapPath::Taiga(0, 0, 1)], - SwapLimit::ExactTarget(1_000_000_000u128, 10_000_000_000u128) + SwapLimit::ExactTarget(2_000_000_000u128, 10_000_000_000u128) ), - Some((1_000_000_000u128, 10_000_000_000u128)) + Some((1_000_164_076u128, 10_000_000_980u128)) ); assert_eq!( AggregatedDex::get_aggregated_swap_amount( &vec![SwapPath::Taiga(0, 0, 1)], - SwapLimit::ExactTarget(999_999_999u128, 10_000_000_000u128) + SwapLimit::ExactTarget(1_000_000_000u128, 10_000_000_000u128) ), None ); @@ -624,26 +735,26 @@ fn get_aggregated_swap_amount_work() { &vec![SwapPath::Taiga(0, 0, 1), SwapPath::Dex(vec![LDOT, AUSD])], SwapLimit::ExactSupply(1_000_000_000u128, 0) ), - Some((1_000_000_000u128, 1_818_181_818_181u128)) + Some((1_000_000_000u128, 1_817_910_863_730u128)) ); assert_eq!( AggregatedDex::get_aggregated_swap_amount( &vec![SwapPath::Taiga(0, 0, 1), SwapPath::Dex(vec![LDOT, AUSD])], - SwapLimit::ExactSupply(1_000_000_000u128, 1_818_181_818_182u128) + SwapLimit::ExactSupply(1_000_000_000u128, 1_817_910_863_731u128) ), None ); assert_eq!( AggregatedDex::get_aggregated_swap_amount( &vec![SwapPath::Taiga(0, 0, 1), SwapPath::Dex(vec![LDOT, AUSD])], - SwapLimit::ExactTarget(1_000_000_000u128, 1_818_181_818_181u128) + SwapLimit::ExactTarget(2_000_000_000u128, 1_817_910_863_730u128) ), - Some((1_000_000_000u128, 1_818_181_818_181u128)) + Some((1_000_000_098u128, 1_817_911_025_719u128)) ); assert_eq!( AggregatedDex::get_aggregated_swap_amount( &vec![SwapPath::Taiga(0, 0, 1), SwapPath::Dex(vec![LDOT, AUSD])], - SwapLimit::ExactTarget(999_999_999u128, 1_818_181_818_181u128) + SwapLimit::ExactTarget(1_000_000_097u128, 1_817_910_863_730u128) ), None ); @@ -651,35 +762,21 @@ fn get_aggregated_swap_amount_work() { assert_eq!( AggregatedDex::get_aggregated_swap_amount( &vec![SwapPath::Dex(vec![AUSD, LDOT]), SwapPath::Taiga(0, 1, 0)], - SwapLimit::ExactSupply(1_818_181_818_181u128, 0) - ), - Some((1_818_181_818_181u128, 833_333_333u128)) - ); - assert_eq!( - AggregatedDex::get_aggregated_swap_amount( - &vec![SwapPath::Dex(vec![AUSD, LDOT]), SwapPath::Taiga(0, 1, 0)], - SwapLimit::ExactSupply(2_222_222_222_223u128, 1_000_000_000u128) - ), - Some((2_222_222_222_223u128, 1_000_000_000u128)) - ); - assert_eq!( - AggregatedDex::get_aggregated_swap_amount( - &vec![SwapPath::Dex(vec![AUSD, LDOT]), SwapPath::Taiga(0, 1, 0)], - SwapLimit::ExactSupply(2_222_222_222_222u128, 1_000_000_000u128) + SwapLimit::ExactSupply(1_817_910_863_730u128, 0) ), - None + Some((1_817_910_863_730u128, 833_105_687u128)) ); assert_eq!( AggregatedDex::get_aggregated_swap_amount( &vec![SwapPath::Dex(vec![AUSD, LDOT]), SwapPath::Taiga(0, 1, 0)], - SwapLimit::ExactTarget(2_222_222_222_223u128, 1_000_000_000u128) + SwapLimit::ExactTarget(3_000_000_000_000u128, 1_000_000_000u128) ), - Some((2_222_222_222_223u128, 1_000_000_000u128)) + Some((2_222_627_355_534u128, 1_000_000_098u128)) ); assert_eq!( AggregatedDex::get_aggregated_swap_amount( &vec![SwapPath::Dex(vec![AUSD, LDOT]), SwapPath::Taiga(0, 1, 0)], - SwapLimit::ExactTarget(2_222_222_222_222u128, 1_000_000_000u128) + SwapLimit::ExactTarget(2_222_627_355_533u128, 1_000_000_000u128) ), None ); @@ -714,7 +811,7 @@ fn do_aggregated_swap_work() { Error::::InvalidPoolId ); - set_taiga_swap(DOT, LDOT, ExchangeRate::saturating_from_rational(10, 1)); + assert_ok!(inital_taiga_dot_ldot_pool()); assert_noop!( AggregatedDex::do_aggregated_swap( &ALICE, @@ -734,22 +831,28 @@ fn do_aggregated_swap_work() { assert_eq!(Tokens::free_balance(DOT, &ALICE), 100_000_000_000u128); assert_eq!(Tokens::free_balance(LDOT, &ALICE), 0); - assert_ok!(AggregatedDex::do_aggregated_swap( - &ALICE, - &vec![SwapPath::Taiga(0, 0, 1)], - SwapLimit::ExactSupply(1_000_000_000u128, 0) - )); + assert_eq!( + AggregatedDex::do_aggregated_swap( + &ALICE, + &vec![SwapPath::Taiga(0, 0, 1)], + SwapLimit::ExactSupply(1_000_000_000u128, 0) + ), + Ok((1_000_000_000u128, 9_998_360_750u128)) + ); assert_eq!(Tokens::free_balance(DOT, &ALICE), 99_000_000_000u128); - assert_eq!(Tokens::free_balance(LDOT, &ALICE), 10_000_000_000u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 9_998_360_750u128); assert_eq!(Tokens::free_balance(AUSD, &ALICE), 0); - assert_ok!(AggregatedDex::do_aggregated_swap( - &ALICE, - &vec![SwapPath::Taiga(0, 0, 1)], - SwapLimit::ExactTarget(u128::MAX, 10_000_000_000u128) - )); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 98_000_000_000u128); - assert_eq!(Tokens::free_balance(LDOT, &ALICE), 20_000_000_000u128); + assert_eq!( + AggregatedDex::do_aggregated_swap( + &ALICE, + &vec![SwapPath::Taiga(0, 0, 1)], + SwapLimit::ExactTarget(2_000_000_000u128, 10_000_000_000u128) + ), + Ok((1_000_492_274u128, 10_000_000_980u128)) + ); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 97_999_507_726u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 19_998_361_730u128); assert_eq!(Tokens::free_balance(AUSD, &ALICE), 0); assert_ok!(inject_liquidity( @@ -767,45 +870,57 @@ fn do_aggregated_swap_work() { Error::::CannotSwap ); - assert_ok!(AggregatedDex::do_aggregated_swap( - &ALICE, - &vec![SwapPath::Dex(vec![LDOT, AUSD])], - SwapLimit::ExactSupply(1_000_000_000u128, 0) - )); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 98_000_000_000u128); - assert_eq!(Tokens::free_balance(LDOT, &ALICE), 19_000_000_000u128); + assert_eq!( + AggregatedDex::do_aggregated_swap( + &ALICE, + &vec![SwapPath::Dex(vec![LDOT, AUSD])], + SwapLimit::ExactSupply(1_000_000_000u128, 0) + ), + Ok((1_000_000_000u128, 198_019_801_980u128)) + ); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 97_999_507_726u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 18_998_361_730u128); assert_eq!(Tokens::free_balance(AUSD, &ALICE), 198_019_801_980u128); - assert_ok!(AggregatedDex::do_aggregated_swap( - &ALICE, - &vec![SwapPath::Dex(vec![LDOT, AUSD])], - SwapLimit::ExactTarget(1_000_000_000u128, 10_000_000_000u128) - )); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 98_000_000_000u128); - assert_eq!(Tokens::free_balance(LDOT, &ALICE), 18_948_969_229u128); + assert_eq!( + AggregatedDex::do_aggregated_swap( + &ALICE, + &vec![SwapPath::Dex(vec![LDOT, AUSD])], + SwapLimit::ExactTarget(1_000_000_000u128, 10_000_000_000u128) + ), + Ok((51_030_771u128, 10_000_000_090u128)) + ); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 97_999_507_726u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 18_947_330_959u128); // actually swap by ExactSupply, actual target amount may be slightly more than exact target amount // of limit assert_eq!(Tokens::free_balance(AUSD, &ALICE), 208_019_802_070u128); - assert_ok!(AggregatedDex::do_aggregated_swap( - &ALICE, - &vec![SwapPath::Taiga(0, 0, 1), SwapPath::Dex(vec![LDOT, AUSD])], - SwapLimit::ExactSupply(1_000_000_000u128, 0) - )); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 97_000_000_000u128); - assert_eq!(Tokens::free_balance(LDOT, &ALICE), 18_948_969_229u128); - assert_eq!(Tokens::free_balance(AUSD, &ALICE), 1_990_261_719_188u128); + assert_eq!( + AggregatedDex::do_aggregated_swap( + &ALICE, + &vec![SwapPath::Taiga(0, 0, 1), SwapPath::Dex(vec![LDOT, AUSD])], + SwapLimit::ExactSupply(1_000_000_000u128, 0) + ), + Ok((1_000_000_000u128, 1_780_911_406_971u128)) + ); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 96_999_507_726u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 18_947_330_959u128); + assert_eq!(Tokens::free_balance(AUSD, &ALICE), 1_988_931_209_041u128); - assert_ok!(AggregatedDex::do_aggregated_swap( - &ALICE, - &vec![SwapPath::Taiga(0, 0, 1), SwapPath::Dex(vec![LDOT, AUSD])], - SwapLimit::ExactTarget(1_000_000_000_000u128, 1_000_000_000_000u128) - )); - assert_eq!(Tokens::free_balance(DOT, &ALICE), 96_347_132_631u128); - assert_eq!(Tokens::free_balance(LDOT, &ALICE), 18_948_969_229u128); + assert_eq!( + AggregatedDex::do_aggregated_swap( + &ALICE, + &vec![SwapPath::Taiga(0, 0, 1), SwapPath::Dex(vec![LDOT, AUSD])], + SwapLimit::ExactTarget(1_000_000_000_000u128, 1_000_000_000_000u128) + ), + Ok((653_482_016u128, 1_000_000_140_971u128)) + ); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 96_346_025_710u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 18_947_330_959u128); // actually swap by ExactSupply, actual target amount may be slightly more than exact target amount // of limit - assert_eq!(Tokens::free_balance(AUSD, &ALICE), 2_990_261_719_330u128); + assert_eq!(Tokens::free_balance(AUSD, &ALICE), 2_988_931_350_012u128); }); } @@ -834,7 +949,7 @@ fn update_aggregated_swap_paths_work() { Error::::InvalidPoolId ); - set_taiga_swap(DOT, LDOT, ExchangeRate::saturating_from_rational(10, 1)); + assert_ok!(inital_taiga_dot_ldot_pool()); assert_noop!( AggregatedDex::update_aggregated_swap_paths( @@ -920,14 +1035,14 @@ fn aggregated_swap_get_swap_amount_work() { Some((3_000_000_000u128, 22_500_000_000u128)) ); - set_taiga_swap(DOT, LDOT, ExchangeRate::saturating_from_rational(10, 1)); + assert_ok!(inital_taiga_dot_ldot_pool()); assert_eq!( AggregatedSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactSupply(1_000_000_000u128, 0)), Some((1_000_000_000u128, 15_000_000_000u128)) ); assert_eq!( AggregatedSwap::::get_swap_amount(DOT, LDOT, SwapLimit::ExactSupply(3_000_000_000u128, 0)), - Some((3_000_000_000u128, 30_000_000_000u128)) + Some((3_000_000_000u128, 29_985_240_300u128)) ); assert_ok!(inject_liquidity(LDOT, AUSD, 30_000_000_000u128, 60_000_000_000u128)); @@ -946,7 +1061,7 @@ fn aggregated_swap_get_swap_amount_work() { )); assert_eq!( AggregatedSwap::::get_swap_amount(DOT, AUSD, SwapLimit::ExactSupply(3_000_000_000u128, 0)), - Some((3_000_000_000u128, 30_000_000_000u128)) + Some((3_000_000_000u128, 29_992_618_334u128)) ); assert_eq!( AggregatedSwap::::get_swap_amount(AUSD, DOT, SwapLimit::ExactSupply(30_000_000_000u128, 0)), @@ -966,16 +1081,20 @@ fn aggregated_swap_get_swap_amount_work() { ); assert_eq!( AggregatedSwap::::get_swap_amount(LDOT, DOT, SwapLimit::ExactSupply(10_000_000_000u128, 0)), - Some((10_000_000_000u128, 1_000_000_000u128)) + Some((10_000_000_000u128, 999_836_075u128)) ); assert_eq!( AggregatedSwap::::get_swap_amount(AUSD, DOT, SwapLimit::ExactSupply(30_000_000_000u128, 0)), - Some((30_000_000_000u128, 1_000_000_000u128)) + Some((30_000_000_000u128, 999_836_075u128)) ); assert_eq!( - AggregatedSwap::::get_swap_amount(LDOT, DOT, SwapLimit::ExactTarget(u128::MAX, 1_000_000_000u128)), - Some((10_000_000_000u128, 1_000_000_000u128)) + AggregatedSwap::::get_swap_amount( + LDOT, + DOT, + SwapLimit::ExactTarget(20_000_000_000u128, 1_000_000_000u128) + ), + Some((10_001_640_760u128, 1_000_000_098u128)) ); assert_eq!( AggregatedSwap::::get_swap_amount( @@ -987,7 +1106,7 @@ fn aggregated_swap_get_swap_amount_work() { ); assert_eq!( AggregatedSwap::::get_swap_amount(AUSD, DOT, SwapLimit::ExactTarget(u128::MAX, 1_000_000_000u128)), - Some((30_000_000_001u128, 1_000_000_000u128)) + Some((30_007_384_026u128, 1_000_000_098u128)) ); }); } @@ -1022,15 +1141,18 @@ fn aggregated_swap_swap_work() { assert_eq!(Tokens::free_balance(DOT, &ALICE), 99_000_000_000u128); assert_eq!(Tokens::free_balance(LDOT, &ALICE), 15_000_000_000u128); - set_taiga_swap(DOT, LDOT, ExchangeRate::saturating_from_rational(10, 1)); - assert_ok!(AggregatedSwap::::swap( - &ALICE, - DOT, - LDOT, - SwapLimit::ExactSupply(1_000_000_000u128, 10_000_000_000u128) - )); + assert_ok!(inital_taiga_dot_ldot_pool()); + assert_eq!( + AggregatedSwap::::swap( + &ALICE, + DOT, + LDOT, + SwapLimit::ExactSupply(1_000_000_000u128, 9_000_000_000u128) + ), + Ok((1_000_000_000u128, 9_998_360_750u128)) + ); assert_eq!(Tokens::free_balance(DOT, &ALICE), 98_000_000_000u128); - assert_eq!(Tokens::free_balance(LDOT, &ALICE), 25_000_000_000u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 24_998_360_750u128); assert_ok!(inject_liquidity(LDOT, AUSD, 30_000_000_000u128, 60_000_000_000u128)); @@ -1048,14 +1170,20 @@ fn aggregated_swap_swap_work() { )); assert_eq!(Tokens::free_balance(AUSD, &ALICE), 0); - assert_ok!(AggregatedSwap::::swap( - &ALICE, - DOT, - AUSD, - SwapLimit::ExactSupply(3_000_000_000u128, 0) - )); + assert_eq!( + AggregatedSwap::::swap(&ALICE, DOT, AUSD, SwapLimit::ExactSupply(3_000_000_000u128, 0)), + Ok((3_000_000_000u128, 29_987_688_109u128)) + ); assert_eq!(Tokens::free_balance(DOT, &ALICE), 95_000_000_000u128); - assert_eq!(Tokens::free_balance(LDOT, &ALICE), 25_000_000_000u128); - assert_eq!(Tokens::free_balance(AUSD, &ALICE), 30_000_000_000u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 24_998_360_750u128); + assert_eq!(Tokens::free_balance(AUSD, &ALICE), 29_987_688_109u128); + + assert_eq!( + AggregatedSwap::::swap(&ALICE, DOT, AUSD, SwapLimit::ExactTarget(u128::MAX, 10_000_000_000u128)), + Ok((3_002_366_414u128, 10_000_000_216u128)) + ); + assert_eq!(Tokens::free_balance(DOT, &ALICE), 91_997_633_586u128); + assert_eq!(Tokens::free_balance(LDOT, &ALICE), 24_998_360_750u128); + assert_eq!(Tokens::free_balance(AUSD, &ALICE), 39_987_688_325u128); }); } diff --git a/modules/asset-registry/Cargo.toml b/modules/asset-registry/Cargo.toml index f1c26a2128..ee00ffd65a 100644 --- a/modules/asset-registry/Cargo.toml +++ b/modules/asset-registry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-asset-registry" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" @@ -16,8 +16,6 @@ frame-system = { git = "https://github.com/paritytech/substrate", branch = "polk primitives = { package = "acala-primitives", path = "../../primitives", default-features = false } xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.22", default-features = false } -xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.22", default-features = false } -xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.22", default-features = false } module-support = { path = "../support", default-features = false } @@ -46,8 +44,6 @@ std = [ "frame-system/std", "primitives/std", "xcm/std", - "xcm-builder/std", - "xcm-executor/std", "module-support/std", ] try-runtime = ["frame-support/try-runtime"] diff --git a/modules/asset-registry/src/lib.rs b/modules/asset-registry/src/lib.rs index 691d3e4eb0..0b30f9fc5f 100644 --- a/modules/asset-registry/src/lib.rs +++ b/modules/asset-registry/src/lib.rs @@ -30,10 +30,9 @@ use frame_support::{ pallet_prelude::*, traits::{Currency, EnsureOrigin}, transactional, - weights::constants::WEIGHT_PER_SECOND, }; use frame_system::pallet_prelude::*; -use module_support::{AssetIdMapping, BuyWeightRate, EVMBridge, Erc20InfoMapping, InvokeContext, Rate}; +use module_support::{AssetIdMapping, BuyWeightRate, EVMBridge, Erc20InfoMapping, InvokeContext, Ratio}; use primitives::{ currency::{ AssetIds, AssetMetadata, CurrencyIdType, DexShare, DexShareType, Erc20Id, ForeignAssetId, Lease, @@ -50,15 +49,10 @@ use scale_info::prelude::format; use sp_runtime::{traits::One, ArithmeticError, FixedPointNumber, FixedU128}; use sp_std::{boxed::Box, vec::Vec}; -// NOTE:v1::MultiLocation is used in storages, we would need to do migration if upgrade the -// MultiLocation in the future. -use xcm::opaque::latest::{prelude::XcmError, AssetId, Fungibility::Fungible, MultiAsset}; use xcm::{ v1::{Junction, Junctions::*, MultiLocation}, VersionedMultiLocation, }; -use xcm_builder::TakeRevenue; -use xcm_executor::{traits::WeightTrader, Assets}; mod mock; mod tests; @@ -565,7 +559,7 @@ impl BuyWeightRate for BuyWeightRateOfForeignAsset where BalanceOf: Into, { - fn calculate_rate(location: MultiLocation) -> Option { + fn calculate_rate(location: MultiLocation) -> Option { if let Some(CurrencyId::ForeignAsset(foreign_asset_id)) = Pallet::::location_to_currency_ids(location) { if let Some(asset_metadata) = Pallet::::asset_metadatas(AssetIds::ForeignAssetId(foreign_asset_id)) { let minimum_balance = asset_metadata.minimal_balance.into(); @@ -584,7 +578,7 @@ impl BuyWeightRate for BuyWeightRateOfErc20 where BalanceOf: Into, { - fn calculate_rate(location: MultiLocation) -> Option { + fn calculate_rate(location: MultiLocation) -> Option { match location { MultiLocation { parents: 0, @@ -613,118 +607,6 @@ where } } -/// Simple fee calculator that requires payment in a single fungible at a fixed rate. -/// -/// The constant `FixedRate` type parameter should be the concrete fungible ID and the amount of it -/// required for one second of weight. -pub struct FixedRateOfAssetRegistry, R: TakeRevenue, M: BuyWeightRate> { - weight: Weight, - amount: u128, - ed_ratio: FixedU128, - multi_location: Option, - _marker: PhantomData<(FixedRate, R, M)>, -} - -impl, R: TakeRevenue, M: BuyWeightRate> WeightTrader - for FixedRateOfAssetRegistry -{ - fn new() -> Self { - Self { - weight: 0, - amount: 0, - ed_ratio: Default::default(), - multi_location: None, - _marker: PhantomData, - } - } - - fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { - log::trace!(target: "asset-registry::weight", "buy_weight weight: {:?}, payment: {:?}", weight, payment); - - // only support first fungible assets now. - let asset_id = payment - .fungible - .iter() - .next() - .map_or(Err(XcmError::TooExpensive), |v| Ok(v.0))?; - - if let AssetId::Concrete(ref multi_location) = asset_id { - log::debug!(target: "asset-registry::weight", "buy_weight multi_location: {:?}", multi_location); - - if let Some(ed_ratio) = M::calculate_rate(multi_location.clone()) { - // The WEIGHT_PER_SECOND is non-zero. - let weight_ratio = FixedU128::saturating_from_rational(weight as u128, WEIGHT_PER_SECOND as u128); - let amount = ed_ratio.saturating_mul_int(weight_ratio.saturating_mul_int(FixedRate::get())); - - let required = MultiAsset { - id: asset_id.clone(), - fun: Fungible(amount), - }; - - log::trace!( - target: "asset-registry::weight", "buy_weight payment: {:?}, required: {:?}, fixed_rate: {:?}, ed_ratio: {:?}, weight_ratio: {:?}", - payment, required, FixedRate::get(), ed_ratio, weight_ratio - ); - let unused = payment - .clone() - .checked_sub(required) - .map_err(|_| XcmError::TooExpensive)?; - self.weight = self.weight.saturating_add(weight); - self.amount = self.amount.saturating_add(amount); - self.ed_ratio = ed_ratio; - self.multi_location = Some(multi_location.clone()); - return Ok(unused); - } - } - - log::trace!(target: "asset-registry::weight", "no concrete fungible asset"); - Err(XcmError::TooExpensive) - } - - fn refund_weight(&mut self, weight: Weight) -> Option { - log::trace!( - target: "asset-registry::weight", "refund_weight weight: {:?}, weight: {:?}, amount: {:?}, ed_ratio: {:?}, multi_location: {:?}", - weight, self.weight, self.amount, self.ed_ratio, self.multi_location - ); - let weight = weight.min(self.weight); - let weight_ratio = FixedU128::saturating_from_rational(weight as u128, WEIGHT_PER_SECOND as u128); - let amount = self - .ed_ratio - .saturating_mul_int(weight_ratio.saturating_mul_int(FixedRate::get())); - - self.weight = self.weight.saturating_sub(weight); - self.amount = self.amount.saturating_sub(amount); - - log::trace!(target: "asset-registry::weight", "refund_weight amount: {:?}", amount); - if amount > 0 && self.multi_location.is_some() { - Some( - ( - self.multi_location.as_ref().expect("checked is non-empty; qed").clone(), - amount, - ) - .into(), - ) - } else { - None - } - } -} - -impl, R: TakeRevenue, M: BuyWeightRate> Drop for FixedRateOfAssetRegistry { - fn drop(&mut self) { - log::trace!(target: "asset-registry::weight", "take revenue, weight: {:?}, amount: {:?}, multi_location: {:?}", self.weight, self.amount, self.multi_location); - if self.amount > 0 && self.multi_location.is_some() { - R::take_revenue( - ( - self.multi_location.as_ref().expect("checked is non-empty; qed").clone(), - self.amount, - ) - .into(), - ); - } - } -} - pub struct EvmErc20InfoMapping(sp_std::marker::PhantomData); impl EvmErc20InfoMapping { diff --git a/modules/auction-manager/Cargo.toml b/modules/auction-manager/Cargo.toml index db6579ffd7..e84cd55219 100644 --- a/modules/auction-manager/Cargo.toml +++ b/modules/auction-manager/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-auction-manager" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/cdp-engine/Cargo.toml b/modules/cdp-engine/Cargo.toml index a69ac27391..fd129cb7da 100644 --- a/modules/cdp-engine/Cargo.toml +++ b/modules/cdp-engine/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-cdp-engine" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/cdp-treasury/Cargo.toml b/modules/cdp-treasury/Cargo.toml index cfb12dd3e8..918e23fa6e 100644 --- a/modules/cdp-treasury/Cargo.toml +++ b/modules/cdp-treasury/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-cdp-treasury" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/collator-selection/Cargo.toml b/modules/collator-selection/Cargo.toml index f6b856812e..8da762eacb 100644 --- a/modules/collator-selection/Cargo.toml +++ b/modules/collator-selection/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'module-collator-selection' -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/currencies/Cargo.toml b/modules/currencies/Cargo.toml index ff9c31d098..8ccc7c4da5 100644 --- a/modules/currencies/Cargo.toml +++ b/modules/currencies/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-currencies" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/currencies/src/lib.rs b/modules/currencies/src/lib.rs index fe0a74728d..ca76e19e1b 100644 --- a/modules/currencies/src/lib.rs +++ b/modules/currencies/src/lib.rs @@ -137,6 +137,18 @@ pub mod module { to: T::AccountId, amount: BalanceOf, }, + /// Withdrawn some balances from an account + Withdrawn { + currency_id: CurrencyId, + who: T::AccountId, + amount: BalanceOf, + }, + /// Deposited some balance into an account + Deposited { + currency_id: CurrencyId, + who: T::AccountId, + amount: BalanceOf, + }, /// Dust swept. DustSwept { currency_id: CurrencyId, @@ -364,12 +376,38 @@ impl MultiCurrency for Pallet { return Ok(()); } match currency_id { - CurrencyId::Erc20(_) => >::transfer( - currency_id, - &T::AddressMapping::get_account_id(&T::Erc20HoldingAccount::get()), - who, - amount, - ), + CurrencyId::Erc20(contract) => { + // deposit from erc20 holding account to receiver(who). in xcm case which receive erc20 from sibling + // parachain, we choose receiver to charge storage fee. we must make sure receiver has enough native + // token to charge storage fee. + let sender = T::Erc20HoldingAccount::get(); + let from = T::AddressMapping::get_account_id(&sender); + ensure!( + !Self::free_balance(currency_id, &from).is_zero(), + Error::::DepositFailed + ); + let receiver = T::AddressMapping::get_or_create_evm_address(who); + T::EVMBridge::transfer( + InvokeContext { + contract, + sender, + origin: receiver, + }, + receiver, + amount, + )?; + Self::deposit_event(Event::Withdrawn { + currency_id, + who: from, + amount, + }); + Self::deposit_event(Event::Deposited { + currency_id, + who: who.clone(), + amount, + }); + Ok(()) + } id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::deposit(who, amount), _ => T::MultiCurrency::deposit(currency_id, who, amount), } @@ -381,12 +419,34 @@ impl MultiCurrency for Pallet { } match currency_id { - CurrencyId::Erc20(_) => >::transfer( - currency_id, - who, - &T::AddressMapping::get_account_id(&T::Erc20HoldingAccount::get()), - amount, - ), + CurrencyId::Erc20(contract) => { + // withdraw from sender(who) to erc20 holding account. in xcm case which receive erc20 from sibling + // parachain, sender is sibling parachain sovereign account. As the origin here is used to charge + // storage fee, we must make sure sibling parachain sovereign account has enough native token to + // charge storage fee. + let receiver = T::Erc20HoldingAccount::get(); + let sender = T::AddressMapping::get_evm_address(who).ok_or(Error::::EvmAccountNotFound)?; + T::EVMBridge::transfer( + InvokeContext { + contract, + sender, + origin: sender, + }, + receiver, + amount, + )?; + Self::deposit_event(Event::Withdrawn { + currency_id, + who: who.clone(), + amount, + }); + Self::deposit_event(Event::Deposited { + currency_id, + who: T::AddressMapping::get_account_id(&receiver), + amount, + }); + Ok(()) + } id if id == T::GetNativeCurrencyId::get() => T::NativeCurrency::withdraw(who, amount), _ => T::MultiCurrency::withdraw(currency_id, who, amount), } diff --git a/modules/currencies/src/tests.rs b/modules/currencies/src/tests.rs index 86d6cee96f..b4e9858510 100644 --- a/modules/currencies/src/tests.rs +++ b/modules/currencies/src/tests.rs @@ -1330,9 +1330,11 @@ fn fungible_mutate_trait_should_work() { &alice(), 0 )); + // mint_into will deposit erc20 holding account to recipient. + // but here erc20 holding account don't have enough balance. assert_noop!( >::mint_into(CurrencyId::Erc20(erc20_address()), &alice(), 1), - Error::::RealOriginNotFound + Error::::DepositFailed ); assert_eq!(>::total_issuance(), 101000); diff --git a/modules/dex-oracle/Cargo.toml b/modules/dex-oracle/Cargo.toml index 88a168ccd0..84d655b122 100644 --- a/modules/dex-oracle/Cargo.toml +++ b/modules/dex-oracle/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-dex-oracle" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/dex/Cargo.toml b/modules/dex/Cargo.toml index 58d4f141b5..c03091f260 100644 --- a/modules/dex/Cargo.toml +++ b/modules/dex/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-dex" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/earning/Cargo.toml b/modules/earning/Cargo.toml index 206285e204..4931c5130b 100644 --- a/modules/earning/Cargo.toml +++ b/modules/earning/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-earning" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/emergency-shutdown/Cargo.toml b/modules/emergency-shutdown/Cargo.toml index 9361500882..6c0f3bd246 100644 --- a/modules/emergency-shutdown/Cargo.toml +++ b/modules/emergency-shutdown/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-emergency-shutdown" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/emergency-shutdown/src/lib.rs b/modules/emergency-shutdown/src/lib.rs index 68ec17e30b..88474e4d94 100644 --- a/modules/emergency-shutdown/src/lib.rs +++ b/modules/emergency-shutdown/src/lib.rs @@ -55,7 +55,6 @@ pub mod module { type Event: From> + IsType<::Event>; /// The list of valid collateral currency types - #[pallet::constant] type CollateralCurrencyIds: Get>; /// Price source to freeze currencies' price diff --git a/modules/evm-accounts/Cargo.toml b/modules/evm-accounts/Cargo.toml index c869686691..9e0013abcc 100644 --- a/modules/evm-accounts/Cargo.toml +++ b/modules/evm-accounts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-evm-accounts" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/evm-bridge/Cargo.toml b/modules/evm-bridge/Cargo.toml index da0413bf73..302c7c0dde 100644 --- a/modules/evm-bridge/Cargo.toml +++ b/modules/evm-bridge/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-evm-bridge" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/evm-utility/Cargo.toml b/modules/evm-utility/Cargo.toml index 3ae42bc0ad..704ac4aa5a 100644 --- a/modules/evm-utility/Cargo.toml +++ b/modules/evm-utility/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-evm-utility" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/evm-utility/macro/Cargo.toml b/modules/evm-utility/macro/Cargo.toml index 43fdb4fe64..df697ee1d9 100644 --- a/modules/evm-utility/macro/Cargo.toml +++ b/modules/evm-utility/macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-evm-utility-macro" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/evm/Cargo.toml b/modules/evm/Cargo.toml index 2328399958..b4774612c5 100644 --- a/modules/evm/Cargo.toml +++ b/modules/evm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-evm" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/evm/rpc/Cargo.toml b/modules/evm/rpc/Cargo.toml index a1068ce555..a516f5ef63 100644 --- a/modules/evm/rpc/Cargo.toml +++ b/modules/evm/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "evm-rpc" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/evm/rpc/runtime_api/Cargo.toml b/modules/evm/rpc/runtime_api/Cargo.toml index d8cc719d20..fb17572bbb 100644 --- a/modules/evm/rpc/runtime_api/Cargo.toml +++ b/modules/evm/rpc/runtime_api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-evm-rpc-runtime-api" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/example/Cargo.toml b/modules/example/Cargo.toml index 650bbb35e5..33572be76c 100644 --- a/modules/example/Cargo.toml +++ b/modules/example/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-example" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/homa-lite/Cargo.toml b/modules/homa-lite/Cargo.toml index 3a0b5cdb23..1480469776 100644 --- a/modules/homa-lite/Cargo.toml +++ b/modules/homa-lite/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-homa-lite" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/homa-validator-list/Cargo.toml b/modules/homa-validator-list/Cargo.toml index f7c21ab023..e66af87c2f 100644 --- a/modules/homa-validator-list/Cargo.toml +++ b/modules/homa-validator-list/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-homa-validator-list" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/homa/Cargo.toml b/modules/homa/Cargo.toml index c696043245..f71bca17ab 100644 --- a/modules/homa/Cargo.toml +++ b/modules/homa/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-homa" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/honzon-bridge/Cargo.toml b/modules/honzon-bridge/Cargo.toml index cf12f95761..de6a1d3b73 100644 --- a/modules/honzon-bridge/Cargo.toml +++ b/modules/honzon-bridge/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-honzon-bridge" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/honzon/Cargo.toml b/modules/honzon/Cargo.toml index 7f5f1f6344..a20aafd29a 100644 --- a/modules/honzon/Cargo.toml +++ b/modules/honzon/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-honzon" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/honzon/src/lib.rs b/modules/honzon/src/lib.rs index 2c5c0844c3..2665d66d08 100644 --- a/modules/honzon/src/lib.rs +++ b/modules/honzon/src/lib.rs @@ -68,7 +68,6 @@ pub mod module { type DepositPerAuthorization: Get; /// The list of valid collateral currency types - #[pallet::constant] type CollateralCurrencyIds: Get>; /// Weight information for the extrinsics in this module. diff --git a/modules/idle-scheduler/Cargo.toml b/modules/idle-scheduler/Cargo.toml index c77d5c90a4..e1598a155a 100644 --- a/modules/idle-scheduler/Cargo.toml +++ b/modules/idle-scheduler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-idle-scheduler" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/incentives/Cargo.toml b/modules/incentives/Cargo.toml index f4ce5fb494..98e2ff37ea 100644 --- a/modules/incentives/Cargo.toml +++ b/modules/incentives/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-incentives" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/loans/Cargo.toml b/modules/loans/Cargo.toml index 14b6d132b9..69be3b364f 100644 --- a/modules/loans/Cargo.toml +++ b/modules/loans/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-loans" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/nft/Cargo.toml b/modules/nft/Cargo.toml index 9e2135ba17..0ff3b1ab69 100644 --- a/modules/nft/Cargo.toml +++ b/modules/nft/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-nft" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/nominees-election/Cargo.toml b/modules/nominees-election/Cargo.toml index a2d8b215c9..22bb7c0eab 100644 --- a/modules/nominees-election/Cargo.toml +++ b/modules/nominees-election/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-nominees-election" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/prices/Cargo.toml b/modules/prices/Cargo.toml index 1756e8308d..9e5fc43daa 100644 --- a/modules/prices/Cargo.toml +++ b/modules/prices/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-prices" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/relaychain/Cargo.toml b/modules/relaychain/Cargo.toml index 275cfbd553..527d8b23de 100644 --- a/modules/relaychain/Cargo.toml +++ b/modules/relaychain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-relaychain" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/session-manager/Cargo.toml b/modules/session-manager/Cargo.toml index a054ad3008..7d64f031e0 100644 --- a/modules/session-manager/Cargo.toml +++ b/modules/session-manager/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-session-manager" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/support/Cargo.toml b/modules/support/Cargo.toml index 8540acecbd..e4e5ca1a1e 100644 --- a/modules/support/Cargo.toml +++ b/modules/support/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-support" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/support/src/lib.rs b/modules/support/src/lib.rs index 17381ecea7..49dfcc761d 100644 --- a/modules/support/src/lib.rs +++ b/modules/support/src/lib.rs @@ -176,5 +176,5 @@ pub trait NomineesProvider { } pub trait BuyWeightRate { - fn calculate_rate(location: MultiLocation) -> Option; + fn calculate_rate(location: MultiLocation) -> Option; } diff --git a/modules/support/src/mocks.rs b/modules/support/src/mocks.rs index 2488cc6e4c..ddeba2afc6 100644 --- a/modules/support/src/mocks.rs +++ b/modules/support/src/mocks.rs @@ -17,7 +17,7 @@ // along with this program. If not, see . #![allow(clippy::type_complexity)] -use crate::{AddressMapping, BuyWeightRate, CurrencyId, Erc20InfoMapping, Rate, TransactionPayment}; +use crate::{AddressMapping, CurrencyId, Erc20InfoMapping, TransactionPayment}; use codec::Encode; use frame_support::pallet_prelude::{DispatchClass, Pays, Weight}; use nutsfinance_stable_asset::{ @@ -30,12 +30,11 @@ use primitives::{ }; use sp_core::{crypto::AccountId32, H160}; use sp_io::hashing::blake2_256; -use sp_runtime::{traits::One, transaction_validity::TransactionValidityError, DispatchError, DispatchResult}; +use sp_runtime::{transaction_validity::TransactionValidityError, DispatchError, DispatchResult}; use sp_std::{marker::PhantomData, vec::Vec}; #[cfg(feature = "std")] use frame_support::traits::Imbalance; -use xcm::latest::MultiLocation; pub struct MockAddressMapping; @@ -409,17 +408,3 @@ impl StableAsset unimplemented!() } } - -pub struct MockNoneMinimumBalance; -impl BuyWeightRate for MockNoneMinimumBalance { - fn calculate_rate(_: MultiLocation) -> Option { - None - } -} - -pub struct MockFixedMinimumBalance; -impl BuyWeightRate for MockFixedMinimumBalance { - fn calculate_rate(_: MultiLocation) -> Option { - Some(Rate::one()) - } -} diff --git a/modules/transaction-pause/Cargo.toml b/modules/transaction-pause/Cargo.toml index ba7cec3c57..836c890441 100644 --- a/modules/transaction-pause/Cargo.toml +++ b/modules/transaction-pause/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-transaction-pause" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/modules/transaction-payment/Cargo.toml b/modules/transaction-payment/Cargo.toml index 2d55dec865..d42e968141 100644 --- a/modules/transaction-payment/Cargo.toml +++ b/modules/transaction-payment/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-transaction-payment" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" @@ -20,8 +20,6 @@ support = { package = "module-support", path = "../support", default-features = orml-traits = { path = "../../orml/traits", default-features = false } xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.22", default-features = false } -xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.22", default-features = false } -xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.22", default-features = false } [dev-dependencies] sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.22" } @@ -48,7 +46,5 @@ std = [ "support/std", "orml-traits/std", "xcm/std", - "xcm-builder/std", - "xcm-executor/std", ] try-runtime = ["frame-support/try-runtime"] diff --git a/modules/transaction-payment/src/lib.rs b/modules/transaction-payment/src/lib.rs index 3602c3e936..c5aa08c7f9 100644 --- a/modules/transaction-payment/src/lib.rs +++ b/modules/transaction-payment/src/lib.rs @@ -36,10 +36,7 @@ use frame_support::{ WithdrawReasons, }, transactional, - weights::{ - constants::WEIGHT_PER_SECOND, DispatchInfo, GetDispatchInfo, Pays, PostDispatchInfo, WeightToFeeCoefficient, - WeightToFeePolynomial, - }, + weights::{DispatchInfo, GetDispatchInfo, Pays, PostDispatchInfo, WeightToFeeCoefficient, WeightToFeePolynomial}, BoundedVec, PalletId, }; use frame_system::pallet_prelude::*; @@ -59,10 +56,8 @@ use sp_runtime::{ FixedPointNumber, FixedPointOperand, MultiSignature, Percent, Perquintill, }; use sp_std::prelude::*; -use support::{DEXManager, PriceProvider, Ratio, SwapLimit, TransactionPayment}; -use xcm::opaque::latest::{prelude::XcmError, AssetId, Fungibility::Fungible, MultiAsset, MultiLocation}; -use xcm_builder::TakeRevenue; -use xcm_executor::{traits::WeightTrader, Assets}; +use support::{BuyWeightRate, DEXManager, PriceProvider, Ratio, SwapLimit, TransactionPayment}; +use xcm::opaque::latest::MultiLocation; mod mock; mod tests; @@ -802,8 +797,6 @@ where call: &CallOf, reason: WithdrawReasons, ) -> Result<(T::AccountId, Balance), DispatchError> { - let custom_fee_surplus = T::CustomFeeSurplus::get().mul_ceil(fee); - let custom_fee_amount = fee.saturating_add(custom_fee_surplus); match call.is_sub_type() { Some(Call::with_fee_path { fee_swap_path, .. }) => { ensure!( @@ -812,6 +805,9 @@ where && fee_swap_path.last() == Some(&T::NativeCurrencyId::get()), Error::::InvalidSwapPath ); + let fee = Self::check_native_is_not_enough(who, fee, reason).map_or_else(|| fee, |amount| amount); + let custom_fee_surplus = T::CustomFeeSurplus::get().mul_ceil(fee); + let custom_fee_amount = fee.saturating_add(custom_fee_surplus); T::DEX::swap_with_specific_path( who, fee_swap_path, @@ -824,12 +820,15 @@ where TokenExchangeRate::::contains_key(currency_id), Error::::InvalidToken ); - let fee_amount = if T::DefaultFeeTokens::get().contains(currency_id) { - fee.saturating_add(T::AlternativeFeeSurplus::get().mul_ceil(fee)) + let fee = Self::check_native_is_not_enough(who, fee, reason).map_or_else(|| fee, |amount| amount); + let alternative_fee_surplus = T::AlternativeFeeSurplus::get().mul_ceil(fee); + let custom_fee_surplus = T::CustomFeeSurplus::get().mul_ceil(fee); + let (fee_amount, fee_surplus) = if T::DefaultFeeTokens::get().contains(currency_id) { + (fee.saturating_add(alternative_fee_surplus), alternative_fee_surplus) } else { - custom_fee_amount + (fee.saturating_add(custom_fee_surplus), custom_fee_surplus) }; - Self::swap_from_pool_or_dex(who, fee_amount, *currency_id).map(|_| (who.clone(), fee_amount)) + Self::swap_from_pool_or_dex(who, fee_amount, *currency_id).map(|_| (who.clone(), fee_surplus)) } Some(Call::with_fee_paid_by { call: _, @@ -1074,94 +1073,17 @@ where } } -/// `WeightTrader` implementation used for `Trader`, the `rate` is read from storage, -/// and `token_per_second` is calculated by `rate` * `native_asset_per_second`. -pub struct TransactionFeePoolTrader, R: TakeRevenue> { - weight: Weight, - amount: u128, - asset_location: Option, - asset_per_second: u128, - _marker: PhantomData<(T, C, K, R)>, -} - -impl, R: TakeRevenue> WeightTrader for TransactionFeePoolTrader +/// Calculate the exchange rate of token in transaction fee pool. +pub struct BuyWeightRateOfTransactionFeePool(sp_std::marker::PhantomData<(T, C)>); +impl BuyWeightRate for BuyWeightRateOfTransactionFeePool where C: Convert>, { - fn new() -> Self { - Self { - weight: 0, - amount: 0, - asset_location: None, - asset_per_second: 0, - _marker: Default::default(), - } - } - - fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { - // only support first fungible assets now. - let asset_id = payment - .fungible - .iter() - .next() - .map_or(Err(XcmError::TooExpensive), |v| Ok(v.0))?; - - if let AssetId::Concrete(ref multi_location) = asset_id.clone() { - if let Some(token_id) = C::convert(multi_location.clone()) { - if let Some(rate) = TokenExchangeRate::::get(token_id) { - // calculate the amount of fungible asset. - let weight_ratio = Ratio::saturating_from_rational(weight as u128, WEIGHT_PER_SECOND as u128); - let asset_per_second = rate.saturating_mul_int(K::get()); - let amount = weight_ratio.saturating_mul_int(asset_per_second); - let required = MultiAsset { - id: asset_id.clone(), - fun: Fungible(amount), - }; - let unused = payment.checked_sub(required).map_err(|_| XcmError::TooExpensive)?; - self.weight = self.weight.saturating_add(weight); - self.amount = self.amount.saturating_add(amount); - self.asset_location = Some(multi_location.clone()); - self.asset_per_second = asset_per_second; - return Ok(unused); - } - } - } - Err(XcmError::TooExpensive) - } - - fn refund_weight(&mut self, weight: Weight) -> Option { - let weight = weight.min(self.weight); - let weight_ratio = Ratio::saturating_from_rational(weight as u128, WEIGHT_PER_SECOND as u128); - let amount = weight_ratio.saturating_mul_int(self.asset_per_second); - self.weight = self.weight.saturating_sub(weight); - self.amount = self.amount.saturating_sub(amount); - if amount > 0 && self.asset_location.is_some() { - Some( - ( - self.asset_location.as_ref().expect("checked is non-empty; qed").clone(), - amount, - ) - .into(), - ) - } else { - None - } + fn calculate_rate(multi_location: MultiLocation) -> Option { + C::convert(multi_location).and_then(TokenExchangeRate::::get) } } -impl, R: TakeRevenue> Drop for TransactionFeePoolTrader { - fn drop(&mut self) { - if self.amount > 0 && self.asset_location.is_some() { - R::take_revenue( - ( - self.asset_location.as_ref().expect("checked is non-empty; qed").clone(), - self.amount, - ) - .into(), - ); - } - } -} impl Convert> for Pallet where T: Config, diff --git a/modules/transaction-payment/src/tests.rs b/modules/transaction-payment/src/tests.rs index c206aa0893..1137a296b6 100644 --- a/modules/transaction-payment/src/tests.rs +++ b/modules/transaction-payment/src/tests.rs @@ -23,7 +23,7 @@ use super::*; use crate::mock::{AlternativeFeeSurplus, AusdFeeSwapPath, CustomFeeSurplus, DotFeeSwapPath}; use frame_support::{ - assert_noop, assert_ok, parameter_types, + assert_noop, assert_ok, weights::{DispatchClass, DispatchInfo, Pays}, }; use mock::{ @@ -39,10 +39,9 @@ use sp_runtime::{ testing::TestXt, traits::{One, UniqueSaturatedInto}, }; -use support::{Price, TransactionPayment as TransactionPaymentT}; +use support::{BuyWeightRate, Price, TransactionPayment as TransactionPaymentT}; use xcm::latest::prelude::*; use xcm::prelude::GeneralKey; -use xcm_executor::Assets; const CALL: ::Call = Call::Currencies(module_currencies::Call::transfer { dest: BOB, @@ -506,26 +505,27 @@ fn charges_fee_when_validate_with_fee_path_call() { // Enable dex with Alice, and initialize tx charge fee pool builder_with_dex_and_fee_pool(true).execute_with(|| { let dex_acc: AccountId = PalletId(*b"aca/dexm").into_account(); - let dex_ausd = Currencies::free_balance(ACA, &dex_acc); + let dex_aca = Currencies::free_balance(ACA, &dex_acc); - let fee: Balance = 50 * 2 + 100; - let fee_perc = CustomFeeSurplus::get(); - let surplus = fee_perc.mul_ceil(fee); - let fee_surplus = fee + surplus; + let fee: Balance = 50 * 2 + 100 + 10; + let fee_surplus = fee + CustomFeeSurplus::get().mul_ceil(fee); + assert_eq!(315, fee_surplus); + + assert_ok!(Currencies::update_balance(Origin::root(), BOB, AUSD, 10000)); // AUSD - ACA assert_ok!(ChargeTransactionPayment::::from(0).validate( - &ALICE, + &BOB, &with_fee_path_call(vec![AUSD, ACA]), &INFO2, 50 )); System::assert_has_event(crate::mock::Event::DEXModule(module_dex::Event::Swap { - trader: ALICE, + trader: BOB, path: vec![AUSD, ACA], - liquidity_changes: vec![31, fee_surplus], // 31 AUSD - 300 ACA + liquidity_changes: vec![33, fee_surplus], // 33 AUSD - 315 ACA })); - assert_eq!(dex_ausd - fee_surplus, Currencies::free_balance(ACA, &dex_acc)); + assert_eq!(dex_aca - fee_surplus, Currencies::free_balance(ACA, &dex_acc)); // DOT - ACA swap dex is invalid assert_noop!( @@ -539,18 +539,26 @@ fn charges_fee_when_validate_with_fee_path_call() { ); // DOT - AUSD - ACA + let fee: Balance = 50 * 2 + 100; + let fee_surplus2 = fee + CustomFeeSurplus::get().mul_ceil(fee); + assert_eq!(300, fee_surplus2); + + assert_ok!(Currencies::update_balance(Origin::root(), BOB, DOT, 10000)); assert_ok!(ChargeTransactionPayment::::from(0).validate( - &ALICE, + &BOB, &with_fee_path_call(vec![DOT, AUSD, ACA]), &INFO2, 50 )); System::assert_has_event(crate::mock::Event::DEXModule(module_dex::Event::Swap { - trader: ALICE, + trader: BOB, path: vec![DOT, AUSD, ACA], - liquidity_changes: vec![4, 33, fee_surplus], // 4 DOT - 33 AUSD - 300 ACA + liquidity_changes: vec![4, 34, fee_surplus2], // 4 DOT - 34 AUSD - 300 ACA })); - assert_eq!(dex_ausd - fee_surplus * 2, Currencies::free_balance(ACA, &dex_acc)); + assert_eq!( + dex_aca - fee_surplus - fee_surplus2, + Currencies::free_balance(ACA, &dex_acc) + ); }); } @@ -565,28 +573,48 @@ fn charges_fee_when_validate_with_fee_currency_call() { let sub_dot_aca = Currencies::free_balance(ACA, &dot_acc); let sub_dot_dot = Currencies::free_balance(DOT, &dot_acc); - let fee: Balance = 50 * 2 + 100; + let fee: Balance = 50 * 2 + 100 + 10; let fee_perc = AlternativeFeeSurplus::get(); - let surplus = fee_perc.mul_ceil(fee); - let fee_amount = fee + surplus; + let surplus = fee_perc.mul_ceil(fee); // 53 + let fee_amount = fee + surplus; // 263 + assert_ok!(Currencies::update_balance(Origin::root(), BOB, AUSD, 10000)); + assert_eq!(0, Currencies::free_balance(ACA, &BOB)); assert_ok!(ChargeTransactionPayment::::from(0).validate( - &ALICE, + &BOB, &with_fee_currency_call(AUSD), &INFO2, 50 )); + assert_eq!(10, Currencies::free_balance(ACA, &BOB)); // ED + assert_eq!(7370, Currencies::free_balance(AUSD, &BOB)); + System::assert_has_event(crate::mock::Event::Tokens(orml_tokens::Event::Transfer { + currency_id: AUSD, + from: BOB, + to: ausd_acc.clone(), + amount: 2630, + })); + System::assert_has_event(crate::mock::Event::PalletBalances(pallet_balances::Event::Transfer { + from: ausd_acc.clone(), + to: BOB, + amount: 263, + })); + assert_eq!(sub_ausd_aca - fee_amount, Currencies::free_balance(ACA, &ausd_acc)); assert_eq!( sub_ausd_usd + fee_amount * 10, Currencies::free_balance(AUSD, &ausd_acc) ); + let fee: Balance = 50 * 2 + 100; let fee_perc = CustomFeeSurplus::get(); let surplus = fee_perc.mul_ceil(fee); let fee_amount = fee + surplus; + + assert_ok!(Currencies::update_balance(Origin::root(), BOB, DOT, 10000)); + assert_eq!(10, Currencies::free_balance(ACA, &BOB)); assert_ok!(ChargeTransactionPayment::::from(0).validate( - &ALICE, + &BOB, &with_fee_currency_call(DOT), &INFO2, 50 @@ -1363,35 +1391,23 @@ impl Convert> for CurrencyIdConvert { } #[test] -fn period_rate_buy_refund_weight_works() { - parameter_types! { - pub const NativePerSecond: u128 = 8_000_000_000_000; - } +fn buy_weight_transaction_fee_pool_works() { builder_with_dex_and_fee_pool(true).execute_with(|| { - let mock_weight: Weight = 200_000_000; - let dot_rate = TokenExchangeRate::::get(DOT); - let usd_rate = TokenExchangeRate::::get(AUSD); - assert_eq!(dot_rate, Some(Ratio::saturating_from_rational(1, 10))); - assert_eq!(usd_rate, Some(Ratio::saturating_from_rational(10, 1))); - - // 1DOT=10KAR, rate=DOT/KAR=1/10, rate=0.1, amount=rate*kar_per_second*weight, - // amount=8*weight*rate=0.8*weight=160_000_000 - let asset: MultiAsset = ((0, X1(GeneralKey(DOT.encode()))), 170_000_000).into(); - let assets: Assets = asset.into(); - let mut trader = TransactionFeePoolTrader::::new(); - let unused = trader.buy_weight(mock_weight, assets); - let expect_asset: MultiAsset = ((0, X1(GeneralKey(DOT.encode()))), 10_000_000).into(); - assert_eq!(unused.unwrap(), expect_asset.into()); - assert_eq!(trader.amount, 160_000_000); - - // 1KAR=10AUSD, rate=AUSD/KAR=10, rate=10, amount=8*weight*rate=80*weight=16_000_000_000 - let asset: MultiAsset = ((0, X1(GeneralKey(AUSD.encode()))), 17_000_000_000).into(); - let assets: Assets = asset.into(); - let mut trader = TransactionFeePoolTrader::::new(); - let unused = trader.buy_weight(mock_weight, assets); - let expect_asset: MultiAsset = ((0, X1(GeneralKey(AUSD.encode()))), 1_000_000_000).into(); - assert_eq!(unused.unwrap(), expect_asset.into()); - assert_eq!(trader.amount, 16_000_000_000); + // Location convert return None. + let location = MultiLocation::new(1, X1(Junction::Parachain(2000))); + let rate = >::calculate_rate(location); + assert_eq!(rate, None); + + // Token not in charge fee pool + let currency_id = CurrencyId::Token(TokenSymbol::LDOT); + let location = MultiLocation::new(1, X1(GeneralKey(currency_id.encode()))); + let rate = >::calculate_rate(location); + assert_eq!(rate, None); + + // DOT Token is in charge fee pool. + let location = MultiLocation::parent(); + let rate = >::calculate_rate(location); + assert_eq!(rate, Some(Ratio::saturating_from_rational(1, 10))); }); } diff --git a/modules/xcm-interface/Cargo.toml b/modules/xcm-interface/Cargo.toml index d233de5e04..5a56a03aa2 100644 --- a/modules/xcm-interface/Cargo.toml +++ b/modules/xcm-interface/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "module-xcm-interface" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/node/Cargo.toml b/node/Cargo.toml index af6c27b5ac..caaa04c31e 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "acala" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" default-run = "acala" diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 370fa0863a..5fa91a5859 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "acala-cli" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/node/e2e-tests/Cargo.toml b/node/e2e-tests/Cargo.toml index 67520ad0bf..738172f64c 100644 --- a/node/e2e-tests/Cargo.toml +++ b/node/e2e-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "e2e-tests" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/node/service/Cargo.toml b/node/service/Cargo.toml index b33486090c..2ddeaf15a5 100644 --- a/node/service/Cargo.toml +++ b/node/service/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "acala-service" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 0078ce796b..9bfb09d3d3 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "acala-primitives" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/primitives/src/unchecked_extrinsic.rs b/primitives/src/unchecked_extrinsic.rs index 5fc37ed93a..a187aed108 100644 --- a/primitives/src/unchecked_extrinsic.rs +++ b/primitives/src/unchecked_extrinsic.rs @@ -37,22 +37,22 @@ use sp_runtime::{ use sp_std::{marker::PhantomData, prelude::*}; #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] -#[scale_info(skip_type_params(ConvertTx, CheckPayerTx))] +#[scale_info(skip_type_params(ConvertEthTx, CheckPayerTx))] pub struct AcalaUncheckedExtrinsic< Call, Extra: SignedExtension, - ConvertTx, + ConvertEthTx, StorageDepositPerByte, TxFeePerGas, CheckPayerTx, >( pub UncheckedExtrinsic, - PhantomData<(ConvertTx, StorageDepositPerByte, TxFeePerGas, CheckPayerTx)>, + PhantomData<(ConvertEthTx, StorageDepositPerByte, TxFeePerGas, CheckPayerTx)>, ); #[cfg(feature = "std")] -impl parity_util_mem::MallocSizeOf - for AcalaUncheckedExtrinsic +impl parity_util_mem::MallocSizeOf + for AcalaUncheckedExtrinsic where Extra: SignedExtension, { @@ -62,8 +62,8 @@ where } } -impl Extrinsic - for AcalaUncheckedExtrinsic +impl Extrinsic + for AcalaUncheckedExtrinsic { type Call = Call; @@ -85,27 +85,27 @@ impl ExtrinsicMetadata - for AcalaUncheckedExtrinsic +impl ExtrinsicMetadata + for AcalaUncheckedExtrinsic { const VERSION: u8 = UncheckedExtrinsic::::VERSION; type SignedExtensions = Extra; } -impl ExtrinsicCall - for AcalaUncheckedExtrinsic +impl ExtrinsicCall + for AcalaUncheckedExtrinsic { fn call(&self) -> &Self::Call { self.0.call() } } -impl Checkable - for AcalaUncheckedExtrinsic +impl Checkable + for AcalaUncheckedExtrinsic where Call: Encode + Member, Extra: SignedExtension, - ConvertTx: Convert<(Call, Extra), Result<(EthereumTransactionMessage, Extra), InvalidTransaction>>, + ConvertEthTx: Convert<(Call, Extra), Result<(EthereumTransactionMessage, Extra), InvalidTransaction>>, CheckPayerTx: Convert<(Call, Extra), Result<(), InvalidTransaction>>, StorageDepositPerByte: Get, TxFeePerGas: Get, @@ -122,7 +122,7 @@ where match self.0.signature { Some((addr, AcalaMultiSignature::Ethereum(sig), extra)) => { - let (eth_msg, eth_extra) = ConvertTx::convert((function.clone(), extra))?; + let (eth_msg, eth_extra) = ConvertEthTx::convert((function.clone(), extra))?; log::trace!( target: "evm", "Ethereum eth_msg: {:?}", eth_msg ); @@ -171,7 +171,7 @@ where }) } Some((addr, AcalaMultiSignature::Eip1559(sig), extra)) => { - let (eth_msg, eth_extra) = ConvertTx::convert((function.clone(), extra))?; + let (eth_msg, eth_extra) = ConvertEthTx::convert((function.clone(), extra))?; log::trace!( target: "evm", "Eip1559 eth_msg: {:?}", eth_msg ); @@ -215,7 +215,7 @@ where }) } Some((addr, AcalaMultiSignature::AcalaEip712(sig), extra)) => { - let (eth_msg, eth_extra) = ConvertTx::convert((function.clone(), extra))?; + let (eth_msg, eth_extra) = ConvertEthTx::convert((function.clone(), extra))?; log::trace!( target: "evm", "AcalaEip712 eth_msg: {:?}", eth_msg ); @@ -239,8 +239,8 @@ where } } -impl GetDispatchInfo - for AcalaUncheckedExtrinsic +impl GetDispatchInfo + for AcalaUncheckedExtrinsic where Call: GetDispatchInfo, Extra: SignedExtension, @@ -251,8 +251,9 @@ where } #[cfg(feature = "std")] -impl serde::Serialize - for AcalaUncheckedExtrinsic +impl + serde::Serialize + for AcalaUncheckedExtrinsic { fn serialize(&self, seq: S) -> Result where @@ -263,9 +264,9 @@ impl +impl<'a, Call: Decode, Extra: SignedExtension, ConvertEthTx, StorageDepositPerByte, TxFeePerGas, CheckPayerTx> serde::Deserialize<'a> - for AcalaUncheckedExtrinsic + for AcalaUncheckedExtrinsic { fn deserialize(de: D) -> Result where diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 2db5e6c15f..4c77489563 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "acala-rpc" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/runtime/acala/Cargo.toml b/runtime/acala/Cargo.toml index 4ecb596285..39b3800141 100644 --- a/runtime/acala/Cargo.toml +++ b/runtime/acala/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "acala-runtime" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" build = "build.rs" diff --git a/runtime/acala/src/lib.rs b/runtime/acala/src/lib.rs index 19f75a0e03..4a627b60e5 100644 --- a/runtime/acala/src/lib.rs +++ b/runtime/acala/src/lib.rs @@ -39,7 +39,7 @@ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{ AccountIdConversion, AccountIdLookup, BadOrigin, BlakeTwo256, Block as BlockT, Convert, SaturatedConversion, - StaticLookup, Verify, + StaticLookup, }, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, DispatchResult, FixedPointNumber, Perbill, Percent, Permill, Perquintill, @@ -50,14 +50,14 @@ use sp_version::NativeVersion; use sp_version::RuntimeVersion; use frame_system::{EnsureRoot, RawOrigin}; -use module_asset_registry::{AssetIdMaps, EvmErc20InfoMapping, FixedRateOfAssetRegistry}; +use module_asset_registry::{AssetIdMaps, EvmErc20InfoMapping}; use module_cdp_engine::CollateralCurrencyIds; use module_currencies::BasicCurrencyAdapter; use module_evm::{runner::RunnerExtended, CallInfo, CreateInfo, EvmChainId, EvmTask}; use module_evm_accounts::EvmAddressMapping; use module_relaychain::RelayChainCallBuilder; use module_support::{AssetIdMapping, DispatchableTask, PoolId}; -use module_transaction_payment::{TargetedFeeAdjustment, TransactionFeePoolTrader}; +use module_transaction_payment::TargetedFeeAdjustment; use cumulus_pallet_parachain_system::RelaychainBlockNumberProvider; use orml_traits::{ @@ -99,15 +99,15 @@ pub use primitives::{ TradingPair, }; pub use runtime_common::{ - calculate_asset_ratio, cent, dollar, microcent, millicent, AcalaDropAssets, AllPrecompiles, - EnsureRootOrAllGeneralCouncil, EnsureRootOrAllTechnicalCommittee, EnsureRootOrHalfFinancialCouncil, - EnsureRootOrHalfGeneralCouncil, EnsureRootOrHalfHomaCouncil, EnsureRootOrOneGeneralCouncil, - EnsureRootOrOneThirdsTechnicalCommittee, EnsureRootOrThreeFourthsGeneralCouncil, - EnsureRootOrTwoThirdsGeneralCouncil, EnsureRootOrTwoThirdsTechnicalCommittee, ExchangeRate, - ExistentialDepositsTimesOneHundred, FinancialCouncilInstance, FinancialCouncilMembershipInstance, GasToWeight, - GeneralCouncilInstance, GeneralCouncilMembershipInstance, HomaCouncilInstance, HomaCouncilMembershipInstance, - MaxTipsOfPriority, OffchainSolutionWeightLimit, OperationalFeeMultiplier, OperatorMembershipInstanceAcala, Price, - ProxyType, Rate, Ratio, RuntimeBlockLength, RuntimeBlockWeights, SystemContractsFilter, TechnicalCommitteeInstance, + cent, dollar, microcent, millicent, AcalaDropAssets, AllPrecompiles, EnsureRootOrAllGeneralCouncil, + EnsureRootOrAllTechnicalCommittee, EnsureRootOrHalfFinancialCouncil, EnsureRootOrHalfGeneralCouncil, + EnsureRootOrHalfHomaCouncil, EnsureRootOrOneGeneralCouncil, EnsureRootOrOneThirdsTechnicalCommittee, + EnsureRootOrThreeFourthsGeneralCouncil, EnsureRootOrTwoThirdsGeneralCouncil, + EnsureRootOrTwoThirdsTechnicalCommittee, ExchangeRate, ExistentialDepositsTimesOneHundred, + FinancialCouncilInstance, FinancialCouncilMembershipInstance, GasToWeight, GeneralCouncilInstance, + GeneralCouncilMembershipInstance, HomaCouncilInstance, HomaCouncilMembershipInstance, MaxTipsOfPriority, + OffchainSolutionWeightLimit, OperationalFeeMultiplier, OperatorMembershipInstanceAcala, Price, ProxyType, Rate, + Ratio, RuntimeBlockLength, RuntimeBlockWeights, SystemContractsFilter, TechnicalCommitteeInstance, TechnicalCommitteeMembershipInstance, TimeStampedPrice, TipPerWeightStep, ACA, AUSD, DOT, LCDOT, LDOT, RENBTC, }; pub use xcm::latest::prelude::*; @@ -125,7 +125,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("acala"), impl_name: create_runtime_str!("acala"), authoring_version: 1, - spec_version: 2064, + spec_version: 2070, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -1104,6 +1104,7 @@ impl module_aggregated_dex::Config for Runtime { type GovernanceOrigin = EnsureRootOrHalfGeneralCouncil; type DexSwapJointList = AlternativeSwapPathJointList; type SwapPathLimit = ConstU32<3>; + type RebaseTokenAmountConvertor = ConvertBalanceHoma; type WeightInfo = (); } @@ -1300,6 +1301,8 @@ impl InstanceFilter for ProxyType { c, Call::Honzon(module_honzon::Call::adjust_loan { .. }) | Call::Honzon(module_honzon::Call::close_loan_has_debit_by_dex { .. }) + | Call::Honzon(module_honzon::Call::adjust_loan_by_debit_value { .. }) + | Call::Honzon(module_honzon::Call::transfer_debit { .. }) ) } ProxyType::DexLiquidity => { @@ -1310,6 +1313,12 @@ impl InstanceFilter for ProxyType { ) } ProxyType::StableAssetLiquidity | ProxyType::StableAssetSwap => false, + ProxyType::Homa => { + matches!( + c, + Call::Homa(module_homa::Call::mint { .. }) | Call::Homa(module_homa::Call::request_redeem { .. }) + ) + } } } fn is_superset(&self, o: &Self) -> bool { @@ -2126,50 +2135,50 @@ impl Convert<(Call, SignedExtra), Result<(EthereumTransactionMessage, SignedExtr fn convert( (call, mut extra): (Call, SignedExtra), ) -> Result<(EthereumTransactionMessage, SignedExtra), InvalidTransaction> { - match call { - Call::EVM(module_evm::Call::eth_call { - action, - input, - value, - gas_limit, - storage_limit, - access_list, - valid_until, - }) => { - if System::block_number() > valid_until { - return Err(InvalidTransaction::Stale); - } - - let (_, _, _, _, mortality, check_nonce, _, charge, ..) = extra.clone(); + if let Call::EVM(module_evm::Call::eth_call { + action, + input, + value, + gas_limit, + storage_limit, + access_list, + valid_until, + }) = call + { + if System::block_number() > valid_until { + return Err(InvalidTransaction::Stale); + } - if mortality != frame_system::CheckEra::from(sp_runtime::generic::Era::Immortal) { - // require immortal - return Err(InvalidTransaction::BadProof); - } + let (_, _, _, _, mortality, check_nonce, _, charge, ..) = extra.clone(); - let nonce = check_nonce.nonce; - let tip = charge.0; - - extra.5.mark_as_ethereum_tx(valid_until); - - Ok(( - EthereumTransactionMessage { - chain_id: EVM::chain_id(), - genesis: System::block_hash(0), - nonce, - tip, - gas_limit, - storage_limit, - action, - value, - input, - valid_until, - access_list, - }, - extra, - )) + if mortality != frame_system::CheckEra::from(sp_runtime::generic::Era::Immortal) { + // require immortal + return Err(InvalidTransaction::BadProof); } - _ => Err(InvalidTransaction::BadProof), + + let nonce = check_nonce.nonce; + let tip = charge.0; + + extra.5.mark_as_ethereum_tx(valid_until); + + Ok(( + EthereumTransactionMessage { + chain_id: EVM::chain_id(), + genesis: System::block_hash(0), + nonce, + tip, + gas_limit, + storage_limit, + action, + value, + input, + valid_until, + access_list, + }, + extra, + )) + } else { + Err(InvalidTransaction::BadProof) } } } @@ -2178,23 +2187,25 @@ impl Convert<(Call, SignedExtra), Result<(EthereumTransactionMessage, SignedExtr pub struct PayerSignatureVerification; impl Convert<(Call, SignedExtra), Result<(), InvalidTransaction>> for PayerSignatureVerification { - fn convert((call, extra): (Call, SignedExtra)) -> Result<(), InvalidTransaction> { + fn convert((call, _extra): (Call, SignedExtra)) -> Result<(), InvalidTransaction> { if let Call::TransactionPayment(module_transaction_payment::Call::with_fee_paid_by { - call, - payer_addr, - payer_sig, + call: _, + payer_addr: _, + payer_sig: _, }) = call { - let payer_account: [u8; 32] = payer_addr - .encode() - .as_slice() - .try_into() - .map_err(|_| InvalidTransaction::BadSigner)?; - // payer signature is aim at inner call of `with_fee_paid_by` call. - let raw_payload = SignedPayload::new(*call, extra).map_err(|_| InvalidTransaction::BadSigner)?; - if !raw_payload.using_encoded(|payload| payer_sig.verify(payload, &payer_account.into())) { - return Err(InvalidTransaction::BadProof); - } + // Disabled for now + return Err(InvalidTransaction::BadProof); + // let payer_account: [u8; 32] = payer_addr + // .encode() + // .as_slice() + // .try_into() + // .map_err(|_| InvalidTransaction::BadSigner)?; + // // payer signature is aim at inner call of `with_fee_paid_by` call. + // let raw_payload = SignedPayload::new(*call, extra).map_err(|_| + // InvalidTransaction::BadSigner)?; if !raw_payload.using_encoded(|payload| + // payer_sig.verify(payload, &payer_account.into())) { return Err(InvalidTransaction:: + // BadProof); } } Ok(()) } diff --git a/runtime/acala/src/xcm_config.rs b/runtime/acala/src/xcm_config.rs index 074d64e341..22820f35c8 100644 --- a/runtime/acala/src/xcm_config.rs +++ b/runtime/acala/src/xcm_config.rs @@ -18,9 +18,8 @@ use super::{ constants::fee::*, AcalaTreasuryAccount, AccountId, AssetIdMapping, AssetIdMaps, Balance, Call, Convert, - Currencies, CurrencyId, Event, ExistentialDeposits, FixedRateOfAssetRegistry, GetNativeCurrencyId, - NativeTokenExistentialDeposit, Origin, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, - TransactionFeePoolTrader, UnknownTokens, XcmpQueue, ACA, AUSD, + Currencies, CurrencyId, Event, ExistentialDeposits, GetNativeCurrencyId, NativeTokenExistentialDeposit, Origin, + ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, UnknownTokens, XcmpQueue, ACA, AUSD, }; use codec::{Decode, Encode}; pub use cumulus_primitives_core::ParaId; @@ -30,12 +29,13 @@ pub use frame_support::{ weights::Weight, }; use module_asset_registry::{BuyWeightRateOfErc20, BuyWeightRateOfForeignAsset}; +use module_transaction_payment::BuyWeightRateOfTransactionFeePool; use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key, MultiCurrency}; use orml_xcm_support::{DepositToAlternative, IsNativeConcrete, MultiCurrencyAdapter, MultiNativeAsset}; use pallet_xcm::XcmPassthrough; use polkadot_parachain::primitives::Sibling; use primitives::evm::is_system_contract; -use runtime_common::{AcalaDropAssets, EnsureRootOrHalfGeneralCouncil}; +use runtime_common::{native_currency_location, AcalaDropAssets, EnsureRootOrHalfGeneralCouncil, FixedRateOfAsset}; use xcm::latest::prelude::*; pub use xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, @@ -133,17 +133,16 @@ parameter_types! { ).into(), aca_per_second() ); - pub ForeignAssetUnitsPerSecond: u128 = aca_per_second(); - pub AcaPerSecondAsBased: u128 = aca_per_second(); + pub BaseRate: u128 = aca_per_second(); } pub type Trader = ( - TransactionFeePoolTrader, + FixedRateOfAsset>, FixedRateOfFungible, FixedRateOfFungible, FixedRateOfFungible, - FixedRateOfAssetRegistry>, - FixedRateOfAssetRegistry>, + FixedRateOfAsset>, + FixedRateOfAsset>, ); pub struct XcmConfig; @@ -234,11 +233,6 @@ pub type LocalAssetTransactor = MultiCurrencyAdapter< DepositToAlternative, >; -//TODO: use token registry currency type encoding -fn native_currency_location(id: CurrencyId) -> MultiLocation { - MultiLocation::new(1, X2(Parachain(ParachainInfo::get().into()), GeneralKey(id.encode()))) -} - pub struct CurrencyIdConvert; impl Convert> for CurrencyIdConvert { fn convert(id: CurrencyId) -> Option { @@ -246,8 +240,10 @@ impl Convert> for CurrencyIdConvert { use CurrencyId::{Erc20, ForeignAsset, Token}; match id { Token(DOT) => Some(MultiLocation::parent()), - Token(ACA) | Token(AUSD) | Token(LDOT) => Some(native_currency_location(id)), - Erc20(address) if !is_system_contract(address) => Some(native_currency_location(id)), + Token(ACA) | Token(AUSD) | Token(LDOT) => Some(native_currency_location(ParachainInfo::get().into(), id)), + Erc20(address) if !is_system_contract(address) => { + Some(native_currency_location(ParachainInfo::get().into(), id)) + } ForeignAsset(foreign_asset_id) => AssetIdMaps::::get_multi_location(foreign_asset_id), _ => None, } diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index 84703ae0bb..d209805726 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runtime-common" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" @@ -12,6 +12,7 @@ required-features = ["bench"] [dependencies] hex-literal = "0.3.1" static_assertions = "1.1.0" +log = { version = "0.4.17", default-features = false } num_enum = { version = "0.5.1", default-features = false } serde = { version = "1.0.136", optional = true, default-features = false } serde_json = { version = "1.0.68", default-features = false, features = ["alloc"] } @@ -78,6 +79,7 @@ orml-rewards = { path = "../../orml/rewards", default-features = false, optional default = ["std"] std = [ "num_enum/std", + "log/std", "serde", "serde_json/std", "codec/std", diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 8a81bb0c8f..655232c131 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -22,10 +22,9 @@ #![recursion_limit = "256"] use codec::{Decode, Encode, MaxEncodedLen}; -use frame_support::traits::Get; use frame_support::{ parameter_types, - traits::{Contains, EnsureOneOf}, + traits::{Contains, EnsureOneOf, Get}, weights::{ constants::{BlockExecutionWeight, ExtrinsicBaseWeight, WEIGHT_PER_MILLIS}, DispatchClass, Weight, @@ -33,29 +32,17 @@ use frame_support::{ RuntimeDebug, }; use frame_system::{limits, EnsureRoot}; -pub use module_support::{ExchangeRate, PrecompileCallerFilter, Price, Rate, Ratio}; +use module_evm::GenesisAccount; +use orml_traits::GetByKey; use primitives::{evm::is_system_contract, Balance, CurrencyId, Nonce}; use scale_info::TypeInfo; use sp_core::{Bytes, H160}; -use sp_runtime::{traits::Convert, transaction_validity::TransactionPriority, FixedPointNumber, Perbill}; -use sp_std::collections::btree_map::BTreeMap; +use sp_runtime::{traits::Convert, transaction_validity::TransactionPriority, Perbill}; +use sp_std::{collections::btree_map::BTreeMap, marker::PhantomData, prelude::*}; use static_assertions::const_assert; -#[cfg(feature = "std")] -use sp_core::bytes::from_hex; -#[cfg(feature = "std")] -use std::str::FromStr; - -pub mod bench; -pub mod check_nonce; -pub mod precompile; - -#[cfg(test)] -mod mock; - pub use check_nonce::CheckNonce; -use module_evm::GenesisAccount; -use orml_traits::GetByKey; +pub use module_support::{ExchangeRate, PrecompileCallerFilter, Price, Rate, Ratio}; pub use precompile::{ AllPrecompiles, DEXPrecompile, EVMPrecompile, MultiCurrencyPrecompile, NFTPrecompile, OraclePrecompile, SchedulePrecompile, StableAssetPrecompile, @@ -64,12 +51,21 @@ pub use primitives::{ currency::{TokenInfo, ACA, AUSD, BNC, DOT, KAR, KBTC, KINT, KSM, KUSD, LCDOT, LDOT, LKSM, PHA, RENBTC, VSKSM}, AccountId, }; -use sp_std::{marker::PhantomData, prelude::*}; -pub use xcm::latest::prelude::*; -pub use xcm_builder::TakeRevenue; -pub use xcm_executor::{traits::DropAssets, Assets}; +pub use xcm_impl::{native_currency_location, AcalaDropAssets, FixedRateOfAsset}; + +#[cfg(feature = "std")] +use sp_core::bytes::from_hex; +#[cfg(feature = "std")] +use std::str::FromStr; + +pub mod bench; +pub mod check_nonce; +pub mod precompile; +pub mod xcm_impl; mod gas_to_weight_ratio; +#[cfg(test)] +mod mock; pub type TimeStampedPrice = orml_oracle::TimestampedValue; @@ -205,10 +201,6 @@ pub fn microcent(currency_id: CurrencyId) -> Balance { millicent(currency_id) / 1000 } -pub fn calculate_asset_ratio(foreign_asset: (AssetId, u128), native_asset: (AssetId, u128)) -> Ratio { - Ratio::saturating_from_rational(foreign_asset.1, native_asset.1) -} - pub type GeneralCouncilInstance = pallet_collective::Instance1; pub type FinancialCouncilInstance = pallet_collective::Instance2; pub type HomaCouncilInstance = pallet_collective::Instance3; @@ -339,6 +331,7 @@ pub enum ProxyType { DexLiquidity, StableAssetSwap, StableAssetLiquidity, + Homa, } impl Default for ProxyType { @@ -347,77 +340,6 @@ impl Default for ProxyType { } } -pub fn native_currency_location(para_id: u32, id: CurrencyId) -> MultiLocation { - MultiLocation::new(1, X2(Parachain(para_id), GeneralKey(id.encode()))) -} - -/// `DropAssets` implementation support asset amount lower thant ED handled by `TakeRevenue`. -/// -/// parameters type: -/// - `NC`: native currency_id type. -/// - `NB`: the ExistentialDeposit amount of native currency_id. -/// - `GK`: the ExistentialDeposit amount of tokens. -pub struct AcalaDropAssets(PhantomData<(X, T, C, NC, NB, GK)>); -impl DropAssets for AcalaDropAssets -where - X: DropAssets, - T: TakeRevenue, - C: Convert>, - NC: Get, - NB: Get, - GK: GetByKey, -{ - fn drop_assets(origin: &MultiLocation, assets: Assets) -> Weight { - let multi_assets: Vec = assets.into(); - let mut asset_traps: Vec = vec![]; - for asset in multi_assets { - if let MultiAsset { - id: Concrete(location), - fun: Fungible(amount), - } = asset.clone() - { - let currency_id = C::convert(location); - // burn asset(do nothing here) if convert result is None - if let Some(currency_id) = currency_id { - let ed = ExistentialDepositsForDropAssets::::get(¤cy_id); - if amount < ed { - T::take_revenue(asset); - } else { - asset_traps.push(asset); - } - } - } - } - if !asset_traps.is_empty() { - X::drop_assets(origin, asset_traps.into()); - } - 0 - } -} - -/// `ExistentialDeposit` for tokens, give priority to match native token, then handled by -/// `ExistentialDeposits`. -/// -/// parameters type: -/// - `NC`: native currency_id type. -/// - `NB`: the ExistentialDeposit amount of native currency_id. -/// - `GK`: the ExistentialDeposit amount of tokens. -pub struct ExistentialDepositsForDropAssets(PhantomData<(NC, NB, GK)>); -impl ExistentialDepositsForDropAssets -where - NC: Get, - NB: Get, - GK: GetByKey, -{ - fn get(currency_id: &CurrencyId) -> Balance { - if currency_id == &NC::get() { - NB::get() - } else { - GK::get(currency_id) - } - } -} - pub struct EvmLimits(PhantomData); impl EvmLimits where diff --git a/runtime/common/src/precompile/dex.rs b/runtime/common/src/precompile/dex.rs index 4f827853c3..be341e88b4 100644 --- a/runtime/common/src/precompile/dex.rs +++ b/runtime/common/src/precompile/dex.rs @@ -103,7 +103,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128_tuple(balance_a, balance_b), + output: Output::encode_uint_tuple(vec![balance_a, balance_b]), logs: Default::default(), }) } @@ -123,7 +123,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_address(&address), + output: Output::encode_address(address), logs: Default::default(), }) } @@ -149,7 +149,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(target), + output: Output::encode_uint(target), logs: Default::default(), }) } @@ -175,7 +175,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(supply), + output: Output::encode_uint(supply), logs: Default::default(), }) } @@ -207,7 +207,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(value), + output: Output::encode_uint(value), logs: Default::default(), }) } @@ -239,7 +239,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(value), + output: Output::encode_uint(value), logs: Default::default(), }) } diff --git a/runtime/common/src/precompile/evm.rs b/runtime/common/src/precompile/evm.rs index 3b300c1007..d849ff802e 100644 --- a/runtime/common/src/precompile/evm.rs +++ b/runtime/common/src/precompile/evm.rs @@ -91,7 +91,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u32(output), + output: Output::encode_uint(output), logs: Default::default(), }) } @@ -100,7 +100,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(deposit), + output: Output::encode_uint(deposit), logs: Default::default(), }) } @@ -118,7 +118,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_address(&maintainer), + output: Output::encode_address(maintainer), logs: Default::default(), }) } @@ -127,7 +127,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(deposit), + output: Output::encode_uint(deposit), logs: Default::default(), }) } @@ -136,7 +136,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(fee), + output: Output::encode_uint(fee), logs: Default::default(), }) } @@ -227,7 +227,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_bool(developer_status), + output: Output::encode_bool(developer_status), logs: Default::default(), }) } diff --git a/runtime/common/src/precompile/evm_accounts.rs b/runtime/common/src/precompile/evm_accounts.rs index 0f893764e1..b35c3940dc 100644 --- a/runtime/common/src/precompile/evm_accounts.rs +++ b/runtime/common/src/precompile/evm_accounts.rs @@ -83,7 +83,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_fixed_bytes(output.into().as_ref()), + output: Output::encode_fixed_bytes(output.into().as_ref()), logs: Default::default(), }) } @@ -101,7 +101,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_address(&address), + output: Output::encode_address(address), logs: Default::default(), }) } @@ -125,7 +125,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_address(&address), + output: Output::encode_address(address), logs: Default::default(), }) } diff --git a/runtime/common/src/precompile/homa.rs b/runtime/common/src/precompile/homa.rs index 996eae6641..89803fd2b6 100644 --- a/runtime/common/src/precompile/homa.rs +++ b/runtime/common/src/precompile/homa.rs @@ -145,7 +145,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(rate.into_inner()), + output: Output::encode_uint(rate.into_inner()), logs: Default::default(), }) } @@ -154,7 +154,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(rate.into_inner()), + output: Output::encode_uint(rate.into_inner()), logs: Default::default(), }) } @@ -164,7 +164,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(rate.into_inner()), + output: Output::encode_uint(rate.into_inner()), logs: Default::default(), }) } @@ -174,7 +174,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(rate.into_inner()), + output: Output::encode_uint(rate.into_inner()), logs: Default::default(), }) } diff --git a/runtime/common/src/precompile/honzon.rs b/runtime/common/src/precompile/honzon.rs index adc9b17f65..4745490eff 100644 --- a/runtime/common/src/precompile/honzon.rs +++ b/runtime/common/src/precompile/honzon.rs @@ -160,7 +160,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128_tuple(collateral, debit), + output: Output::encode_uint_tuple(vec![collateral, debit]), logs: Default::default(), }) } @@ -177,7 +177,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(ratio.into_inner()), + output: Output::encode_uint(ratio.into_inner()), logs: Default::default(), }) } @@ -195,7 +195,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(ratio.into_inner()), + output: Output::encode_uint(ratio.into_inner()), logs: Default::default(), }) } @@ -211,7 +211,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(exchange_rate.into_inner()), + output: Output::encode_uint(exchange_rate.into_inner()), logs: Default::default(), }) } diff --git a/runtime/common/src/precompile/input.rs b/runtime/common/src/precompile/input.rs index 916c894808..64666d238d 100644 --- a/runtime/common/src/precompile/input.rs +++ b/runtime/common/src/precompile/input.rs @@ -17,7 +17,7 @@ // along with this program. If not, see . use frame_support::ensure; -use sp_std::{marker::PhantomData, result::Result, vec, vec::Vec}; +use sp_std::{marker::PhantomData, result::Result, vec::Vec}; use crate::WeightToGas; use ethabi::Token; @@ -201,68 +201,68 @@ where } fn bool_at(&self, index: usize) -> Result { + const ONE: U256 = U256([1u64, 0, 0, 0]); let param = self.u256_at(index)?; - Ok(!param.is_zero()) + if param == ONE { + Ok(true) + } else if param.is_zero() { + Ok(false) + } else { + Err(PrecompileFailure::Revert { + exit_status: ExitRevert::Reverted, + output: "failed to decode bool".into(), + cost: self.target_gas.unwrap_or_default(), + }) + } } } -#[derive(Default, Clone, PartialEq, Debug)] pub struct Output; impl Output { - pub fn encode_bool(&self, b: bool) -> Vec { - let out = Token::Bool(b); - ethabi::encode(&[out]) + pub fn encode_bool(b: bool) -> Vec { + ethabi::encode(&[Token::Bool(b)]) } - pub fn encode_u8(&self, b: u8) -> Vec { - let out = Token::Uint(U256::from(b)); - ethabi::encode(&[out]) + pub fn encode_uint(b: T) -> Vec + where + U256: From, + { + ethabi::encode(&[Token::Uint(U256::from(b))]) } - pub fn encode_u32(&self, b: u32) -> Vec { - let out = Token::Uint(U256::from(b)); - ethabi::encode(&[out]) + pub fn encode_uint_tuple(b: Vec) -> Vec + where + U256: From, + { + ethabi::encode(&[Token::Tuple(b.into_iter().map(U256::from).map(Token::Uint).collect())]) } - pub fn encode_u128(&self, b: u128) -> Vec { - let out = Token::Uint(U256::from(b)); - ethabi::encode(&[out]) + pub fn encode_uint_array(b: Vec) -> Vec + where + U256: From, + { + ethabi::encode(&[Token::Array(b.into_iter().map(U256::from).map(Token::Uint).collect())]) } - pub fn encode_u128_tuple(&self, b: u128, c: u128) -> Vec { - let out = Token::Tuple(vec![Token::Uint(U256::from(b)), Token::Uint(U256::from(c))]); - ethabi::encode(&[out]) + pub fn encode_bytes(b: &[u8]) -> Vec { + ethabi::encode(&[Token::Bytes(b.to_vec())]) } - pub fn encode_u128_array(&self, b: Vec) -> Vec { - let result: Vec = b.iter().map(|x| Token::Uint(U256::from(*x))).collect(); - let out = Token::FixedArray(result); - ethabi::encode(&[out]) + pub fn encode_fixed_bytes(b: &[u8]) -> Vec { + ethabi::encode(&[Token::FixedBytes(b.to_vec())]) } - pub fn encode_address_array(&self, b: Vec) -> Vec { - let result: Vec = b - .iter() - .map(|x| Token::Address(H160::from_slice(x.as_bytes()))) - .collect(); - let out = Token::FixedArray(result); - ethabi::encode(&[out]) + pub fn encode_address(b: H160) -> Vec { + ethabi::encode(&[Token::Address(b)]) } - pub fn encode_bytes(&self, b: &[u8]) -> Vec { - let out = Token::Bytes(b.to_vec()); - ethabi::encode(&[out]) + pub fn encode_address_tuple(b: Vec) -> Vec { + ethabi::encode(&[Token::Tuple(b.into_iter().map(Token::Address).collect())]) } - pub fn encode_fixed_bytes(&self, b: &[u8]) -> Vec { - let out = Token::FixedBytes(b.to_vec()); - ethabi::encode(&[out]) - } - - pub fn encode_address(&self, b: &H160) -> Vec { - let out = Token::Address(H160::from_slice(b.as_bytes())); - ethabi::encode(&[out]) + pub fn encode_address_array(b: Vec) -> Vec { + ethabi::encode(&[Token::Array(b.into_iter().map(Token::Address).collect())]) } } @@ -568,6 +568,27 @@ mod tests { assert_ok!(input.i128_at(6), 0); } + #[test] + fn bool_works() { + let data = hex_literal::hex! {" + 00000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000001 + 0000000000000000000000000000000000000000000000000000000000000002 + "}; + let input = TestInput::new(&data[..], Some(10)); + assert_ok!(input.bool_at(1), false); + assert_ok!(input.bool_at(2), true); + assert_eq!( + input.bool_at(3), + Err(PrecompileFailure::Revert { + exit_status: ExitRevert::Reverted, + output: "failed to decode bool".into(), + cost: 10, + }) + ); + } + #[test] fn decode_int128() { let items = [ diff --git a/runtime/common/src/precompile/multicurrency.rs b/runtime/common/src/precompile/multicurrency.rs index f11703d1c0..2e4efbc13d 100644 --- a/runtime/common/src/precompile/multicurrency.rs +++ b/runtime/common/src/precompile/multicurrency.rs @@ -108,7 +108,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_bytes(&name), + output: Output::encode_bytes(&name), logs: Default::default(), }) } @@ -124,7 +124,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_bytes(&symbol), + output: Output::encode_bytes(&symbol), logs: Default::default(), }) } @@ -140,7 +140,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u8(decimals), + output: Output::encode_uint(decimals), logs: Default::default(), }) } @@ -152,7 +152,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(total_issuance), + output: Output::encode_uint(total_issuance), logs: Default::default(), }) } @@ -169,7 +169,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(balance), + output: Output::encode_uint(balance), logs: Default::default(), }) } diff --git a/runtime/common/src/precompile/nft.rs b/runtime/common/src/precompile/nft.rs index a885d01d17..522df54c9a 100644 --- a/runtime/common/src/precompile/nft.rs +++ b/runtime/common/src/precompile/nft.rs @@ -92,7 +92,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: 0, - output: Output::default().encode_u128(balance), + output: Output::encode_uint(balance), logs: Default::default(), }) } @@ -112,7 +112,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: 0, - output: Output::default().encode_address(&owner), + output: Output::encode_address(owner), logs: Default::default(), }) } diff --git a/runtime/common/src/precompile/oracle.rs b/runtime/common/src/precompile/oracle.rs index 656eb0d10c..6db7016fd3 100644 --- a/runtime/common/src/precompile/oracle.rs +++ b/runtime/common/src/precompile/oracle.rs @@ -105,7 +105,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(output), + output: Output::encode_uint(output), logs: Default::default(), }) } diff --git a/runtime/common/src/precompile/schedule.rs b/runtime/common/src/precompile/schedule.rs index 47e55067d0..c787207b57 100644 --- a/runtime/common/src/precompile/schedule.rs +++ b/runtime/common/src/precompile/schedule.rs @@ -228,7 +228,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: 0, - output: Output::default().encode_bytes(&task_id), + output: Output::encode_bytes(&task_id), logs: Default::default(), }) } diff --git a/runtime/common/src/precompile/stable_asset.rs b/runtime/common/src/precompile/stable_asset.rs index b40b840057..a164167384 100644 --- a/runtime/common/src/precompile/stable_asset.rs +++ b/runtime/common/src/precompile/stable_asset.rs @@ -102,7 +102,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_address_array(assets), + output: Output::encode_address_array(assets), logs: Default::default(), }) } @@ -120,7 +120,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(pool_info.total_supply), + output: Output::encode_uint(pool_info.total_supply), logs: Default::default(), }) } @@ -138,7 +138,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(pool_info.precision), + output: Output::encode_uint(pool_info.precision), logs: Default::default(), }) } @@ -156,7 +156,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(pool_info.mint_fee), + output: Output::encode_uint(pool_info.mint_fee), logs: Default::default(), }) } @@ -174,7 +174,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(pool_info.swap_fee), + output: Output::encode_uint(pool_info.swap_fee), logs: Default::default(), }) } @@ -192,7 +192,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128(pool_info.redeem_fee), + output: Output::encode_uint(pool_info.redeem_fee), logs: Default::default(), }) } @@ -222,7 +222,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u128_tuple(input, output), + output: Output::encode_uint_tuple(vec![input, output]), logs: Default::default(), }) } @@ -251,7 +251,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u8(0u8), + output: Output::encode_uint(0u8), logs: Default::default(), }) } @@ -280,7 +280,7 @@ where Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, cost: gas_cost, - output: Output::default().encode_u8(0u8), + output: Output::encode_uint(0u8), logs: Default::default(), }) } @@ -387,12 +387,10 @@ mod tests { "}; let resp = StableAssetPrecompile::execute(&input, None, &context, false).unwrap(); let expected_output = hex! {" - 000000000000000000000000 - 000000000000000000010000 - 000000000000000100000000 - 000000000000000000000000 - 000000000001000000000000 - 00000014 + 00000000000000000000000000000000 00000000000000000000000000000020 + 00000000000000000000000000000000 00000000000000000000000000000002 + 000000000000000000000000 0000000000000000000100000000000000000001 + 000000000000000000000000 0000000000000000000100000000000000000014 "}; assert_eq!(resp.exit_status, ExitSucceed::Returned); assert_eq!(resp.output, expected_output.to_vec()); diff --git a/runtime/common/src/xcm_impl.rs b/runtime/common/src/xcm_impl.rs new file mode 100644 index 0000000000..44f03b0473 --- /dev/null +++ b/runtime/common/src/xcm_impl.rs @@ -0,0 +1,264 @@ +// This file is part of Acala. + +// Copyright (C) 2020-2022 Acala Foundation. +// 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 . + +//! Common xcm implementation + +use codec::Encode; +use frame_support::{ + traits::Get, + weights::{constants::WEIGHT_PER_SECOND, Weight}, +}; +use module_support::BuyWeightRate; +use orml_traits::GetByKey; +use primitives::{Balance, CurrencyId}; +use sp_runtime::{traits::Convert, FixedPointNumber, FixedU128}; +use sp_std::{marker::PhantomData, prelude::*}; +use xcm::latest::prelude::*; +use xcm_builder::TakeRevenue; +use xcm_executor::{ + traits::{DropAssets, WeightTrader}, + Assets, +}; + +pub fn native_currency_location(para_id: u32, id: CurrencyId) -> MultiLocation { + MultiLocation::new(1, X2(Parachain(para_id), GeneralKey(id.encode()))) +} + +/// `ExistentialDeposit` for tokens, give priority to match native token, then handled by +/// `ExistentialDeposits`. +/// +/// parameters type: +/// - `NC`: native currency_id type. +/// - `NB`: the ExistentialDeposit amount of native currency_id. +/// - `GK`: the ExistentialDeposit amount of tokens. +pub struct ExistentialDepositsForDropAssets(PhantomData<(NC, NB, GK)>); +impl ExistentialDepositsForDropAssets +where + NC: Get, + NB: Get, + GK: GetByKey, +{ + fn get(currency_id: &CurrencyId) -> Balance { + if currency_id == &NC::get() { + NB::get() + } else { + GK::get(currency_id) + } + } +} + +/// `DropAssets` implementation support asset amount lower thant ED handled by `TakeRevenue`. +/// +/// parameters type: +/// - `NC`: native currency_id type. +/// - `NB`: the ExistentialDeposit amount of native currency_id. +/// - `GK`: the ExistentialDeposit amount of tokens. +pub struct AcalaDropAssets(PhantomData<(X, T, C, NC, NB, GK)>); +impl DropAssets for AcalaDropAssets +where + X: DropAssets, + T: TakeRevenue, + C: Convert>, + NC: Get, + NB: Get, + GK: GetByKey, +{ + fn drop_assets(origin: &MultiLocation, assets: Assets) -> Weight { + let multi_assets: Vec = assets.into(); + let mut asset_traps: Vec = vec![]; + for asset in multi_assets { + if let MultiAsset { + id: Concrete(location), + fun: Fungible(amount), + } = asset.clone() + { + let currency_id = C::convert(location); + // burn asset(do nothing here) if convert result is None + if let Some(currency_id) = currency_id { + let ed = ExistentialDepositsForDropAssets::::get(¤cy_id); + if amount < ed { + T::take_revenue(asset); + } else { + asset_traps.push(asset); + } + } + } + } + if !asset_traps.is_empty() { + X::drop_assets(origin, asset_traps.into()); + } + 0 + } +} + +/// Simple fee calculator that requires payment in a single fungible at a fixed rate. +/// +/// - The `FixedRate` constant should be the concrete fungible ID and the amount of it +/// required for one second of weight. +/// - The `TakeRevenue` trait is used to collecting xcm execution fee. +/// - The `BuyWeightRate` trait is used to calculate ratio by location. +pub struct FixedRateOfAsset, R: TakeRevenue, M: BuyWeightRate> { + weight: Weight, + amount: u128, + ratio: FixedU128, + multi_location: Option, + _marker: PhantomData<(FixedRate, R, M)>, +} + +impl, R: TakeRevenue, M: BuyWeightRate> WeightTrader for FixedRateOfAsset { + fn new() -> Self { + Self { + weight: 0, + amount: 0, + ratio: Default::default(), + multi_location: None, + _marker: PhantomData, + } + } + + fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { + log::trace!(target: "xcm::weight", "buy_weight weight: {:?}, payment: {:?}", weight, payment); + + // only support first fungible assets now. + let asset_id = payment + .fungible + .iter() + .next() + .map_or(Err(XcmError::TooExpensive), |v| Ok(v.0))?; + + if let AssetId::Concrete(ref multi_location) = asset_id { + log::debug!(target: "xcm::weight", "buy_weight multi_location: {:?}", multi_location); + + if let Some(ratio) = M::calculate_rate(multi_location.clone()) { + // The WEIGHT_PER_SECOND is non-zero. + let weight_ratio = FixedU128::saturating_from_rational(weight as u128, WEIGHT_PER_SECOND as u128); + let amount = ratio.saturating_mul_int(weight_ratio.saturating_mul_int(FixedRate::get())); + + let required = MultiAsset { + id: asset_id.clone(), + fun: Fungible(amount), + }; + + log::trace!( + target: "xcm::weight", "buy_weight payment: {:?}, required: {:?}, fixed_rate: {:?}, ratio: {:?}, weight_ratio: {:?}", + payment, required, FixedRate::get(), ratio, weight_ratio + ); + let unused = payment + .clone() + .checked_sub(required) + .map_err(|_| XcmError::TooExpensive)?; + self.weight = self.weight.saturating_add(weight); + self.amount = self.amount.saturating_add(amount); + self.ratio = ratio; + self.multi_location = Some(multi_location.clone()); + return Ok(unused); + } + } + + log::trace!(target: "xcm::weight", "no concrete fungible asset"); + Err(XcmError::TooExpensive) + } + + fn refund_weight(&mut self, weight: Weight) -> Option { + log::trace!( + target: "xcm::weight", "refund_weight weight: {:?}, weight: {:?}, amount: {:?}, ratio: {:?}, multi_location: {:?}", + weight, self.weight, self.amount, self.ratio, self.multi_location + ); + let weight = weight.min(self.weight); + let weight_ratio = FixedU128::saturating_from_rational(weight as u128, WEIGHT_PER_SECOND as u128); + let amount = self + .ratio + .saturating_mul_int(weight_ratio.saturating_mul_int(FixedRate::get())); + + self.weight = self.weight.saturating_sub(weight); + self.amount = self.amount.saturating_sub(amount); + + log::trace!(target: "xcm::weight", "refund_weight amount: {:?}", amount); + if amount > 0 && self.multi_location.is_some() { + Some( + ( + self.multi_location.as_ref().expect("checked is non-empty; qed").clone(), + amount, + ) + .into(), + ) + } else { + None + } + } +} + +impl, R: TakeRevenue, M: BuyWeightRate> Drop for FixedRateOfAsset { + fn drop(&mut self) { + log::trace!(target: "xcm::weight", "take revenue, weight: {:?}, amount: {:?}, multi_location: {:?}", self.weight, self.amount, self.multi_location); + if self.amount > 0 && self.multi_location.is_some() { + R::take_revenue( + ( + self.multi_location.as_ref().expect("checked is non-empty; qed").clone(), + self.amount, + ) + .into(), + ); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::mock::new_test_ext; + use frame_support::{assert_noop, assert_ok, parameter_types}; + use module_support::Ratio; + use sp_runtime::traits::One; + + pub struct MockNoneBuyWeightRate; + impl BuyWeightRate for MockNoneBuyWeightRate { + fn calculate_rate(_: MultiLocation) -> Option { + None + } + } + + pub struct MockFixedBuyWeightRate>(PhantomData); + impl> BuyWeightRate for MockFixedBuyWeightRate { + fn calculate_rate(_: MultiLocation) -> Option { + Some(T::get()) + } + } + + parameter_types! { + const FixedBasedRate: u128 = 10; + FixedRate: Ratio = Ratio::one(); + } + + #[test] + fn buy_weight_rate_mock_works() { + new_test_ext().execute_with(|| { + let asset: MultiAsset = (Parent, 100).into(); + let assets: Assets = asset.into(); + let mut trader = >::new(); + let buy_weight = trader.buy_weight(WEIGHT_PER_SECOND, assets.clone()); + assert_noop!(buy_weight, XcmError::TooExpensive); + + let mut trader = >>::new(); + let buy_weight = trader.buy_weight(WEIGHT_PER_SECOND, assets.clone()); + let asset: MultiAsset = (Parent, 90).into(); + let assets: Assets = asset.into(); + assert_ok!(buy_weight, assets.clone()); + }); + } +} diff --git a/runtime/integration-tests/Cargo.toml b/runtime/integration-tests/Cargo.toml index 308e31988b..d74780e657 100644 --- a/runtime/integration-tests/Cargo.toml +++ b/runtime/integration-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runtime-integration-tests" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" diff --git a/runtime/integration-tests/src/payment.rs b/runtime/integration-tests/src/payment.rs index da6c5054d0..6468a42829 100644 --- a/runtime/integration-tests/src/payment.rs +++ b/runtime/integration-tests/src/payment.rs @@ -257,7 +257,7 @@ fn trader_works() { let unspent: Vec = result_assets.into(); assert_eq!(vec![expect_unspent.clone()], unspent); - let mut period_trader = PeriodTrader::new(); + let mut period_trader = TransactionFeePoolTrader::new(); let result_assets = period_trader.buy_weight(xcm_weight, assets.clone()); assert!(result_assets.is_err()); }); @@ -331,7 +331,7 @@ fn trader_works() { let expect_unspent: MultiAsset = (Parent, total_balance - spent as u128).into(); // the newly `TransactionFeePoolTrader` works fine as first priority - let mut period_trader = PeriodTrader::new(); + let mut period_trader = TransactionFeePoolTrader::new(); let result_assets = period_trader.buy_weight(xcm_weight, assets); let unspent: Vec = result_assets.unwrap().into(); assert_eq!(vec![expect_unspent.clone()], unspent); diff --git a/runtime/integration-tests/src/relaychain/erc20.rs b/runtime/integration-tests/src/relaychain/erc20.rs index b05d9230ef..0b75a8b9fd 100644 --- a/runtime/integration-tests/src/relaychain/erc20.rs +++ b/runtime/integration-tests/src/relaychain/erc20.rs @@ -103,47 +103,65 @@ fn erc20_transfer_between_sibling() { )); }); + let initial_native_amount = 1_000_000_000_000u128; + let storage_fee = 6_400_000_000u128; + Karura::execute_with(|| { let alith = MockAddressMapping::get_account_id(&alice_evm_addr()); + let total_erc20 = 100_000_000_000_000_000_000_000u128; + let transfer_amount = 10 * dollar(NATIVE_CURRENCY); + + // used to deploy contracts assert_ok!(Currencies::deposit( NATIVE_CURRENCY, &alice(), 1_000_000 * dollar(NATIVE_CURRENCY) )); + // when transfer erc20 cross chain, the origin `alith` is used to charge storage assert_ok!(Currencies::deposit( NATIVE_CURRENCY, &alith.clone(), - 1_000_000 * dollar(NATIVE_CURRENCY) + initial_native_amount + )); + // when withdraw sibling parachain account, the origin `sibling_reserve_account` is used to charge + // storage + assert_ok!(Currencies::deposit( + NATIVE_CURRENCY, + &sibling_reserve_account(), + initial_native_amount + )); + // when deposit to recipient, the origin is recipient `BOB`, and is used to charge storage. + assert_ok!(Currencies::deposit( + NATIVE_CURRENCY, + &AccountId::from(BOB), + initial_native_amount + )); + // when xcm finished, deposit to treasury account, the origin is `treasury account`, and is used to + // charge storage. + assert_ok!(Currencies::deposit( + NATIVE_CURRENCY, + &KaruraTreasuryAccount::get(), + initial_native_amount )); deploy_erc20_contracts(); - // Erc20 claim account - assert_ok!(EvmAccounts::claim_account( - Origin::signed(AccountId::from(ALICE)), - EvmAccounts::eth_address(&alice_key()), - EvmAccounts::eth_sign(&alice_key(), &AccountId::from(ALICE)) - )); - + // `transfer` invoked by `TransferReserveAsset` xcm instruction need to passing origin check. + // In frontend/js, when issue xtokens extrinsic, it have `EvmSetOrigin` SignedExtra to `set_origin`. + // In testcase, we're manual invoke `set_origin` here. because in erc20 xtokens transfer, + // the `from` or `to` is not erc20 holding account. so we need make sure origin exists. >::set_origin(alith.clone()); - // use Currencies `transfer` dispatch call to transfer erc20 token to bob. - assert_ok!(Currencies::transfer( - Origin::signed(alith), - MultiAddress::Id(AccountId::from(CHARLIE)), - CurrencyId::Erc20(erc20_address_0()), - 1_000_000_000_000_000 - )); assert_eq!( - Currencies::free_balance(CurrencyId::Erc20(erc20_address_0()), &AccountId::from(CHARLIE)), - 1_000_000_000_000_000 + Currencies::free_balance(CurrencyId::Erc20(erc20_address_0()), &alith), + total_erc20 ); // transfer erc20 token to Sibling assert_ok!(XTokens::transfer( - Origin::signed(CHARLIE.into()), + Origin::signed(alith.clone()), CurrencyId::Erc20(erc20_address_0()), - 10_000_000_000_000, + transfer_amount, Box::new( MultiLocation::new( 1, @@ -160,14 +178,24 @@ fn erc20_transfer_between_sibling() { 1_000_000_000, )); + // using native token to charge storage fee assert_eq!( - 990_000_000_000_000, - Currencies::free_balance(CurrencyId::Erc20(erc20_address_0()), &AccountId::from(CHARLIE)) + initial_native_amount - storage_fee, + Currencies::free_balance(NATIVE_CURRENCY, &alith) ); assert_eq!( - 10_000_000_000_000, + total_erc20 - transfer_amount, + Currencies::free_balance(CurrencyId::Erc20(erc20_address_0()), &alith) + ); + assert_eq!( + transfer_amount, Currencies::free_balance(CurrencyId::Erc20(erc20_address_0()), &sibling_reserve_account()) ); + // initial_native_amount + ed + assert_eq!( + 1_100_000_000_000, + Currencies::free_balance(NATIVE_CURRENCY, &KaruraTreasuryAccount::get()) + ); System::reset_events(); }); @@ -213,34 +241,50 @@ fn erc20_transfer_between_sibling() { 5_000_000_000_000, Currencies::free_balance(CurrencyId::Erc20(erc20_address_0()), &sibling_reserve_account()) ); - assert_eq!( - 6_400_000_000, - Currencies::free_balance(CurrencyId::Erc20(erc20_address_0()), &KaruraTreasuryAccount::get()) - ); assert_eq!( 4_993_600_000_000, Currencies::free_balance(CurrencyId::Erc20(erc20_address_0()), &AccountId::from(BOB)) ); + assert_eq!( + 6_400_000_000, + Currencies::free_balance(CurrencyId::Erc20(erc20_address_0()), &KaruraTreasuryAccount::get()) + ); assert_eq!( 0, Currencies::free_balance(CurrencyId::Erc20(erc20_address_0()), &erc20_holding_account) ); - System::assert_has_event(Event::Currencies(module_currencies::Event::Transferred { + // withdraw erc20 need charge storage fee + assert_eq!( + initial_native_amount - storage_fee, + Currencies::free_balance(NATIVE_CURRENCY, &sibling_reserve_account()) + ); + // deposit erc20 need charge storage fee + assert_eq!( + initial_native_amount - storage_fee, + Currencies::free_balance(NATIVE_CURRENCY, &AccountId::from(BOB)) + ); + // deposit reserve and unreserve storage fee, so the native token not changed. + assert_eq!( + 1_100_000_000_000, + Currencies::free_balance(NATIVE_CURRENCY, &KaruraTreasuryAccount::get()) + ); + + // withdraw operation transfer from sibling parachain account to erc20 holding account + System::assert_has_event(Event::Currencies(module_currencies::Event::Withdrawn { currency_id: CurrencyId::Erc20(erc20_address_0()), - from: sibling_reserve_account(), - to: erc20_holding_account.clone(), + who: sibling_reserve_account(), amount: 5_000_000_000_000, })); - System::assert_has_event(Event::Currencies(module_currencies::Event::Transferred { + // deposit operation transfer from erc20 holding account to recipient + System::assert_has_event(Event::Currencies(module_currencies::Event::Deposited { currency_id: CurrencyId::Erc20(erc20_address_0()), - from: erc20_holding_account.clone(), - to: AccountId::from(BOB), + who: AccountId::from(BOB), amount: 4_993_600_000_000, })); - System::assert_has_event(Event::Currencies(module_currencies::Event::Transferred { + // TakeRevenue deposit from erc20 holding account to treasury account + System::assert_has_event(Event::Currencies(module_currencies::Event::Deposited { currency_id: CurrencyId::Erc20(erc20_address_0()), - from: erc20_holding_account, - to: KaruraTreasuryAccount::get(), + who: KaruraTreasuryAccount::get(), amount: 6_400_000_000, })); }); diff --git a/runtime/integration-tests/src/setup.rs b/runtime/integration-tests/src/setup.rs index 8ae3a0e69c..3814cb84d0 100644 --- a/runtime/integration-tests/src/setup.rs +++ b/runtime/integration-tests/src/setup.rs @@ -59,7 +59,8 @@ mod mandala_imports { Tokens, TransactionPayment, TransactionPaymentPalletId, TreasuryAccount, TreasuryPalletId, UncheckedExtrinsic, Utility, Vesting, XcmInterface, EVM, NFT, }; - pub use runtime_common::{cent, dollar, millicent, ACA, AUSD, DOT, KSM, LDOT, LKSM}; + use module_transaction_payment::BuyWeightRateOfTransactionFeePool; + pub use runtime_common::{cent, dollar, millicent, FixedRateOfAsset, ACA, AUSD, DOT, KSM, LDOT, LKSM}; pub use sp_runtime::traits::AccountIdConversion; use sp_runtime::Percent; pub use xcm_executor::XcmExecutor; @@ -74,8 +75,8 @@ mod mandala_imports { ); pub const NATIVE_TOKEN_SYMBOL: TokenSymbol = TokenSymbol::ACA; pub type Trader = FixedRateOfFungible; - pub type PeriodTrader = - module_transaction_payment::TransactionFeePoolTrader; + pub type TransactionFeePoolTrader = + FixedRateOfAsset>; pub const ALTERNATIVE_SURPLUS: Percent = AlternativeFeeSurplus::get(); } @@ -98,8 +99,9 @@ mod karura_imports { TransactionPayment, TransactionPaymentPalletId, TreasuryPalletId, Utility, Vesting, XTokens, XcmInterface, EVM, NFT, }; + use module_transaction_payment::BuyWeightRateOfTransactionFeePool; pub use primitives::TradingPair; - pub use runtime_common::{calculate_asset_ratio, cent, dollar, millicent, KAR, KSM, KUSD, LKSM}; + pub use runtime_common::{cent, dollar, millicent, FixedRateOfAsset, KAR, KSM, KUSD, LKSM}; pub use sp_runtime::traits::AccountIdConversion; use sp_runtime::Percent; pub use xcm_executor::XcmExecutor; @@ -124,8 +126,8 @@ mod karura_imports { ); pub const NATIVE_TOKEN_SYMBOL: TokenSymbol = TokenSymbol::KAR; pub type Trader = FixedRateOfFungible; - pub type PeriodTrader = - module_transaction_payment::TransactionFeePoolTrader; + pub type TransactionFeePoolTrader = + FixedRateOfAsset>; pub const ALTERNATIVE_SURPLUS: Percent = AlternativeFeeSurplus::get(); } @@ -147,8 +149,9 @@ mod acala_imports { TransactionPaymentPalletId, TreasuryPalletId, Utility, Vesting, XTokens, XcmInterface, EVM, LCDOT, NFT, }; pub use frame_support::parameter_types; + use module_transaction_payment::BuyWeightRateOfTransactionFeePool; pub use primitives::TradingPair; - pub use runtime_common::{cent, dollar, millicent, ACA, AUSD, DOT, LDOT}; + pub use runtime_common::{cent, dollar, millicent, FixedRateOfAsset, ACA, AUSD, DOT, LDOT}; pub use sp_runtime::traits::AccountIdConversion; use sp_runtime::Percent; pub use xcm_executor::XcmExecutor; @@ -175,8 +178,8 @@ mod acala_imports { ); pub const NATIVE_TOKEN_SYMBOL: TokenSymbol = TokenSymbol::ACA; pub type Trader = FixedRateOfFungible; - pub type PeriodTrader = - module_transaction_payment::TransactionFeePoolTrader; + pub type TransactionFeePoolTrader = + FixedRateOfAsset>; pub const ALTERNATIVE_SURPLUS: Percent = AlternativeFeeSurplus::get(); } diff --git a/runtime/karura/Cargo.toml b/runtime/karura/Cargo.toml index 626737c188..b907dfe21a 100644 --- a/runtime/karura/Cargo.toml +++ b/runtime/karura/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "karura-runtime" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" build = "build.rs" diff --git a/runtime/karura/src/lib.rs b/runtime/karura/src/lib.rs index 0aa6d4e1c8..91178ec040 100644 --- a/runtime/karura/src/lib.rs +++ b/runtime/karura/src/lib.rs @@ -39,7 +39,7 @@ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{ AccountIdConversion, AccountIdLookup, BadOrigin, BlakeTwo256, Block as BlockT, Convert, SaturatedConversion, - StaticLookup, Verify, + StaticLookup, }, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, DispatchResult, FixedPointNumber, Perbill, Percent, Permill, Perquintill, @@ -51,14 +51,14 @@ use sp_version::RuntimeVersion; use frame_support::pallet_prelude::InvalidTransaction; use frame_system::{EnsureRoot, RawOrigin}; -use module_asset_registry::{AssetIdMaps, EvmErc20InfoMapping, FixedRateOfAssetRegistry}; +use module_asset_registry::{AssetIdMaps, EvmErc20InfoMapping}; use module_cdp_engine::CollateralCurrencyIds; use module_currencies::BasicCurrencyAdapter; use module_evm::{runner::RunnerExtended, CallInfo, CreateInfo, EvmChainId, EvmTask}; use module_evm_accounts::EvmAddressMapping; use module_relaychain::RelayChainCallBuilder; use module_support::{AssetIdMapping, DispatchableTask, ExchangeRateProvider, PoolId}; -use module_transaction_payment::{TargetedFeeAdjustment, TransactionFeePoolTrader}; +use module_transaction_payment::TargetedFeeAdjustment; use cumulus_pallet_parachain_system::RelaychainBlockNumberProvider; use orml_traits::{ @@ -97,12 +97,12 @@ pub use primitives::{ TradingPair, }; pub use runtime_common::{ - calculate_asset_ratio, cent, dollar, microcent, millicent, AcalaDropAssets, AllPrecompiles, - EnsureRootOrAllGeneralCouncil, EnsureRootOrAllTechnicalCommittee, EnsureRootOrHalfFinancialCouncil, - EnsureRootOrHalfGeneralCouncil, EnsureRootOrHalfHomaCouncil, EnsureRootOrOneGeneralCouncil, - EnsureRootOrOneThirdsTechnicalCommittee, EnsureRootOrThreeFourthsGeneralCouncil, - EnsureRootOrTwoThirdsGeneralCouncil, EnsureRootOrTwoThirdsTechnicalCommittee, ExchangeRate, - ExistentialDepositsTimesOneHundred, FinancialCouncilInstance, FinancialCouncilMembershipInstance, GasToWeight, + cent, dollar, microcent, millicent, AcalaDropAssets, AllPrecompiles, EnsureRootOrAllGeneralCouncil, + EnsureRootOrAllTechnicalCommittee, EnsureRootOrHalfFinancialCouncil, EnsureRootOrHalfGeneralCouncil, + EnsureRootOrHalfHomaCouncil, EnsureRootOrOneGeneralCouncil, EnsureRootOrOneThirdsTechnicalCommittee, + EnsureRootOrThreeFourthsGeneralCouncil, EnsureRootOrTwoThirdsGeneralCouncil, + EnsureRootOrTwoThirdsTechnicalCommittee, ExchangeRate, ExistentialDepositsTimesOneHundred, + FinancialCouncilInstance, FinancialCouncilMembershipInstance, FixedRateOfAsset, GasToWeight, GeneralCouncilInstance, GeneralCouncilMembershipInstance, HomaCouncilInstance, HomaCouncilMembershipInstance, MaxTipsOfPriority, OperationalFeeMultiplier, OperatorMembershipInstanceAcala, Price, ProxyType, Rate, Ratio, RuntimeBlockLength, RuntimeBlockWeights, SystemContractsFilter, TechnicalCommitteeInstance, @@ -127,7 +127,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("karura"), impl_name: create_runtime_str!("karura"), authoring_version: 1, - spec_version: 2064, + spec_version: 2070, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -1117,6 +1117,7 @@ impl module_aggregated_dex::Config for Runtime { type GovernanceOrigin = EnsureRootOrHalfGeneralCouncil; type DexSwapJointList = AlternativeSwapPathJointList; type SwapPathLimit = ConstU32<3>; + type RebaseTokenAmountConvertor = ConvertBalanceHoma; type WeightInfo = (); } @@ -1312,6 +1313,8 @@ impl InstanceFilter for ProxyType { c, Call::Honzon(module_honzon::Call::adjust_loan { .. }) | Call::Honzon(module_honzon::Call::close_loan_has_debit_by_dex { .. }) + | Call::Honzon(module_honzon::Call::adjust_loan_by_debit_value { .. }) + | Call::Honzon(module_honzon::Call::transfer_debit { .. }) ) } ProxyType::DexLiquidity => { @@ -1333,6 +1336,12 @@ impl InstanceFilter for ProxyType { | Call::StableAsset(nutsfinance_stable_asset::Call::redeem_multi { .. }) ) } + ProxyType::Homa => { + matches!( + c, + Call::Homa(module_homa::Call::mint { .. }) | Call::Homa(module_homa::Call::request_redeem { .. }) + ) + } } } fn is_superset(&self, o: &Self) -> bool { @@ -2168,50 +2177,50 @@ impl Convert<(Call, SignedExtra), Result<(EthereumTransactionMessage, SignedExtr fn convert( (call, mut extra): (Call, SignedExtra), ) -> Result<(EthereumTransactionMessage, SignedExtra), InvalidTransaction> { - match call { - Call::EVM(module_evm::Call::eth_call { - action, - input, - value, - gas_limit, - storage_limit, - access_list, - valid_until, - }) => { - if System::block_number() > valid_until { - return Err(InvalidTransaction::Stale); - } - - let (_, _, _, _, mortality, check_nonce, _, charge, ..) = extra.clone(); + if let Call::EVM(module_evm::Call::eth_call { + action, + input, + value, + gas_limit, + storage_limit, + access_list, + valid_until, + }) = call + { + if System::block_number() > valid_until { + return Err(InvalidTransaction::Stale); + } - if mortality != frame_system::CheckEra::from(sp_runtime::generic::Era::Immortal) { - // require immortal - return Err(InvalidTransaction::BadProof); - } + let (_, _, _, _, mortality, check_nonce, _, charge, ..) = extra.clone(); - let nonce = check_nonce.nonce; - let tip = charge.0; - - extra.5.mark_as_ethereum_tx(valid_until); - - Ok(( - EthereumTransactionMessage { - chain_id: EVM::chain_id(), - genesis: System::block_hash(0), - nonce, - tip, - gas_limit, - storage_limit, - action, - value, - input, - valid_until, - access_list, - }, - extra, - )) + if mortality != frame_system::CheckEra::from(sp_runtime::generic::Era::Immortal) { + // require immortal + return Err(InvalidTransaction::BadProof); } - _ => Err(InvalidTransaction::BadProof), + + let nonce = check_nonce.nonce; + let tip = charge.0; + + extra.5.mark_as_ethereum_tx(valid_until); + + Ok(( + EthereumTransactionMessage { + chain_id: EVM::chain_id(), + genesis: System::block_hash(0), + nonce, + tip, + gas_limit, + storage_limit, + action, + value, + input, + valid_until, + access_list, + }, + extra, + )) + } else { + Err(InvalidTransaction::BadProof) } } } @@ -2220,23 +2229,25 @@ impl Convert<(Call, SignedExtra), Result<(EthereumTransactionMessage, SignedExtr pub struct PayerSignatureVerification; impl Convert<(Call, SignedExtra), Result<(), InvalidTransaction>> for PayerSignatureVerification { - fn convert((call, extra): (Call, SignedExtra)) -> Result<(), InvalidTransaction> { + fn convert((call, _extra): (Call, SignedExtra)) -> Result<(), InvalidTransaction> { if let Call::TransactionPayment(module_transaction_payment::Call::with_fee_paid_by { - call, - payer_addr, - payer_sig, + call: _, + payer_addr: _, + payer_sig: _, }) = call { - let payer_account: [u8; 32] = payer_addr - .encode() - .as_slice() - .try_into() - .map_err(|_| InvalidTransaction::BadSigner)?; - // payer signature is aim at inner call of `with_fee_paid_by` call. - let raw_payload = SignedPayload::new(*call, extra).map_err(|_| InvalidTransaction::BadSigner)?; - if !raw_payload.using_encoded(|payload| payer_sig.verify(payload, &payer_account.into())) { - return Err(InvalidTransaction::BadProof); - } + // Disabled for now + return Err(InvalidTransaction::BadProof); + // let payer_account: [u8; 32] = payer_addr + // .encode() + // .as_slice() + // .try_into() + // .map_err(|_| InvalidTransaction::BadSigner)?; + // // payer signature is aim at inner call of `with_fee_paid_by` call. + // let raw_payload = SignedPayload::new(*call, extra).map_err(|_| + // InvalidTransaction::BadSigner)?; if !raw_payload.using_encoded(|payload| + // payer_sig.verify(payload, &payer_account.into())) { return Err(InvalidTransaction:: + // BadProof); } } Ok(()) } diff --git a/runtime/karura/src/xcm_config.rs b/runtime/karura/src/xcm_config.rs index 3583f7e64b..64f0146a4e 100644 --- a/runtime/karura/src/xcm_config.rs +++ b/runtime/karura/src/xcm_config.rs @@ -19,9 +19,8 @@ use super::{ constants::{fee::*, parachains}, AccountId, AssetIdMapping, AssetIdMaps, Balance, Call, Convert, Currencies, CurrencyId, Event, ExistentialDeposits, - FixedRateOfAssetRegistry, GetNativeCurrencyId, KaruraTreasuryAccount, NativeTokenExistentialDeposit, Origin, - ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, TransactionFeePoolTrader, UnknownTokens, XcmInterface, - XcmpQueue, KAR, KUSD, LKSM, + FixedRateOfAsset, GetNativeCurrencyId, KaruraTreasuryAccount, NativeTokenExistentialDeposit, Origin, ParachainInfo, + ParachainSystem, PolkadotXcm, Runtime, UnknownTokens, XcmInterface, XcmpQueue, KAR, KUSD, LKSM, }; use codec::{Decode, Encode}; pub use cumulus_primitives_core::ParaId; @@ -32,6 +31,7 @@ pub use frame_support::{ }; pub use module_asset_registry::{BuyWeightRateOfErc20, BuyWeightRateOfForeignAsset}; use module_support::HomaSubAccountXcm; +use module_transaction_payment::BuyWeightRateOfTransactionFeePool; use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key, MultiCurrency}; use orml_xcm_support::{DepositToAlternative, IsNativeConcrete, MultiCurrencyAdapter, MultiNativeAsset}; use pallet_xcm::XcmPassthrough; @@ -184,12 +184,11 @@ parameter_types! { (ksm_per_second() * 4) / 3 ); - pub ForeignAssetUnitsPerSecond: u128 = kar_per_second(); - pub KarPerSecondAsBased: u128 = kar_per_second(); + pub BaseRate: u128 = kar_per_second(); } pub type Trader = ( - TransactionFeePoolTrader, + FixedRateOfAsset>, FixedRateOfFungible, FixedRateOfFungible, FixedRateOfFungible, @@ -199,8 +198,8 @@ pub type Trader = ( FixedRateOfFungible, FixedRateOfFungible, FixedRateOfFungible, - FixedRateOfAssetRegistry>, - FixedRateOfAssetRegistry>, + FixedRateOfAsset>, + FixedRateOfAsset>, ); pub struct XcmConfig; diff --git a/runtime/mandala/Cargo.toml b/runtime/mandala/Cargo.toml index 96598edc18..615d868ccd 100644 --- a/runtime/mandala/Cargo.toml +++ b/runtime/mandala/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mandala-runtime" -version = "2.6.4" +version = "2.7.0" authors = ["Acala Developers"] edition = "2021" build = "build.rs" diff --git a/runtime/mandala/src/lib.rs b/runtime/mandala/src/lib.rs index 430f9a7986..dc290c260d 100644 --- a/runtime/mandala/src/lib.rs +++ b/runtime/mandala/src/lib.rs @@ -49,14 +49,14 @@ pub use frame_support::{ }; use frame_system::{EnsureRoot, RawOrigin}; use hex_literal::hex; -use module_asset_registry::{AssetIdMaps, EvmErc20InfoMapping, FixedRateOfAssetRegistry}; +use module_asset_registry::{AssetIdMaps, EvmErc20InfoMapping}; use module_cdp_engine::CollateralCurrencyIds; use module_currencies::{BasicCurrencyAdapter, Currency}; use module_evm::{runner::RunnerExtended, CallInfo, CreateInfo, EvmChainId, EvmTask}; use module_evm_accounts::EvmAddressMapping; use module_relaychain::RelayChainCallBuilder; use module_support::{AssetIdMapping, DispatchableTask, ExchangeRateProvider, PoolId}; -use module_transaction_payment::{TargetedFeeAdjustment, TransactionFeePoolTrader}; +use module_transaction_payment::TargetedFeeAdjustment; use scale_info::TypeInfo; use orml_tokens::CurrencyAdapter; @@ -103,15 +103,15 @@ pub use primitives::{ TradingPair, }; pub use runtime_common::{ - calculate_asset_ratio, cent, dollar, microcent, millicent, AcalaDropAssets, AllPrecompiles, - EnsureRootOrAllGeneralCouncil, EnsureRootOrAllTechnicalCommittee, EnsureRootOrHalfFinancialCouncil, - EnsureRootOrHalfGeneralCouncil, EnsureRootOrHalfHomaCouncil, EnsureRootOrOneGeneralCouncil, - EnsureRootOrOneThirdsTechnicalCommittee, EnsureRootOrThreeFourthsGeneralCouncil, - EnsureRootOrTwoThirdsGeneralCouncil, EnsureRootOrTwoThirdsTechnicalCommittee, ExchangeRate, - ExistentialDepositsTimesOneHundred, FinancialCouncilInstance, FinancialCouncilMembershipInstance, GasToWeight, - GeneralCouncilInstance, GeneralCouncilMembershipInstance, HomaCouncilInstance, HomaCouncilMembershipInstance, - MaxTipsOfPriority, OffchainSolutionWeightLimit, OperationalFeeMultiplier, OperatorMembershipInstanceAcala, Price, - ProxyType, Rate, Ratio, RuntimeBlockLength, RuntimeBlockWeights, SystemContractsFilter, TechnicalCommitteeInstance, + cent, dollar, microcent, millicent, AcalaDropAssets, AllPrecompiles, EnsureRootOrAllGeneralCouncil, + EnsureRootOrAllTechnicalCommittee, EnsureRootOrHalfFinancialCouncil, EnsureRootOrHalfGeneralCouncil, + EnsureRootOrHalfHomaCouncil, EnsureRootOrOneGeneralCouncil, EnsureRootOrOneThirdsTechnicalCommittee, + EnsureRootOrThreeFourthsGeneralCouncil, EnsureRootOrTwoThirdsGeneralCouncil, + EnsureRootOrTwoThirdsTechnicalCommittee, ExchangeRate, ExistentialDepositsTimesOneHundred, + FinancialCouncilInstance, FinancialCouncilMembershipInstance, GasToWeight, GeneralCouncilInstance, + GeneralCouncilMembershipInstance, HomaCouncilInstance, HomaCouncilMembershipInstance, MaxTipsOfPriority, + OffchainSolutionWeightLimit, OperationalFeeMultiplier, OperatorMembershipInstanceAcala, Price, ProxyType, Rate, + Ratio, RuntimeBlockLength, RuntimeBlockWeights, SystemContractsFilter, TechnicalCommitteeInstance, TechnicalCommitteeMembershipInstance, TimeStampedPrice, TipPerWeightStep, ACA, AUSD, DOT, KSM, LDOT, RENBTC, }; pub use xcm::latest::prelude::*; @@ -132,7 +132,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("mandala"), impl_name: create_runtime_str!("mandala"), authoring_version: 1, - spec_version: 2064, + spec_version: 2070, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -1163,6 +1163,7 @@ impl module_aggregated_dex::Config for Runtime { type GovernanceOrigin = EnsureRootOrHalfGeneralCouncil; type DexSwapJointList = AlternativeSwapPathJointList; type SwapPathLimit = ConstU32<3>; + type RebaseTokenAmountConvertor = ConvertBalanceHoma; type WeightInfo = (); } @@ -1471,6 +1472,8 @@ impl InstanceFilter for ProxyType { c, Call::Honzon(module_honzon::Call::adjust_loan { .. }) | Call::Honzon(module_honzon::Call::close_loan_has_debit_by_dex { .. }) + | Call::Honzon(module_honzon::Call::adjust_loan_by_debit_value { .. }) + | Call::Honzon(module_honzon::Call::transfer_debit { .. }) ) } ProxyType::DexLiquidity => { @@ -1492,6 +1495,12 @@ impl InstanceFilter for ProxyType { | Call::StableAsset(nutsfinance_stable_asset::Call::redeem_multi { .. }) ) } + ProxyType::Homa => { + matches!( + c, + Call::Homa(module_homa::Call::mint { .. }) | Call::Homa(module_homa::Call::request_redeem { .. }) + ) + } } } fn is_superset(&self, o: &Self) -> bool { diff --git a/runtime/mandala/src/xcm_config.rs b/runtime/mandala/src/xcm_config.rs index cc3358f1d5..e25a307ee5 100644 --- a/runtime/mandala/src/xcm_config.rs +++ b/runtime/mandala/src/xcm_config.rs @@ -18,9 +18,8 @@ use super::{ constants::fee::*, AccountId, AssetIdMapping, AssetIdMaps, Balance, Call, Convert, Currencies, CurrencyId, Event, - ExistentialDeposits, FixedRateOfAssetRegistry, GetNativeCurrencyId, NativeTokenExistentialDeposit, Origin, - ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, TransactionFeePoolTrader, TreasuryAccount, UnknownTokens, - XcmpQueue, ACA, + ExistentialDeposits, GetNativeCurrencyId, NativeTokenExistentialDeposit, Origin, ParachainInfo, ParachainSystem, + PolkadotXcm, Runtime, TreasuryAccount, UnknownTokens, XcmpQueue, ACA, }; use codec::{Decode, Encode}; pub use cumulus_primitives_core::ParaId; @@ -30,12 +29,13 @@ pub use frame_support::{ weights::Weight, }; use module_asset_registry::{BuyWeightRateOfErc20, BuyWeightRateOfForeignAsset}; +use module_transaction_payment::BuyWeightRateOfTransactionFeePool; use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key, MultiCurrency}; use orml_xcm_support::{DepositToAlternative, IsNativeConcrete, MultiCurrencyAdapter, MultiNativeAsset}; use pallet_xcm::XcmPassthrough; use polkadot_parachain::primitives::Sibling; use primitives::evm::is_system_contract; -use runtime_common::{AcalaDropAssets, EnsureRootOrHalfGeneralCouncil}; +use runtime_common::{native_currency_location, AcalaDropAssets, EnsureRootOrHalfGeneralCouncil, FixedRateOfAsset}; use xcm::latest::prelude::*; pub use xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, @@ -125,16 +125,15 @@ parameter_types! { ).into(), aca_per_second() ); - pub ForeignAssetUnitsPerSecond: u128 = aca_per_second(); - pub AcaPerSecondAsBased: u128 = aca_per_second(); + pub BaseRate: u128 = aca_per_second(); } pub type Trader = ( - TransactionFeePoolTrader, + FixedRateOfAsset>, FixedRateOfFungible, FixedRateOfFungible, - FixedRateOfAssetRegistry>, - FixedRateOfAssetRegistry>, + FixedRateOfAsset>, + FixedRateOfAsset>, ); pub struct XcmConfig; @@ -227,11 +226,6 @@ pub type LocalAssetTransactor = MultiCurrencyAdapter< DepositToAlternative, >; -//TODO: use token registry currency type encoding -fn native_currency_location(id: CurrencyId) -> MultiLocation { - MultiLocation::new(1, X2(Parachain(ParachainInfo::get().into()), GeneralKey(id.encode()))) -} - pub struct CurrencyIdConvert; impl Convert> for CurrencyIdConvert { fn convert(id: CurrencyId) -> Option { @@ -239,8 +233,12 @@ impl Convert> for CurrencyIdConvert { use CurrencyId::{Erc20, ForeignAsset, Token}; match id { Token(DOT) => Some(MultiLocation::parent()), - Token(ACA) | Token(AUSD) | Token(LDOT) | Token(RENBTC) | Token(TAI) => Some(native_currency_location(id)), - Erc20(address) if !is_system_contract(address) => Some(native_currency_location(id)), + Token(ACA) | Token(AUSD) | Token(LDOT) | Token(RENBTC) | Token(TAI) => { + Some(native_currency_location(ParachainInfo::get().into(), id)) + } + Erc20(address) if !is_system_contract(address) => { + Some(native_currency_location(ParachainInfo::get().into(), id)) + } ForeignAsset(foreign_asset_id) => AssetIdMaps::::get_multi_location(foreign_asset_id), _ => None, }