From ba81eac13eafd51492caf08eb10d3d4ea3ed5052 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Mon, 30 Jan 2023 16:24:30 +0100 Subject: [PATCH 01/35] chore: add testnet initialization script --- package.json | 1 + scripts/init-testnet.ts | 318 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 319 insertions(+) create mode 100644 scripts/init-testnet.ts diff --git a/package.json b/package.json index 5b6af4773..8c2099f01 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "generate:meta": "ts-node node_modules/.bin/polkadot-types-from-chain --package @interlay/interbtc-api/interfaces --endpoint ./src/json/parachain.json --output ./src/interfaces", "hrmp-setup": "ts-node scripts/hrmp-setup", "runtime-upgrade": "ts-node scripts/runtime-upgrade", + "init-testnet": "ts-node scripts/init-testnet", "xcm-cross-chain-transfer": "ts-node scripts/xcm-cross-chain-transfer", "xcm-return-unknown-tokens": "ts-node scripts/xcm-return-unknown-tokens", "democracy": "ts-node scripts/democracy", diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts new file mode 100644 index 000000000..0d947f80b --- /dev/null +++ b/scripts/init-testnet.ts @@ -0,0 +1,318 @@ +/* eslint @typescript-eslint/no-var-requires: "off" */ +import { createSubstrateAPI } from "../src/factory"; +import { ApiPromise, Keyring } from "@polkadot/api"; +import { DefaultTransactionAPI } from "../src/parachain"; +import { cryptoWaitReady } from "@polkadot/util-crypto"; +import { XcmVersionedMultiLocation } from "@polkadot/types/lookup"; + +import { SubmittableExtrinsic } from "@polkadot/api/types"; +import { assert } from "console"; +import { isForeignAsset } from "../src"; +import { BN } from "bn.js"; + +const readline = require("readline"); +const yargs = require("yargs/yargs"); +const { hideBin } = require("yargs/helpers"); + +const args = yargs(hideBin(process.argv)) + .option("parachain-endpoint", { + description: "The wss url of the parachain", + type: "string", + }) + .option("with-defaults-of", { + description: "Which default values to use", + choices: ['testnet-kintsugi', 'testnet-interlay'], + }) + .argv; + +main().catch((err) => { + console.log("Error thrown by script:"); + console.log(err); +}); + +function constructLendingSetup(api: ApiPromise) { + const addMarkets = [ + api.tx.loans.addMarket( + { + Token: 'KBTC' + }, + { + collateralFactor: 630000, + liquidationThreshold: 670000, + reserveFactor: 200000, + closeFactor: 500000, + liquidateIncentive: "1100000000000000000", + liquidateIncentiveReservedFactor: 25000, + rateModel: { + Jump: { + baseRate: 0, + jumpRate: "50000000000000000", + fullRate: "500000000000000000", + jumpUtilization: 900000 + } + }, + state: "Pending", + supplyCap: "2000000000", + borrowCap: "2000000000", + lendTokenId: {LendToken: 1} + } + ), api.tx.loans.addMarket( + { + Token: 'KSM' + }, + { + collateralFactor: 540000, + liquidationThreshold: 610000, + reserveFactor: 200000, + closeFactor: 500000, + liquidateIncentive: "1100000000000000000", + liquidateIncentiveReservedFactor: 25000, + rateModel: { + Jump: { + baseRate: 0, + jumpRate: "150000000000000000", + fullRate: "400000000000000000", + jumpUtilization: 900000 + } + }, + state: "Pending", + supplyCap: "30000000000000000", + borrowCap: "30000000000000000", + lendTokenId: {LendToken: 2} + } + ), api.tx.loans.addMarket( + { + ForeignAsset: 1 // usdt + }, + { + collateralFactor: 650000, + liquidationThreshold: 690000, + reserveFactor: 200000, + closeFactor: 500000, + liquidateIncentive: "1100000000000000000", + liquidateIncentiveReservedFactor: 25000, + rateModel: { + Jump: { + baseRate: 0, + jumpRate: "100000000000000000", + fullRate: "400000000000000000", + jumpUtilization: 900000 + } + }, + state: "Pending", + supplyCap: "80000000000", + borrowCap: "80000000000", + lendTokenId: {LendToken: 3} + } + ), api.tx.loans.addMarket( + { + ForeignAsset: 2 // movr + }, + { + collateralFactor: 470000, + liquidationThreshold: 560000, + reserveFactor: 200000, + closeFactor: 500000, + liquidateIncentive: "1100000000000000000", + liquidateIncentiveReservedFactor: 25000, + rateModel: { + Jump: { + baseRate: 0, + jumpRate: "150000000000000000", + fullRate: "400000000000000000", + jumpUtilization: 900000 + } + }, + state: "Pending", + supplyCap: "20000000000000000000000", + borrowCap: "20000000000000000000000", + lendTokenId: {LendToken: 4} + } + ) + ]; + + + let activateMarkets = [ + api.tx.loans.activateMarket({Token: "KBTC"}), + api.tx.loans.activateMarket({Token: "KSM"}), + api.tx.loans.activateMarket({ForeignAsset: 1}), + api.tx.loans.activateMarket({ForeignAsset: 2}), + ]; + + return addMarkets.concat(activateMarkets); +} + +function constructFundingSetup(api: ApiPromise) { + const tokens = [{Token: "KSM"}, {Token: "KINT"}]; + const faucetSetup = tokens.map((token) => { + return api.tx.tokens.setBalance( + "5DqzGaydetDXGya818gyuHA7GAjEWRsQN6UWNKpvfgq2KyM7", + token, + 20000000000000, + 0 + ); + }); + const calls = faucetSetup.concat([ + api.tx.tokens.setBalance( + "a3cgeH7D28bBsHY4hGLzxkMFUcFQmjGgDa2kmxg3D9Z6AyhtL", // treasury + {Token: "KINT"}, + "1000000000000000000000000", //1e12 KINT + 0 + ) + ]); + return calls; +} + +function constructVaultRegistrySetup(api: ApiPromise) { + const currencyPair = { + collateral: {ForeignAsset: 3}, // lksm + wrapped: {Token: "KBTC"} + }; + return [ + api.tx.vaultRegistry.setLiquidationCollateralThreshold(currencyPair, "1450000000000000000"), + api.tx.vaultRegistry.setPremiumRedeemThreshold(currencyPair, "1650000000000000000"), + api.tx.vaultRegistry.setSecureCollateralThreshold(currencyPair, "1800000000000000000"), + api.tx.vaultRegistry.setMinimumCollateral(currencyPair.collateral, "20000000000000"), + api.tx.vaultRegistry.setSystemCollateralCeiling(currencyPair, "38000000000000000"), + ]; +} + +function constructRewardsSetup(api: ApiPromise) { + const blocksPerYears = 365 * 24 * 60 * 5; // 5 per minute + const vaultAnnuity = [ + api.tx.tokens.setBalance( + "a3cgeH7D3w3wu37yHx4VZeae4EUqNTw5RobTp5KvcMsrPLWJg", // vaultAnnuity + {Token: "KINT"}, + new BN(102803978514).muln(blocksPerYears), + 0 + ), + api.tx.vaultAnnuity.updateRewards(), + ]; + const escrowAnnuity = [ + api.tx.tokens.setBalance( + "a3cgeH7CzXoGgXh453eaSJRCvbbBKZN4mejwUVkic8efQUi5R", // escrowAnnuity + {Token: "KINT"}, + new BN(47564687975).muln(blocksPerYears), + 0 + ), + api.tx.escrowAnnuity.updateRewards(), + ]; + return vaultAnnuity.concat(escrowAnnuity); +} + +function constructAmmSetup(api: ApiPromise) { + const pools = [ + [{ Token: "KBTC" }, { Token: "KSM" }, 45_000], + [{ Token: "KBTC" }, { ForeignAsset: 1 }, 40_000], // usdt + [{ Token: "KBTC" }, { ForeignAsset: 2 }, 20_000], // movr + [{ Token: "KINT" }, { ForeignAsset: 2 }, 35_000], // movr + ]; + const basicPoolSetup = pools.map(([token1, token2, reward]) => { + return [ + api.tx.zenlinkProtocol.createPair(token1, token2), + api.tx.farming.updateRewardSchedule( + { LpToken: [token1, token2] }, + { Token: "KINT" }, + 60 * 24 * 7 * 12, // three months, reward period is per minute + new BN(10).pow(new BN(12)).muln(reward as any), + ), + ]; + }).reduce((x, y) => { return x.concat(y);}); + + return basicPoolSetup; +} + +function constructForeignAssetSetup(api: ApiPromise) { + return [ + api.tx.assetRegistry.registerAsset( + { + decimals: 6, + name: "Tether USD", + symbol: "USDT", + existentialDeposit: 0, + location: null, + additional: { feePerSecond: 8153838, coingeckoId: "" } + }, + 1 + ), api.tx.assetRegistry.registerAsset( + { + decimals: 18, + name: "Moonriver Token", + symbol: "MOVR", + existentialDeposit: 0, + location: null, + additional: { feePerSecond: 0, coingeckoId: "" } + }, + 2 + ), api.tx.assetRegistry.registerAsset( + { + decimals: 12, + name: "Liquid KSM", + symbol: "LKSM", + existentialDeposit: 0, + location: { + V1: { + parents: 1, + interior: { + X2: [ + { + Parachain: 2000 + }, + { + GeneralKey: "0x0083" + } + ] + } + } + + }, + additional: { feePerSecond: 233100000000, coingeckoId: "liquid-ksm" } + }, + 3 + ) + ]; +} + +function toUrl(extrinsic: SubmittableExtrinsic<"promise">, endpoint: string) { + return "https://polkadot.js.org/apps/?rpc=" + + encodeURIComponent(endpoint) + + "#/extrinsics/decode/" + + extrinsic.method.toHex(); +} + +async function main(): Promise { + await cryptoWaitReady(); + + switch (args['with-defaults-of']) { + case 'testnet-interlay': + if (args['parachain-endpoint'] === undefined) { + args['parachain-endpoint'] = "wss://api.interlay.io/parachain"; + } + break; + case 'testnet-kintsugi': + if (args['parachain-endpoint'] === undefined) { + args['parachain-endpoint'] = "wss://api-dev-kintsugi.interlay.io/parachain"; + } + break; + } + + const paraApi = await createSubstrateAPI(args['parachain-endpoint']); + + let calls = [ + constructFundingSetup(paraApi), + constructForeignAssetSetup(paraApi), + constructLendingSetup(paraApi), + constructVaultRegistrySetup(paraApi), + constructRewardsSetup(paraApi), + constructAmmSetup(paraApi), + ].reduce((x, y) => { return x.concat(y);}); + + const batched = paraApi.tx.utility.batchAll(calls); + const sudo = paraApi.tx.sudo.sudo(batched.method.toHex()); + + console.log(toUrl(sudo, args['parachain-endpoint'])); + + await paraApi.disconnect(); +} + + From 76eaee887add1d229317503a5bff2e8d175ef0e3 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Mon, 30 Jan 2023 17:00:00 +0100 Subject: [PATCH 02/35] refactor: init-testnet refactoring --- scripts/init-testnet.ts | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 0d947f80b..348f2f18a 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -280,22 +280,7 @@ function toUrl(extrinsic: SubmittableExtrinsic<"promise">, endpoint: string) { extrinsic.method.toHex(); } -async function main(): Promise { - await cryptoWaitReady(); - - switch (args['with-defaults-of']) { - case 'testnet-interlay': - if (args['parachain-endpoint'] === undefined) { - args['parachain-endpoint'] = "wss://api.interlay.io/parachain"; - } - break; - case 'testnet-kintsugi': - if (args['parachain-endpoint'] === undefined) { - args['parachain-endpoint'] = "wss://api-dev-kintsugi.interlay.io/parachain"; - } - break; - } - +async function setupParachain() { const paraApi = await createSubstrateAPI(args['parachain-endpoint']); let calls = [ @@ -309,10 +294,29 @@ async function main(): Promise { const batched = paraApi.tx.utility.batchAll(calls); const sudo = paraApi.tx.sudo.sudo(batched.method.toHex()); - + console.log(toUrl(sudo, args['parachain-endpoint'])); await paraApi.disconnect(); } +async function main(): Promise { + await cryptoWaitReady(); + + switch (args['with-defaults-of']) { + case 'testnet-interlay': + if (args['parachain-endpoint'] === undefined) { + args['parachain-endpoint'] = "wss://api.interlay.io/parachain"; + } + break; + case 'testnet-kintsugi': + if (args['parachain-endpoint'] === undefined) { + args['parachain-endpoint'] = "wss://api-dev-kintsugi.interlay.io/parachain"; + } + break; + } + + await setupParachain(); +} + From 2993aaaa8db7b1a57dedc901410c29951c9540c9 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Mon, 30 Jan 2023 17:20:27 +0100 Subject: [PATCH 03/35] chore(script): lending rewards --- scripts/init-testnet.ts | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 348f2f18a..219f56178 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -131,15 +131,20 @@ function constructLendingSetup(api: ApiPromise) { ) ]; - - let activateMarkets = [ - api.tx.loans.activateMarket({Token: "KBTC"}), - api.tx.loans.activateMarket({Token: "KSM"}), - api.tx.loans.activateMarket({ForeignAsset: 1}), - api.tx.loans.activateMarket({ForeignAsset: 2}), + const underlyingTokens = [ + {Token: "KBTC"}, + {Token: "KSM"}, + {ForeignAsset: 1}, // usdt + {ForeignAsset: 2}, // movr ]; - return addMarkets.concat(activateMarkets); + let addRewards = [api.tx.loans.addReward("100000000000000000000")]; + let activateMarketWithRewards = underlyingTokens.map((token) => { return [ + api.tx.loans.activateMarket(token), + api.tx.loans.updateMarketRewardSpeed(token, 10, 10), + ]}).reduce((x, y) => { return x.concat(y);}); + + return addMarkets.concat(addRewards).concat(activateMarketWithRewards); } function constructFundingSetup(api: ApiPromise) { @@ -177,7 +182,7 @@ function constructVaultRegistrySetup(api: ApiPromise) { ]; } -function constructRewardsSetup(api: ApiPromise) { +function constructAnnuitySetup(api: ApiPromise) { const blocksPerYears = 365 * 24 * 60 * 5; // 5 per minute const vaultAnnuity = [ api.tx.tokens.setBalance( @@ -288,7 +293,7 @@ async function setupParachain() { constructForeignAssetSetup(paraApi), constructLendingSetup(paraApi), constructVaultRegistrySetup(paraApi), - constructRewardsSetup(paraApi), + constructAnnuitySetup(paraApi), constructAmmSetup(paraApi), ].reduce((x, y) => { return x.concat(y);}); From 57cbd2df8b38b64733dfbae6a309a3aacf3174d8 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Mon, 30 Jan 2023 17:36:55 +0100 Subject: [PATCH 04/35] chore(script): vksm and sksm --- scripts/init-testnet.ts | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 219f56178..41bb0a468 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -274,6 +274,41 @@ function constructForeignAssetSetup(api: ApiPromise) { additional: { feePerSecond: 233100000000, coingeckoId: "liquid-ksm" } }, 3 + ), api.tx.assetRegistry.registerAsset( + { + decimals: 12, + name: "Voucher KSM", + symbol: "VKSM", + existentialDeposit: 0, + location: { + V1: { + parents: 1, + interior: { + X2: [ + { + Parachain: 2001 + }, + { + GeneralKey: "0x0104" + } + ] + } + } + + }, + additional: { feePerSecond: 233100000000, coingeckoId: "" } + }, + 4 + ), api.tx.assetRegistry.registerAsset( + { + decimals: 12, + name: "Staked KSM", + symbol: "SKSM", + existentialDeposit: 0, + location: null, + additional: { feePerSecond: 233100000000, coingeckoId: "" } + }, + 5 ) ]; } From ee85d6a02083c8b46376430a9a251d463283ecf8 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Mon, 30 Jan 2023 17:57:47 +0100 Subject: [PATCH 05/35] chore(script): basepool & metapool setup --- scripts/init-testnet.ts | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 41bb0a468..61d645de5 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -224,7 +224,40 @@ function constructAmmSetup(api: ApiPromise) { ]; }).reduce((x, y) => { return x.concat(y);}); - return basicPoolSetup; + const basePoolSetup = api.tx.zenlinkStableAmm.createBasePool( + [ + { ForeignAsset: 3 }, // LKSM + { ForeignAsset: 4 }, // VKSM + { ForeignAsset: 5 }, // SKSM + ], + [12, 12, 12], // decimals + 200, // amplification coefficient + 100_000_000, // max fee 1% + 0, // no admin fee + Buffer.concat([ + Buffer.from("modl"), // 4 bytes + Buffer.from("mod/trsy"), // 8 bytes + ], 32), // treasury + "LKSM+VKSM+SKSM" // currency symbol + ); + + const metaPoolSetup = api.tx.zenlinkStableAmm.createMetaPool( + [ + { StableLpToken: 0 }, // LKSM+VKSM+SKSM + { Token: "KSM" }, + ], + [12, 12], // decimals + 200, // amplification coefficient + 100_000_000, // max fee 1% + 0, // no admin fee + Buffer.concat([ + Buffer.from("modl"), // 4 bytes + Buffer.from("mod/trsy"), // 8 bytes + ], 32), // treasury + "(LKSM+VKSM+SKSM)+KSM" // currency symbol + ); + + return basicPoolSetup.concat([basePoolSetup, metaPoolSetup]); } function constructForeignAssetSetup(api: ApiPromise) { From cb77c96b3ff5b6ae411d82c5fc52cb8e4ce158b4 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Mon, 30 Jan 2023 18:15:23 +0100 Subject: [PATCH 06/35] chore(script): basepool & metapool rewards --- scripts/init-testnet.ts | 95 ++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 40 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 61d645de5..f92660d25 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -21,8 +21,12 @@ const args = yargs(hideBin(process.argv)) }) .option("with-defaults-of", { description: "Which default values to use", - choices: ['testnet-kintsugi', 'testnet-interlay'], + choices: ['testnet-kintsugi'], }) + // .option("clients-url", { + // description: "Url of the clients, without the client-name. E.g. https://github.com/interlay/interbtc-clients/releases/download/1.17.6/", + // demandOption: true, + // }) .argv; main().catch((err) => { @@ -205,7 +209,7 @@ function constructAnnuitySetup(api: ApiPromise) { return vaultAnnuity.concat(escrowAnnuity); } -function constructAmmSetup(api: ApiPromise) { +async function constructAmmSetup(api: ApiPromise) { const pools = [ [{ Token: "KBTC" }, { Token: "KSM" }, 45_000], [{ Token: "KBTC" }, { ForeignAsset: 1 }, 40_000], // usdt @@ -224,40 +228,56 @@ function constructAmmSetup(api: ApiPromise) { ]; }).reduce((x, y) => { return x.concat(y);}); - const basePoolSetup = api.tx.zenlinkStableAmm.createBasePool( - [ - { ForeignAsset: 3 }, // LKSM - { ForeignAsset: 4 }, // VKSM - { ForeignAsset: 5 }, // SKSM - ], - [12, 12, 12], // decimals - 200, // amplification coefficient - 100_000_000, // max fee 1% - 0, // no admin fee - Buffer.concat([ - Buffer.from("modl"), // 4 bytes - Buffer.from("mod/trsy"), // 8 bytes - ], 32), // treasury - "LKSM+VKSM+SKSM" // currency symbol - ); + const basePoolId = (await api.query.zenlinkStableAmm.nextPoolId() as any).toNumber(); // note: this is before the batch is executed - const metaPoolSetup = api.tx.zenlinkStableAmm.createMetaPool( - [ - { StableLpToken: 0 }, // LKSM+VKSM+SKSM - { Token: "KSM" }, - ], - [12, 12], // decimals - 200, // amplification coefficient - 100_000_000, // max fee 1% - 0, // no admin fee - Buffer.concat([ - Buffer.from("modl"), // 4 bytes - Buffer.from("mod/trsy"), // 8 bytes - ], 32), // treasury - "(LKSM+VKSM+SKSM)+KSM" // currency symbol - ); + const basePoolSetup = [ + api.tx.zenlinkStableAmm.createBasePool( + [ + { ForeignAsset: 3 }, // LKSM + { ForeignAsset: 4 }, // VKSM + { ForeignAsset: 5 }, // SKSM + ], + [12, 12, 12], // decimals + 200, // amplification coefficient + 100_000_000, // max fee 1% + 0, // no admin fee + Buffer.concat([ + Buffer.from("modl"), // 4 bytes + Buffer.from("mod/trsy"), // 8 bytes + ], 32), // treasury + "LKSM+VKSM+SKSM" // currency symbol + ), api.tx.farming.updateRewardSchedule( + { StableLpToken: basePoolId }, + { Token: "KINT" }, + 60 * 24 * 7 * 12, // three months, reward period is per minute + new BN(10).pow(new BN(12)).muln(15_000), + ) + ]; + + const metaPoolSetup = [ + api.tx.zenlinkStableAmm.createMetaPool( + [ + { StableLpToken: basePoolId + 1}, // LKSM+VKSM+SKSM + { Token: "KSM" }, + ], + [12, 12], // decimals + 200, // amplification coefficient + 100_000_000, // max fee 1% + 0, // no admin fee + Buffer.concat([ + Buffer.from("modl"), // 4 bytes + Buffer.from("mod/trsy"), // 8 bytes + ], 32), // treasury + "(LKSM+VKSM+SKSM)+KSM" // currency symbol + ), api.tx.farming.updateRewardSchedule( + { StableLpToken: basePoolId + 1 }, + { Token: "KINT" }, + 60 * 24 * 7 * 12, // three months, reward period is per minute + new BN(10).pow(new BN(12)).muln(33_000), + ) + ]; - return basicPoolSetup.concat([basePoolSetup, metaPoolSetup]); + return basicPoolSetup.concat(basePoolSetup).concat(metaPoolSetup); } function constructForeignAssetSetup(api: ApiPromise) { @@ -362,7 +382,7 @@ async function setupParachain() { constructLendingSetup(paraApi), constructVaultRegistrySetup(paraApi), constructAnnuitySetup(paraApi), - constructAmmSetup(paraApi), + await constructAmmSetup(paraApi), ].reduce((x, y) => { return x.concat(y);}); const batched = paraApi.tx.utility.batchAll(calls); @@ -377,11 +397,6 @@ async function main(): Promise { await cryptoWaitReady(); switch (args['with-defaults-of']) { - case 'testnet-interlay': - if (args['parachain-endpoint'] === undefined) { - args['parachain-endpoint'] = "wss://api.interlay.io/parachain"; - } - break; case 'testnet-kintsugi': if (args['parachain-endpoint'] === undefined) { args['parachain-endpoint'] = "wss://api-dev-kintsugi.interlay.io/parachain"; From d5a8caed43a12cb6791547cb1e27fdfe6fd2ab5f Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Mon, 30 Jan 2023 18:22:18 +0100 Subject: [PATCH 07/35] chore(script): fix basepool id --- scripts/init-testnet.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index f92660d25..745964c33 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -23,10 +23,10 @@ const args = yargs(hideBin(process.argv)) description: "Which default values to use", choices: ['testnet-kintsugi'], }) - // .option("clients-url", { - // description: "Url of the clients, without the client-name. E.g. https://github.com/interlay/interbtc-clients/releases/download/1.17.6/", - // demandOption: true, - // }) + .option("clients-url", { + description: "Url of the clients, without the client-name. E.g. https://github.com/interlay/interbtc-clients/releases/download/1.17.6/", + demandOption: true, + }) .argv; main().catch((err) => { @@ -257,7 +257,7 @@ async function constructAmmSetup(api: ApiPromise) { const metaPoolSetup = [ api.tx.zenlinkStableAmm.createMetaPool( [ - { StableLpToken: basePoolId + 1}, // LKSM+VKSM+SKSM + { StableLpToken: basePoolId }, // LKSM+VKSM+SKSM { Token: "KSM" }, ], [12, 12], // decimals @@ -366,6 +366,8 @@ function constructForeignAssetSetup(api: ApiPromise) { ]; } +// function constructClientsInfoSetup(api: ApiPromise) { +// } function toUrl(extrinsic: SubmittableExtrinsic<"promise">, endpoint: string) { return "https://polkadot.js.org/apps/?rpc=" + encodeURIComponent(endpoint) + From a26563a4b412271b854e8520d2135a36c44f94e0 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Mon, 30 Jan 2023 19:19:55 +0100 Subject: [PATCH 08/35] chore(script): as submitted --- scripts/init-testnet.ts | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 745964c33..cc07a8f67 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -23,10 +23,10 @@ const args = yargs(hideBin(process.argv)) description: "Which default values to use", choices: ['testnet-kintsugi'], }) - .option("clients-url", { - description: "Url of the clients, without the client-name. E.g. https://github.com/interlay/interbtc-clients/releases/download/1.17.6/", - demandOption: true, - }) + // .option("clients-url", { + // description: "Url of the clients, without the client-name. E.g. https://github.com/interlay/interbtc-clients/releases/download/1.17.6/", + // demandOption: true, + // }) .argv; main().catch((err) => { @@ -142,7 +142,12 @@ function constructLendingSetup(api: ApiPromise) { {ForeignAsset: 2}, // movr ]; - let addRewards = [api.tx.loans.addReward("100000000000000000000")]; + let addRewards = [ + api.tx.utility.dispatchAs( + { system: { Signed: "a3ckVDnZwjdBhkq1KJodZj3iCgYMseWfLA5fpqExuEpMy8Y5q" } }, // root + api.tx.loans.addReward("100000000000000000000") + ) + ]; let activateMarketWithRewards = underlyingTokens.map((token) => { return [ api.tx.loans.activateMarket(token), api.tx.loans.updateMarketRewardSpeed(token, 10, 10), @@ -210,6 +215,24 @@ function constructAnnuitySetup(api: ApiPromise) { } async function constructAmmSetup(api: ApiPromise) { + // workaround for broken is_exists check - TODO: remove once fixed. + // see https://github.com/interlay/interbtc/blob/1a1afa90228f37c9ade4acbda8275c2f5cfe85ce/parachain/runtime/testnet-kintsugi/src/zenlink.rs#L43 + const isExistsWorkaround = [ + {Token: "KBTC" }, + { ForeignAsset: 1 }, + { ForeignAsset: 2 }, + { ForeignAsset: 3 }, + { ForeignAsset: 4 }, + { ForeignAsset: 5 } + ].map((token) => { + return api.tx.tokens.setBalance( + "a3ckVDnZwjdBhkq1KJodZj3iCgYMseWfLA5fpqExuEpMy8Y5q", // root + token, + 0, + 1 + ) + }); + const pools = [ [{ Token: "KBTC" }, { Token: "KSM" }, 45_000], [{ Token: "KBTC" }, { ForeignAsset: 1 }, 40_000], // usdt @@ -257,8 +280,8 @@ async function constructAmmSetup(api: ApiPromise) { const metaPoolSetup = [ api.tx.zenlinkStableAmm.createMetaPool( [ - { StableLpToken: basePoolId }, // LKSM+VKSM+SKSM { Token: "KSM" }, + { StableLpToken: basePoolId }, // LKSM+VKSM+SKSM ], [12, 12], // decimals 200, // amplification coefficient @@ -277,7 +300,7 @@ async function constructAmmSetup(api: ApiPromise) { ) ]; - return basicPoolSetup.concat(basePoolSetup).concat(metaPoolSetup); + return isExistsWorkaround.concat(basicPoolSetup).concat(basePoolSetup);//.concat(metaPoolSetup); } function constructForeignAssetSetup(api: ApiPromise) { From 9ae7e73219c8ae60f5b49a217007f4f88bb5d394 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Tue, 31 Jan 2023 09:40:57 +0100 Subject: [PATCH 09/35] chore(script): fund faucet in foreign assets --- scripts/init-testnet.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index cc07a8f67..487a60240 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -157,12 +157,20 @@ function constructLendingSetup(api: ApiPromise) { } function constructFundingSetup(api: ApiPromise) { - const tokens = [{Token: "KSM"}, {Token: "KINT"}]; + const tokens = [ + {Token: "KSM"}, + {Token: "KINT"}, + { ForeignAsset: 1 }, + { ForeignAsset: 2 }, + { ForeignAsset: 3 }, + { ForeignAsset: 4 }, + { ForeignAsset: 5 } + ]; const faucetSetup = tokens.map((token) => { return api.tx.tokens.setBalance( "5DqzGaydetDXGya818gyuHA7GAjEWRsQN6UWNKpvfgq2KyM7", token, - 20000000000000, + "1000000000000000000000000000", //1e24 planck 0 ); }); @@ -170,7 +178,7 @@ function constructFundingSetup(api: ApiPromise) { api.tx.tokens.setBalance( "a3cgeH7D28bBsHY4hGLzxkMFUcFQmjGgDa2kmxg3D9Z6AyhtL", // treasury {Token: "KINT"}, - "1000000000000000000000000", //1e12 KINT + "1000000000000000000000000000", //1e15 KINT 0 ) ]); @@ -218,12 +226,7 @@ async function constructAmmSetup(api: ApiPromise) { // workaround for broken is_exists check - TODO: remove once fixed. // see https://github.com/interlay/interbtc/blob/1a1afa90228f37c9ade4acbda8275c2f5cfe85ce/parachain/runtime/testnet-kintsugi/src/zenlink.rs#L43 const isExistsWorkaround = [ - {Token: "KBTC" }, - { ForeignAsset: 1 }, - { ForeignAsset: 2 }, - { ForeignAsset: 3 }, - { ForeignAsset: 4 }, - { ForeignAsset: 5 } + {Token: "KBTC" }, // foreign assets also need issuance, but faucet already has those ].map((token) => { return api.tx.tokens.setBalance( "a3ckVDnZwjdBhkq1KJodZj3iCgYMseWfLA5fpqExuEpMy8Y5q", // root From d5e5b6332d8a56ad80662adc5a7efb991d07a8b9 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Tue, 31 Jan 2023 12:15:19 +0100 Subject: [PATCH 10/35] chore(script): set client versions --- scripts/init-testnet.ts | 43 +++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 487a60240..7dd41941a 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -9,6 +9,7 @@ import { SubmittableExtrinsic } from "@polkadot/api/types"; import { assert } from "console"; import { isForeignAsset } from "../src"; import { BN } from "bn.js"; +import fetch from "cross-fetch"; const readline = require("readline"); const yargs = require("yargs/yargs"); @@ -23,10 +24,10 @@ const args = yargs(hideBin(process.argv)) description: "Which default values to use", choices: ['testnet-kintsugi'], }) - // .option("clients-url", { - // description: "Url of the clients, without the client-name. E.g. https://github.com/interlay/interbtc-clients/releases/download/1.17.6/", - // demandOption: true, - // }) + .option("clients-url", { + description: "Url of the clients, without the client-name. E.g. https://github.com/interlay/interbtc-clients/releases/download/1.17.6/", + demandOption: true, + }) .argv; main().catch((err) => { @@ -392,8 +393,33 @@ function constructForeignAssetSetup(api: ApiPromise) { ]; } -// function constructClientsInfoSetup(api: ApiPromise) { -// } +async function constructClientsInfoSetup(api: ApiPromise, baseUrl: String) { + const checksumFile = await fetch(baseUrl + 'sha256sums.txt') + .then(res => { + if (res.status >= 400) { + throw new Error("Bad response from server"); + } + return res.text(); + }); + + const re = /([a-f0-9]+)\s*[.]\/(([a-z]+)-parachain-metadata-kintsugi-testnet)/g; + let matches = [] + let match; + while ((match = re.exec(checksumFile)) !== null) { + matches.push([match[1], match[2], match[3]]); + } + + return matches.map(([checksum, fullFileName, clientName]) => { + return api.tx.clientsInfo.setCurrentClientRelease( + clientName, + { + uri: baseUrl + fullFileName, + checksum: "0x" + checksum, + } + ) + }); +} + function toUrl(extrinsic: SubmittableExtrinsic<"promise">, endpoint: string) { return "https://polkadot.js.org/apps/?rpc=" + encodeURIComponent(endpoint) + @@ -405,6 +431,7 @@ async function setupParachain() { const paraApi = await createSubstrateAPI(args['parachain-endpoint']); let calls = [ + await constructClientsInfoSetup(paraApi, args["clients-url"]), constructFundingSetup(paraApi), constructForeignAssetSetup(paraApi), constructLendingSetup(paraApi), @@ -422,6 +449,10 @@ async function setupParachain() { } async function main(): Promise { + if (!args["clients-url"].endsWith("/")) { + throw new Error("clients-url needs to end with `/`, e.g. https://github.com/interlay/interbtc-clients/releases/download/1.19.2/"); + } + await cryptoWaitReady(); switch (args['with-defaults-of']) { From a3673da09a02fc7e59a6c8af07f0303479a3ae02 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Tue, 31 Jan 2023 15:34:46 +0100 Subject: [PATCH 11/35] chore: fund faucet in kbtc --- scripts/init-testnet.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 7dd41941a..35b40b289 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -161,6 +161,7 @@ function constructFundingSetup(api: ApiPromise) { const tokens = [ {Token: "KSM"}, {Token: "KINT"}, + {Token: "KBTC"}, // note: if the faucet gives this, it'll lead to unredeemable kbtc { ForeignAsset: 1 }, { ForeignAsset: 2 }, { ForeignAsset: 3 }, From 04763740f79d44e6cde11020018a4e411366debd Mon Sep 17 00:00:00 2001 From: Gregory Hill Date: Tue, 31 Jan 2023 15:25:04 +0000 Subject: [PATCH 12/35] chore: add liquidity to base and meta pools Signed-off-by: Gregory Hill --- scripts/init-testnet.ts | 217 +++++++++++++++++++++++----------------- 1 file changed, 126 insertions(+), 91 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 35b40b289..303d98135 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -15,6 +15,11 @@ const readline = require("readline"); const yargs = require("yargs/yargs"); const { hideBin } = require("yargs/helpers"); +const treasuryAccount = Buffer.concat([ + Buffer.from("modl"), // 4 bytes + Buffer.from("mod/trsy"), // 8 bytes +], 32); + const args = yargs(hideBin(process.argv)) .option("parachain-endpoint", { description: "The wss url of the parachain", @@ -41,7 +46,7 @@ function constructLendingSetup(api: ApiPromise) { { Token: 'KBTC' }, - { + { collateralFactor: 630000, liquidationThreshold: 670000, reserveFactor: 200000, @@ -59,13 +64,13 @@ function constructLendingSetup(api: ApiPromise) { state: "Pending", supplyCap: "2000000000", borrowCap: "2000000000", - lendTokenId: {LendToken: 1} + lendTokenId: { LendToken: 1 } } ), api.tx.loans.addMarket( { Token: 'KSM' }, - { + { collateralFactor: 540000, liquidationThreshold: 610000, reserveFactor: 200000, @@ -83,13 +88,13 @@ function constructLendingSetup(api: ApiPromise) { state: "Pending", supplyCap: "30000000000000000", borrowCap: "30000000000000000", - lendTokenId: {LendToken: 2} + lendTokenId: { LendToken: 2 } } ), api.tx.loans.addMarket( { ForeignAsset: 1 // usdt }, - { + { collateralFactor: 650000, liquidationThreshold: 690000, reserveFactor: 200000, @@ -107,13 +112,13 @@ function constructLendingSetup(api: ApiPromise) { state: "Pending", supplyCap: "80000000000", borrowCap: "80000000000", - lendTokenId: {LendToken: 3} + lendTokenId: { LendToken: 3 } } ), api.tx.loans.addMarket( { ForeignAsset: 2 // movr }, - { + { collateralFactor: 470000, liquidationThreshold: 560000, reserveFactor: 200000, @@ -131,73 +136,75 @@ function constructLendingSetup(api: ApiPromise) { state: "Pending", supplyCap: "20000000000000000000000", borrowCap: "20000000000000000000000", - lendTokenId: {LendToken: 4} + lendTokenId: { LendToken: 4 } } ) ]; const underlyingTokens = [ - {Token: "KBTC"}, - {Token: "KSM"}, - {ForeignAsset: 1}, // usdt - {ForeignAsset: 2}, // movr + { Token: "KBTC" }, + { Token: "KSM" }, + { ForeignAsset: 1 }, // usdt + { ForeignAsset: 2 }, // movr ]; let addRewards = [ api.tx.utility.dispatchAs( - { system: { Signed: "a3ckVDnZwjdBhkq1KJodZj3iCgYMseWfLA5fpqExuEpMy8Y5q" } }, // root + { system: { Signed: treasuryAccount } }, api.tx.loans.addReward("100000000000000000000") ) ]; - let activateMarketWithRewards = underlyingTokens.map((token) => { return [ - api.tx.loans.activateMarket(token), - api.tx.loans.updateMarketRewardSpeed(token, 10, 10), - ]}).reduce((x, y) => { return x.concat(y);}); + let activateMarketWithRewards = underlyingTokens.map((token) => { + return [ + api.tx.loans.activateMarket(token), + api.tx.loans.updateMarketRewardSpeed(token, 10, 10), + ] + }).reduce((x, y) => { return x.concat(y); }); return addMarkets.concat(addRewards).concat(activateMarketWithRewards); } function constructFundingSetup(api: ApiPromise) { const tokens = [ - {Token: "KSM"}, - {Token: "KINT"}, - {Token: "KBTC"}, // note: if the faucet gives this, it'll lead to unredeemable kbtc + { Token: "KSM" }, + { Token: "KINT" }, + { Token: "KBTC" }, // NOTE: this is unredeemable { ForeignAsset: 1 }, { ForeignAsset: 2 }, { ForeignAsset: 3 }, { ForeignAsset: 4 }, - { ForeignAsset: 5 } + { ForeignAsset: 5 } ]; - const faucetSetup = tokens.map((token) => { - return api.tx.tokens.setBalance( - "5DqzGaydetDXGya818gyuHA7GAjEWRsQN6UWNKpvfgq2KyM7", - token, - "1000000000000000000000000000", //1e24 planck - 0 - ); - }); - const calls = faucetSetup.concat([ - api.tx.tokens.setBalance( - "a3cgeH7D28bBsHY4hGLzxkMFUcFQmjGgDa2kmxg3D9Z6AyhtL", // treasury - {Token: "KINT"}, - "1000000000000000000000000000", //1e15 KINT - 0 - ) - ]); - return calls; + return tokens.map((token) => { + return [ + api.tx.tokens.setBalance( + // faucet account + "5DqzGaydetDXGya818gyuHA7GAjEWRsQN6UWNKpvfgq2KyM7", + token, + "1000000000000000000000000000", //1e24 planck + 0 + ), + api.tx.tokens.setBalance( + treasuryAccount, + token, + "1000000000000000000000000000", //1e15 KINT + 0 + ) + ] + }).flat(); } function constructVaultRegistrySetup(api: ApiPromise) { const currencyPair = { - collateral: {ForeignAsset: 3}, // lksm - wrapped: {Token: "KBTC"} + collateral: { ForeignAsset: 3 }, // lksm + wrapped: { Token: "KBTC" } }; return [ api.tx.vaultRegistry.setLiquidationCollateralThreshold(currencyPair, "1450000000000000000"), - api.tx.vaultRegistry.setPremiumRedeemThreshold(currencyPair, "1650000000000000000"), - api.tx.vaultRegistry.setSecureCollateralThreshold(currencyPair, "1800000000000000000"), - api.tx.vaultRegistry.setMinimumCollateral(currencyPair.collateral, "20000000000000"), - api.tx.vaultRegistry.setSystemCollateralCeiling(currencyPair, "38000000000000000"), + api.tx.vaultRegistry.setPremiumRedeemThreshold(currencyPair, "1650000000000000000"), + api.tx.vaultRegistry.setSecureCollateralThreshold(currencyPair, "1800000000000000000"), + api.tx.vaultRegistry.setMinimumCollateral(currencyPair.collateral, "20000000000000"), + api.tx.vaultRegistry.setSystemCollateralCeiling(currencyPair, "38000000000000000"), ]; } @@ -205,8 +212,11 @@ function constructAnnuitySetup(api: ApiPromise) { const blocksPerYears = 365 * 24 * 60 * 5; // 5 per minute const vaultAnnuity = [ api.tx.tokens.setBalance( - "a3cgeH7D3w3wu37yHx4VZeae4EUqNTw5RobTp5KvcMsrPLWJg", // vaultAnnuity - {Token: "KINT"}, + Buffer.concat([ + Buffer.from("modl"), // 4 bytes + Buffer.from("vlt/annu"), // 8 bytes + ], 32), + { Token: "KINT" }, new BN(102803978514).muln(blocksPerYears), 0 ), @@ -214,8 +224,11 @@ function constructAnnuitySetup(api: ApiPromise) { ]; const escrowAnnuity = [ api.tx.tokens.setBalance( - "a3cgeH7CzXoGgXh453eaSJRCvbbBKZN4mejwUVkic8efQUi5R", // escrowAnnuity - {Token: "KINT"}, + Buffer.concat([ + Buffer.from("modl"), // 4 bytes + Buffer.from("esc/annu"), // 8 bytes + ], 32), + { Token: "KINT" }, new BN(47564687975).muln(blocksPerYears), 0 ), @@ -227,9 +240,9 @@ function constructAnnuitySetup(api: ApiPromise) { async function constructAmmSetup(api: ApiPromise) { // workaround for broken is_exists check - TODO: remove once fixed. // see https://github.com/interlay/interbtc/blob/1a1afa90228f37c9ade4acbda8275c2f5cfe85ce/parachain/runtime/testnet-kintsugi/src/zenlink.rs#L43 - const isExistsWorkaround = [ - {Token: "KBTC" }, // foreign assets also need issuance, but faucet already has those - ].map((token) => { + const isExistsWorkaround = [ + { Token: "KBTC" }, // foreign assets also need issuance, but faucet already has those + ].map((token) => { return api.tx.tokens.setBalance( "a3ckVDnZwjdBhkq1KJodZj3iCgYMseWfLA5fpqExuEpMy8Y5q", // root token, @@ -237,7 +250,7 @@ async function constructAmmSetup(api: ApiPromise) { 1 ) }); - + const pools = [ [{ Token: "KBTC" }, { Token: "KSM" }, 45_000], [{ Token: "KBTC" }, { ForeignAsset: 1 }, 40_000], // usdt @@ -245,19 +258,19 @@ async function constructAmmSetup(api: ApiPromise) { [{ Token: "KINT" }, { ForeignAsset: 2 }, 35_000], // movr ]; const basicPoolSetup = pools.map(([token1, token2, reward]) => { - return [ - api.tx.zenlinkProtocol.createPair(token1, token2), - api.tx.farming.updateRewardSchedule( + return [ + api.tx.zenlinkProtocol.createPair(token1, token2), + api.tx.farming.updateRewardSchedule( { LpToken: [token1, token2] }, { Token: "KINT" }, 60 * 24 * 7 * 12, // three months, reward period is per minute new BN(10).pow(new BN(12)).muln(reward as any), ), - ]; - }).reduce((x, y) => { return x.concat(y);}); - - const basePoolId = (await api.query.zenlinkStableAmm.nextPoolId() as any).toNumber(); // note: this is before the batch is executed + ]; + }).reduce((x, y) => { return x.concat(y); }); + // note: this is before the batch is executed + const basePoolId = (await api.query.zenlinkStableAmm.nextPoolId() as any).toNumber(); const basePoolSetup = [ api.tx.zenlinkStableAmm.createBasePool( [ @@ -269,43 +282,67 @@ async function constructAmmSetup(api: ApiPromise) { 200, // amplification coefficient 100_000_000, // max fee 1% 0, // no admin fee - Buffer.concat([ - Buffer.from("modl"), // 4 bytes - Buffer.from("mod/trsy"), // 8 bytes - ], 32), // treasury + treasuryAccount, "LKSM+VKSM+SKSM" // currency symbol - ), api.tx.farming.updateRewardSchedule( + ), + api.tx.farming.updateRewardSchedule( { StableLpToken: basePoolId }, { Token: "KINT" }, 60 * 24 * 7 * 12, // three months, reward period is per minute new BN(10).pow(new BN(12)).muln(15_000), + ), + api.tx.utility.dispatchAs( + { system: { Signed: treasuryAccount } }, + api.tx.zenlinkStableAmm.addLiquidity( + basePoolId, + [ + 100_000, + 100_000, + 100_000, + ], + 0, // min mint amount + treasuryAccount, // recipient + new BN(4294967295), // deadline + ), ) ]; + const metaPoolId = basePoolId + 1; const metaPoolSetup = [ api.tx.zenlinkStableAmm.createMetaPool( [ { Token: "KSM" }, { StableLpToken: basePoolId }, // LKSM+VKSM+SKSM ], - [12, 12], // decimals + [12, 18], // decimals 200, // amplification coefficient 100_000_000, // max fee 1% 0, // no admin fee - Buffer.concat([ - Buffer.from("modl"), // 4 bytes - Buffer.from("mod/trsy"), // 8 bytes - ], 32), // treasury - "(LKSM+VKSM+SKSM)+KSM" // currency symbol - ), api.tx.farming.updateRewardSchedule( - { StableLpToken: basePoolId + 1 }, + treasuryAccount, + "KSM+(LKSM+VKSM+SKSM)" // currency symbol + ), + api.tx.farming.updateRewardSchedule( + { StableLpToken: metaPoolId }, { Token: "KINT" }, 60 * 24 * 7 * 12, // three months, reward period is per minute new BN(10).pow(new BN(12)).muln(33_000), + ), + api.tx.utility.dispatchAs( + { system: { Signed: treasuryAccount } }, + api.tx.zenlinkStableAmm.addLiquidity( + metaPoolId, + [ + 100_000, + 100_000, + ], + 0, // min mint amount + treasuryAccount, // recipient + new BN(4294967295), // deadline + ), ) ]; - return isExistsWorkaround.concat(basicPoolSetup).concat(basePoolSetup);//.concat(metaPoolSetup); + return isExistsWorkaround.concat(basicPoolSetup).concat(basePoolSetup).concat(metaPoolSetup); } function constructForeignAssetSetup(api: ApiPromise) { @@ -314,7 +351,7 @@ function constructForeignAssetSetup(api: ApiPromise) { { decimals: 6, name: "Tether USD", - symbol: "USDT", + symbol: "USDT", existentialDeposit: 0, location: null, additional: { feePerSecond: 8153838, coingeckoId: "" } @@ -324,7 +361,7 @@ function constructForeignAssetSetup(api: ApiPromise) { { decimals: 18, name: "Moonriver Token", - symbol: "MOVR", + symbol: "MOVR", existentialDeposit: 0, location: null, additional: { feePerSecond: 0, coingeckoId: "" } @@ -334,7 +371,7 @@ function constructForeignAssetSetup(api: ApiPromise) { { decimals: 12, name: "Liquid KSM", - symbol: "LKSM", + symbol: "LKSM", existentialDeposit: 0, location: { V1: { @@ -350,16 +387,15 @@ function constructForeignAssetSetup(api: ApiPromise) { ] } } - }, additional: { feePerSecond: 233100000000, coingeckoId: "liquid-ksm" } }, - 3 + 3 ), api.tx.assetRegistry.registerAsset( { decimals: 12, name: "Voucher KSM", - symbol: "VKSM", + symbol: "VKSM", existentialDeposit: 0, location: { V1: { @@ -375,33 +411,32 @@ function constructForeignAssetSetup(api: ApiPromise) { ] } } - }, additional: { feePerSecond: 233100000000, coingeckoId: "" } }, - 4 + 4 ), api.tx.assetRegistry.registerAsset( { decimals: 12, name: "Staked KSM", - symbol: "SKSM", + symbol: "SKSM", existentialDeposit: 0, location: null, additional: { feePerSecond: 233100000000, coingeckoId: "" } }, - 5 + 5 ) ]; } async function constructClientsInfoSetup(api: ApiPromise, baseUrl: String) { const checksumFile = await fetch(baseUrl + 'sha256sums.txt') - .then(res => { - if (res.status >= 400) { - throw new Error("Bad response from server"); - } - return res.text(); - }); + .then(res => { + if (res.status >= 400) { + throw new Error("Bad response from server"); + } + return res.text(); + }); const re = /([a-f0-9]+)\s*[.]\/(([a-z]+)-parachain-metadata-kintsugi-testnet)/g; let matches = [] @@ -433,13 +468,13 @@ async function setupParachain() { let calls = [ await constructClientsInfoSetup(paraApi, args["clients-url"]), - constructFundingSetup(paraApi), constructForeignAssetSetup(paraApi), + constructFundingSetup(paraApi), constructLendingSetup(paraApi), constructVaultRegistrySetup(paraApi), constructAnnuitySetup(paraApi), await constructAmmSetup(paraApi), - ].reduce((x, y) => { return x.concat(y);}); + ].reduce((x, y) => { return x.concat(y); }); const batched = paraApi.tx.utility.batchAll(calls); const sudo = paraApi.tx.sudo.sudo(batched.method.toHex()); From fd6521df2a0c7e4e5746ad01081c9e15c80d31c4 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Tue, 31 Jan 2023 16:59:44 +0100 Subject: [PATCH 13/35] fix: usdt and moonriver coingecko ids --- scripts/init-testnet.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 303d98135..e91ec447f 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -354,7 +354,7 @@ function constructForeignAssetSetup(api: ApiPromise) { symbol: "USDT", existentialDeposit: 0, location: null, - additional: { feePerSecond: 8153838, coingeckoId: "" } + additional: { feePerSecond: 8153838, coingeckoId: "tether" } }, 1 ), api.tx.assetRegistry.registerAsset( @@ -364,7 +364,7 @@ function constructForeignAssetSetup(api: ApiPromise) { symbol: "MOVR", existentialDeposit: 0, location: null, - additional: { feePerSecond: 0, coingeckoId: "" } + additional: { feePerSecond: 0, coingeckoId: "moonriver" } }, 2 ), api.tx.assetRegistry.registerAsset( @@ -412,7 +412,7 @@ function constructForeignAssetSetup(api: ApiPromise) { } } }, - additional: { feePerSecond: 233100000000, coingeckoId: "" } + additional: { feePerSecond: 233100000000, coingeckoId: "voucher-ksm" } }, 4 ), api.tx.assetRegistry.registerAsset( From 6c18c49eb112ba18777fdafa52fecaff7dfffbf7 Mon Sep 17 00:00:00 2001 From: Gregory Hill Date: Thu, 2 Feb 2023 14:21:42 +0000 Subject: [PATCH 14/35] chore: add liquidity to uniswap pools Signed-off-by: Gregory Hill --- scripts/init-testnet.ts | 80 +++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 22 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index e91ec447f..18aac0500 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -144,8 +144,8 @@ function constructLendingSetup(api: ApiPromise) { const underlyingTokens = [ { Token: "KBTC" }, { Token: "KSM" }, - { ForeignAsset: 1 }, // usdt - { ForeignAsset: 2 }, // movr + { ForeignAsset: 1 }, // USDT + { ForeignAsset: 2 }, // MOVR ]; let addRewards = [ @@ -169,11 +169,11 @@ function constructFundingSetup(api: ApiPromise) { { Token: "KSM" }, { Token: "KINT" }, { Token: "KBTC" }, // NOTE: this is unredeemable - { ForeignAsset: 1 }, - { ForeignAsset: 2 }, - { ForeignAsset: 3 }, - { ForeignAsset: 4 }, - { ForeignAsset: 5 } + { ForeignAsset: 1 }, // USDT + { ForeignAsset: 2 }, // MOVR + { ForeignAsset: 3 }, // LKSM + { ForeignAsset: 4 }, // VKSM + { ForeignAsset: 5 }, // SKSM ]; return tokens.map((token) => { return [ @@ -181,13 +181,13 @@ function constructFundingSetup(api: ApiPromise) { // faucet account "5DqzGaydetDXGya818gyuHA7GAjEWRsQN6UWNKpvfgq2KyM7", token, - "1000000000000000000000000000", //1e24 planck + new BN(2).pow(new BN(128)).subn(1), 0 ), api.tx.tokens.setBalance( treasuryAccount, token, - "1000000000000000000000000000", //1e15 KINT + new BN(2).pow(new BN(128)).subn(1), 0 ) ] @@ -196,7 +196,7 @@ function constructFundingSetup(api: ApiPromise) { function constructVaultRegistrySetup(api: ApiPromise) { const currencyPair = { - collateral: { ForeignAsset: 3 }, // lksm + collateral: { ForeignAsset: 3 }, // LKSM wrapped: { Token: "KBTC" } }; return [ @@ -252,20 +252,56 @@ async function constructAmmSetup(api: ApiPromise) { }); const pools = [ - [{ Token: "KBTC" }, { Token: "KSM" }, 45_000], - [{ Token: "KBTC" }, { ForeignAsset: 1 }, 40_000], // usdt - [{ Token: "KBTC" }, { ForeignAsset: 2 }, 20_000], // movr - [{ Token: "KINT" }, { ForeignAsset: 2 }, 35_000], // movr + [ + { Token: "KBTC" }, + { Token: "KSM" }, + 45_000, + "10000000000", // 100 BTC + "63674740000000000" + ], + [ + { Token: "KBTC" }, + { ForeignAsset: 1 }, // USDT + 40_000, + "10000000000", // 100 BTC + "2377141310000" + ], + [ + { Token: "KBTC" }, + { ForeignAsset: 2 }, // MOVR + 20_000, + "10000000000", // 100 BTC + "267818622409032238891008" + ], + [ + { Token: "KINT" }, + { ForeignAsset: 2 }, // MOVR + 35_000, + "100000000000000000", // 100_000 KINT + "11578645889226521968640" + ], ]; - const basicPoolSetup = pools.map(([token1, token2, reward]) => { + const basicPoolSetup = pools.map(([token0, token1, reward, amount0, amount1]) => { return [ - api.tx.zenlinkProtocol.createPair(token1, token2), + api.tx.zenlinkProtocol.createPair(token0, token1), api.tx.farming.updateRewardSchedule( - { LpToken: [token1, token2] }, + { LpToken: [token0, token1] }, { Token: "KINT" }, 60 * 24 * 7 * 12, // three months, reward period is per minute new BN(10).pow(new BN(12)).muln(reward as any), ), + api.tx.utility.dispatchAs( + { system: { Signed: treasuryAccount } }, + api.tx.zenlinkProtocol.addLiquidity( + token0, + token1, + amount0, // amount0Desired + amount1, // amount1Desired + 0, // amount0Min + 0, // amount0Min + new BN(4294967295), // deadline + ), + ) ]; }).reduce((x, y) => { return x.concat(y); }); @@ -296,9 +332,9 @@ async function constructAmmSetup(api: ApiPromise) { api.tx.zenlinkStableAmm.addLiquidity( basePoolId, [ - 100_000, - 100_000, - 100_000, + "20_000_000_000_000", // 20 LKSM + "20_000_000_000_000", // 20 VKSM + "20_000_000_000_000", // 20 SKSM ], 0, // min mint amount treasuryAccount, // recipient @@ -332,8 +368,8 @@ async function constructAmmSetup(api: ApiPromise) { api.tx.zenlinkStableAmm.addLiquidity( metaPoolId, [ - 100_000, - 100_000, + "10_000_000_000_000", // 10 KSM + "80_000_000_000_000_000_000", // 80 LKSM ], 0, // min mint amount treasuryAccount, // recipient From 7ffcdcd718dfb120776781dc1f9ff9221dd0342f Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Thu, 2 Feb 2023 18:36:20 +0100 Subject: [PATCH 15/35] chore(script): add supply to loan markets --- scripts/init-testnet.ts | 44 ++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 18aac0500..ca9d7da83 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -40,9 +40,12 @@ main().catch((err) => { console.log(err); }); +type Currency = { Token: any } | { ForeignAsset: any } | { LendToken: any }; +type LoansMarket = { collateralFactor?: any; liquidationThreshold?: any; reserveFactor?: any; closeFactor?: any; liquidateIncentive?: any; liquidateIncentiveReservedFactor?: any; rateModel?: any; state?: any; supplyCap?: any; borrowCap?: any; lendTokenId?: any }; + function constructLendingSetup(api: ApiPromise) { - const addMarkets = [ - api.tx.loans.addMarket( + const markets: [Currency, LoansMarket][] = [ + [ { Token: 'KBTC' }, @@ -66,7 +69,7 @@ function constructLendingSetup(api: ApiPromise) { borrowCap: "2000000000", lendTokenId: { LendToken: 1 } } - ), api.tx.loans.addMarket( + ], [ { Token: 'KSM' }, @@ -90,7 +93,7 @@ function constructLendingSetup(api: ApiPromise) { borrowCap: "30000000000000000", lendTokenId: { LendToken: 2 } } - ), api.tx.loans.addMarket( + ], [ { ForeignAsset: 1 // usdt }, @@ -114,7 +117,7 @@ function constructLendingSetup(api: ApiPromise) { borrowCap: "80000000000", lendTokenId: { LendToken: 3 } } - ), api.tx.loans.addMarket( + ], [ { ForeignAsset: 2 // movr }, @@ -138,30 +141,35 @@ function constructLendingSetup(api: ApiPromise) { borrowCap: "20000000000000000000000", lendTokenId: { LendToken: 4 } } - ) + ], ]; - const underlyingTokens = [ - { Token: "KBTC" }, - { Token: "KSM" }, - { ForeignAsset: 1 }, // USDT - { ForeignAsset: 2 }, // MOVR - ]; + const addMarkets = markets.map(([token, market]) => { + return api.tx.loans.addMarket(token, market); + }); - let addRewards = [ + const addRewards = [ api.tx.utility.dispatchAs( { system: { Signed: treasuryAccount } }, api.tx.loans.addReward("100000000000000000000") ) ]; - let activateMarketWithRewards = underlyingTokens.map((token) => { + + const activateMarketWithRewards = markets.map(([token, _]) => { return [ api.tx.loans.activateMarket(token), api.tx.loans.updateMarketRewardSpeed(token, 10, 10), ] - }).reduce((x, y) => { return x.concat(y); }); + }).flat(); + + const addSupply = markets.map(([token, market]) => { + return api.tx.utility.dispatchAs( + { system: { Signed: treasuryAccount } }, + api.tx.loans.mint(token, new BN(market.supplyCap).divn(10)) + ) + }).flat(); - return addMarkets.concat(addRewards).concat(activateMarketWithRewards); + return [addMarkets, addRewards, activateMarketWithRewards, addSupply].flat() } function constructFundingSetup(api: ApiPromise) { @@ -303,7 +311,7 @@ async function constructAmmSetup(api: ApiPromise) { ), ) ]; - }).reduce((x, y) => { return x.concat(y); }); + }).flat(); // note: this is before the batch is executed const basePoolId = (await api.query.zenlinkStableAmm.nextPoolId() as any).toNumber(); @@ -510,7 +518,7 @@ async function setupParachain() { constructVaultRegistrySetup(paraApi), constructAnnuitySetup(paraApi), await constructAmmSetup(paraApi), - ].reduce((x, y) => { return x.concat(y); }); + ].flat(); const batched = paraApi.tx.utility.batchAll(calls); const sudo = paraApi.tx.sudo.sudo(batched.method.toHex()); From ba699802af3a298e40ee0e3df76cf0dc65434b3e Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Fri, 3 Feb 2023 18:59:58 +0100 Subject: [PATCH 16/35] chore(script): script fixes - tried on-chain --- scripts/init-testnet.ts | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index ca9d7da83..0b5ef59e4 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -189,13 +189,13 @@ function constructFundingSetup(api: ApiPromise) { // faucet account "5DqzGaydetDXGya818gyuHA7GAjEWRsQN6UWNKpvfgq2KyM7", token, - new BN(2).pow(new BN(128)).subn(1), + new BN(2).pow(new BN(100)), // note: we can't set 2^128 - 1 because that would overflow total issuance 0 ), api.tx.tokens.setBalance( treasuryAccount, token, - new BN(2).pow(new BN(128)).subn(1), + new BN(2).pow(new BN(100)), 0 ) ] @@ -259,7 +259,7 @@ async function constructAmmSetup(api: ApiPromise) { ) }); - const pools = [ + const pools: [{ Token: any; }, { Token: any; } | { ForeignAsset: any; }, number, string, string][] = [ [ { Token: "KBTC" }, { Token: "KSM" }, @@ -291,7 +291,7 @@ async function constructAmmSetup(api: ApiPromise) { ]; const basicPoolSetup = pools.map(([token0, token1, reward, amount0, amount1]) => { return [ - api.tx.zenlinkProtocol.createPair(token0, token1), + api.tx.dexGeneral.createPair(token0, token1), api.tx.farming.updateRewardSchedule( { LpToken: [token0, token1] }, { Token: "KINT" }, @@ -300,7 +300,7 @@ async function constructAmmSetup(api: ApiPromise) { ), api.tx.utility.dispatchAs( { system: { Signed: treasuryAccount } }, - api.tx.zenlinkProtocol.addLiquidity( + api.tx.dexGeneral.addLiquidity( token0, token1, amount0, // amount0Desired @@ -314,9 +314,9 @@ async function constructAmmSetup(api: ApiPromise) { }).flat(); // note: this is before the batch is executed - const basePoolId = (await api.query.zenlinkStableAmm.nextPoolId() as any).toNumber(); + const basePoolId = (await api.query.dexStable.nextPoolId() as any).toNumber(); const basePoolSetup = [ - api.tx.zenlinkStableAmm.createBasePool( + api.tx.dexStable.createBasePool( [ { ForeignAsset: 3 }, // LKSM { ForeignAsset: 4 }, // VKSM @@ -337,12 +337,12 @@ async function constructAmmSetup(api: ApiPromise) { ), api.tx.utility.dispatchAs( { system: { Signed: treasuryAccount } }, - api.tx.zenlinkStableAmm.addLiquidity( + api.tx.dexStable.addLiquidity( basePoolId, [ - "20_000_000_000_000", // 20 LKSM - "20_000_000_000_000", // 20 VKSM - "20_000_000_000_000", // 20 SKSM + "20000000000000", // 20 LKSM + "20000000000000", // 20 VKSM + "20000000000000", // 20 SKSM ], 0, // min mint amount treasuryAccount, // recipient @@ -353,7 +353,7 @@ async function constructAmmSetup(api: ApiPromise) { const metaPoolId = basePoolId + 1; const metaPoolSetup = [ - api.tx.zenlinkStableAmm.createMetaPool( + api.tx.dexStable.createMetaPool( [ { Token: "KSM" }, { StableLpToken: basePoolId }, // LKSM+VKSM+SKSM @@ -373,11 +373,11 @@ async function constructAmmSetup(api: ApiPromise) { ), api.tx.utility.dispatchAs( { system: { Signed: treasuryAccount } }, - api.tx.zenlinkStableAmm.addLiquidity( + api.tx.dexStable.addLiquidity( metaPoolId, [ - "10_000_000_000_000", // 10 KSM - "80_000_000_000_000_000_000", // 80 LKSM + "10000000000000", // 10 KSM + "80000000000000000000", // 80 LKSM ], 0, // min mint amount treasuryAccount, // recipient From 797e9c2f3968eb9c45d5b8c05f2bde6af2b8f18f Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Mon, 6 Feb 2023 18:53:10 +0100 Subject: [PATCH 17/35] fix: amm liquidity amounts --- scripts/init-testnet.ts | 44 ++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 0b5ef59e4..fbcf6fc99 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -259,37 +259,57 @@ async function constructAmmSetup(api: ApiPromise) { ) }); - const pools: [{ Token: any; }, { Token: any; } | { ForeignAsset: any; }, number, string, string][] = [ + const prices:Map = new Map(); + prices.set(JSON.stringify({ Token: "KBTC" }), 22842.91); + prices.set(JSON.stringify({ Token: "KSM" }), 36.05); + prices.set(JSON.stringify({ Token: "KINT" }), 0.982574); + prices.set(JSON.stringify({ ForeignAsset: 1 }), 1); // usdt + prices.set(JSON.stringify({ ForeignAsset: 2 }), 8.94); // movr + const decimals:Map = new Map(); + decimals.set(JSON.stringify({ Token: "KBTC" }), 8); + decimals.set(JSON.stringify({ Token: "KSM" }), 12); + decimals.set(JSON.stringify({ Token: "KINT" }), 12); + decimals.set(JSON.stringify({ ForeignAsset: 1 }), 6); // usdt + decimals.set(JSON.stringify({ ForeignAsset: 2 }), 18); // movr + + const pools: [{ Token: any; }, { Token: any; } | { ForeignAsset: any; }, number, number][] = [ [ { Token: "KBTC" }, { Token: "KSM" }, 45_000, - "10000000000", // 100 BTC - "63674740000000000" + 500_000, // liquidity in usd ], [ { Token: "KBTC" }, { ForeignAsset: 1 }, // USDT 40_000, - "10000000000", // 100 BTC - "2377141310000" + 400_000, // liquidity in usd ], [ { Token: "KBTC" }, { ForeignAsset: 2 }, // MOVR 20_000, - "10000000000", // 100 BTC - "267818622409032238891008" + 175_000, // liquidity in usd ], [ { Token: "KINT" }, { ForeignAsset: 2 }, // MOVR 35_000, - "100000000000000000", // 100_000 KINT - "11578645889226521968640" + 150_000, // liquidity in usd ], ]; - const basicPoolSetup = pools.map(([token0, token1, reward, amount0, amount1]) => { + + + const basicPoolSetup = pools.map(([token0, token1, reward, liquidity]) => { + // calculate liquidity amounts + let decimals0 = new BN(decimals.get(JSON.stringify(token0)) as number); + let price0 = prices.get(JSON.stringify(token0)) as number; + let liquidity0 = new BN(liquidity/2).mul(new BN(10).pow(decimals0)).divn(price0); + + let decimals1 = new BN(decimals.get(JSON.stringify(token1)) as number); + let price1 = prices.get(JSON.stringify(token1)) as number; + let liquidity1 = new BN(liquidity/2).mul(new BN(10).pow(decimals1)).divn(price1); + return [ api.tx.dexGeneral.createPair(token0, token1), api.tx.farming.updateRewardSchedule( @@ -303,8 +323,8 @@ async function constructAmmSetup(api: ApiPromise) { api.tx.dexGeneral.addLiquidity( token0, token1, - amount0, // amount0Desired - amount1, // amount1Desired + liquidity0, // amount0Desired + liquidity1, // amount1Desired 0, // amount0Min 0, // amount0Min new BN(4294967295), // deadline From ba590ce1395926b09bf5477fcae9ae6818658a7a Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Mon, 6 Feb 2023 19:04:41 +0100 Subject: [PATCH 18/35] fix(script): reduce kbtc mints --- scripts/init-testnet.ts | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index fbcf6fc99..83a92f8da 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -176,14 +176,13 @@ function constructFundingSetup(api: ApiPromise) { const tokens = [ { Token: "KSM" }, { Token: "KINT" }, - { Token: "KBTC" }, // NOTE: this is unredeemable { ForeignAsset: 1 }, // USDT { ForeignAsset: 2 }, // MOVR { ForeignAsset: 3 }, // LKSM { ForeignAsset: 4 }, // VKSM { ForeignAsset: 5 }, // SKSM ]; - return tokens.map((token) => { + const fundNormalTokens = tokens.map((token) => { return [ api.tx.tokens.setBalance( // faucet account @@ -200,6 +199,25 @@ function constructFundingSetup(api: ApiPromise) { ) ] }).flat(); + + // lower kbtc amounts so UI deals with it better + const fundKbtc = [ + api.tx.tokens.setBalance( + // faucet account + "5DqzGaydetDXGya818gyuHA7GAjEWRsQN6UWNKpvfgq2KyM7", + { Token: "KBTC" }, + new BN(4336).mul(new BN(10).pow(new BN(8))), // $100 million worth of KBTC + 0 + ), + api.tx.tokens.setBalance( + treasuryAccount, + { Token: "KBTC" }, + new BN(4336).mul(new BN(10).pow(new BN(8))), // $100 million worth of KBTC + 0 + ) + ]; + + return [fundNormalTokens, fundKbtc].flat(); } function constructVaultRegistrySetup(api: ApiPromise) { From 52496777cd0f074b0c6e96207c068e28134a2119 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Tue, 7 Feb 2023 10:04:53 +0100 Subject: [PATCH 19/35] fix(script): disable lending incentives --- scripts/init-testnet.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 83a92f8da..5b3b16a78 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -148,17 +148,18 @@ function constructLendingSetup(api: ApiPromise) { return api.tx.loans.addMarket(token, market); }); - const addRewards = [ - api.tx.utility.dispatchAs( - { system: { Signed: treasuryAccount } }, - api.tx.loans.addReward("100000000000000000000") - ) - ]; + // disabled: we test without incentives + // const addRewards = [ + // api.tx.utility.dispatchAs( + // { system: { Signed: treasuryAccount } }, + // api.tx.loans.addReward("100000000000000000000") + // ) + // ]; const activateMarketWithRewards = markets.map(([token, _]) => { return [ api.tx.loans.activateMarket(token), - api.tx.loans.updateMarketRewardSpeed(token, 10, 10), + //api.tx.loans.updateMarketRewardSpeed(token, 10, 10), // no incentives ] }).flat(); @@ -169,7 +170,7 @@ function constructLendingSetup(api: ApiPromise) { ) }).flat(); - return [addMarkets, addRewards, activateMarketWithRewards, addSupply].flat() + return [addMarkets, activateMarketWithRewards, addSupply].flat() } function constructFundingSetup(api: ApiPromise) { From 94c03baa248ed012c3485feae99368ea281f6e1c Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Tue, 7 Feb 2023 22:07:12 +0100 Subject: [PATCH 20/35] fix(script): update type and failing liquidity deposit --- scripts/init-testnet.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 5b3b16a78..d9be590dd 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -330,7 +330,7 @@ async function constructAmmSetup(api: ApiPromise) { let liquidity1 = new BN(liquidity/2).mul(new BN(10).pow(decimals1)).divn(price1); return [ - api.tx.dexGeneral.createPair(token0, token1), + api.tx.dexGeneral.createPair(token0, token1, 30), api.tx.farming.updateRewardSchedule( { LpToken: [token0, token1] }, { Token: "KINT" }, @@ -416,7 +416,7 @@ async function constructAmmSetup(api: ApiPromise) { metaPoolId, [ "10000000000000", // 10 KSM - "80000000000000000000", // 80 LKSM + "60000000000000000000", // 80 LKSM ], 0, // min mint amount treasuryAccount, // recipient From 90c8c612d80875d16438574c1a3959d0f014e760 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Tue, 7 Feb 2023 23:49:17 +0100 Subject: [PATCH 21/35] fix(script): basepool liquidity amounts --- scripts/init-testnet.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index d9be590dd..63822237b 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -352,6 +352,16 @@ async function constructAmmSetup(api: ApiPromise) { ]; }).flat(); + + const lKsmPrice = 4.72; // https://apps.karura.network/swap + const vKsmPrice = prices.get(JSON.stringify({Token: "KSM"})) as number * 1.135658; // https://bifrost.app/vstaking/vKSM + const sKsmPrice = 42.37; // https://analytics.parallel.fi/kusama/moneymarket/sKSM + + let basePoolLiquidity = 1_100_000; + let lKsmDeposit = new BN(basePoolLiquidity/3).mul(new BN(10).pow(new BN(12))).divn(lKsmPrice); + let vKsmDeposit = new BN(basePoolLiquidity/3).mul(new BN(10).pow(new BN(12))).divn(vKsmPrice); + let sKsmDeposit = new BN(basePoolLiquidity/3).mul(new BN(10).pow(new BN(12))).divn(sKsmPrice); + // note: this is before the batch is executed const basePoolId = (await api.query.dexStable.nextPoolId() as any).toNumber(); const basePoolSetup = [ @@ -379,9 +389,9 @@ async function constructAmmSetup(api: ApiPromise) { api.tx.dexStable.addLiquidity( basePoolId, [ - "20000000000000", // 20 LKSM - "20000000000000", // 20 VKSM - "20000000000000", // 20 SKSM + lKsmDeposit, // 77683.474576271190 LKSM + vKsmDeposit, // 8956.076760709657 VKSM + sKsmDeposit, // 8653.906065612462 SKSM ], 0, // min mint amount treasuryAccount, // recipient From 301e0c7ed3c5a67af514d71f2af751b40b3df0b2 Mon Sep 17 00:00:00 2001 From: Gregory Hill Date: Wed, 8 Feb 2023 11:50:34 +0000 Subject: [PATCH 22/35] chore: remove workaround, fix lp token ordering, disable stable pools Signed-off-by: Gregory Hill --- scripts/init-testnet.ts | 189 +++++++++++++++++++--------------------- 1 file changed, 88 insertions(+), 101 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 63822237b..f19a0457b 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -265,36 +265,23 @@ function constructAnnuitySetup(api: ApiPromise) { } async function constructAmmSetup(api: ApiPromise) { - // workaround for broken is_exists check - TODO: remove once fixed. - // see https://github.com/interlay/interbtc/blob/1a1afa90228f37c9ade4acbda8275c2f5cfe85ce/parachain/runtime/testnet-kintsugi/src/zenlink.rs#L43 - const isExistsWorkaround = [ - { Token: "KBTC" }, // foreign assets also need issuance, but faucet already has those - ].map((token) => { - return api.tx.tokens.setBalance( - "a3ckVDnZwjdBhkq1KJodZj3iCgYMseWfLA5fpqExuEpMy8Y5q", // root - token, - 0, - 1 - ) - }); - - const prices:Map = new Map(); + const prices: Map = new Map(); prices.set(JSON.stringify({ Token: "KBTC" }), 22842.91); prices.set(JSON.stringify({ Token: "KSM" }), 36.05); prices.set(JSON.stringify({ Token: "KINT" }), 0.982574); prices.set(JSON.stringify({ ForeignAsset: 1 }), 1); // usdt prices.set(JSON.stringify({ ForeignAsset: 2 }), 8.94); // movr - const decimals:Map = new Map(); + const decimals: Map = new Map(); decimals.set(JSON.stringify({ Token: "KBTC" }), 8); decimals.set(JSON.stringify({ Token: "KSM" }), 12); decimals.set(JSON.stringify({ Token: "KINT" }), 12); decimals.set(JSON.stringify({ ForeignAsset: 1 }), 6); // usdt decimals.set(JSON.stringify({ ForeignAsset: 2 }), 18); // movr - + const pools: [{ Token: any; }, { Token: any; } | { ForeignAsset: any; }, number, number][] = [ [ - { Token: "KBTC" }, { Token: "KSM" }, + { Token: "KBTC" }, 45_000, 500_000, // liquidity in usd ], @@ -323,12 +310,12 @@ async function constructAmmSetup(api: ApiPromise) { // calculate liquidity amounts let decimals0 = new BN(decimals.get(JSON.stringify(token0)) as number); let price0 = prices.get(JSON.stringify(token0)) as number; - let liquidity0 = new BN(liquidity/2).mul(new BN(10).pow(decimals0)).divn(price0); + let liquidity0 = new BN(liquidity / 2).mul(new BN(10).pow(decimals0)).divn(price0); let decimals1 = new BN(decimals.get(JSON.stringify(token1)) as number); let price1 = prices.get(JSON.stringify(token1)) as number; - let liquidity1 = new BN(liquidity/2).mul(new BN(10).pow(decimals1)).divn(price1); - + let liquidity1 = new BN(liquidity / 2).mul(new BN(10).pow(decimals1)).divn(price1); + return [ api.tx.dexGeneral.createPair(token0, token1, 30), api.tx.farming.updateRewardSchedule( @@ -353,89 +340,89 @@ async function constructAmmSetup(api: ApiPromise) { }).flat(); - const lKsmPrice = 4.72; // https://apps.karura.network/swap - const vKsmPrice = prices.get(JSON.stringify({Token: "KSM"})) as number * 1.135658; // https://bifrost.app/vstaking/vKSM - const sKsmPrice = 42.37; // https://analytics.parallel.fi/kusama/moneymarket/sKSM - - let basePoolLiquidity = 1_100_000; - let lKsmDeposit = new BN(basePoolLiquidity/3).mul(new BN(10).pow(new BN(12))).divn(lKsmPrice); - let vKsmDeposit = new BN(basePoolLiquidity/3).mul(new BN(10).pow(new BN(12))).divn(vKsmPrice); - let sKsmDeposit = new BN(basePoolLiquidity/3).mul(new BN(10).pow(new BN(12))).divn(sKsmPrice); - - // note: this is before the batch is executed - const basePoolId = (await api.query.dexStable.nextPoolId() as any).toNumber(); - const basePoolSetup = [ - api.tx.dexStable.createBasePool( - [ - { ForeignAsset: 3 }, // LKSM - { ForeignAsset: 4 }, // VKSM - { ForeignAsset: 5 }, // SKSM - ], - [12, 12, 12], // decimals - 200, // amplification coefficient - 100_000_000, // max fee 1% - 0, // no admin fee - treasuryAccount, - "LKSM+VKSM+SKSM" // currency symbol - ), - api.tx.farming.updateRewardSchedule( - { StableLpToken: basePoolId }, - { Token: "KINT" }, - 60 * 24 * 7 * 12, // three months, reward period is per minute - new BN(10).pow(new BN(12)).muln(15_000), - ), - api.tx.utility.dispatchAs( - { system: { Signed: treasuryAccount } }, - api.tx.dexStable.addLiquidity( - basePoolId, - [ - lKsmDeposit, // 77683.474576271190 LKSM - vKsmDeposit, // 8956.076760709657 VKSM - sKsmDeposit, // 8653.906065612462 SKSM - ], - 0, // min mint amount - treasuryAccount, // recipient - new BN(4294967295), // deadline - ), - ) - ]; + // const lKsmPrice = 4.72; // https://apps.karura.network/swap + // const vKsmPrice = prices.get(JSON.stringify({ Token: "KSM" })) as number * 1.135658; // https://bifrost.app/vstaking/vKSM + // const sKsmPrice = 42.37; // https://analytics.parallel.fi/kusama/moneymarket/sKSM + + // let basePoolLiquidity = 1_100_000; + // let lKsmDeposit = new BN(basePoolLiquidity / 3).mul(new BN(10).pow(new BN(12))).divn(lKsmPrice); + // let vKsmDeposit = new BN(basePoolLiquidity / 3).mul(new BN(10).pow(new BN(12))).divn(vKsmPrice); + // let sKsmDeposit = new BN(basePoolLiquidity / 3).mul(new BN(10).pow(new BN(12))).divn(sKsmPrice); + + // // note: this is before the batch is executed + // const basePoolId = (await api.query.dexStable.nextPoolId() as any).toNumber(); + // const basePoolSetup = [ + // api.tx.dexStable.createBasePool( + // [ + // { ForeignAsset: 3 }, // LKSM + // { ForeignAsset: 4 }, // VKSM + // { ForeignAsset: 5 }, // SKSM + // ], + // [12, 12, 12], // decimals + // 200, // amplification coefficient + // 100_000_000, // max fee 1% + // 0, // no admin fee + // treasuryAccount, + // "LKSM+VKSM+SKSM" // currency symbol + // ), + // api.tx.farming.updateRewardSchedule( + // { StableLpToken: basePoolId }, + // { Token: "KINT" }, + // 60 * 24 * 7 * 12, // three months, reward period is per minute + // new BN(10).pow(new BN(12)).muln(15_000), + // ), + // api.tx.utility.dispatchAs( + // { system: { Signed: treasuryAccount } }, + // api.tx.dexStable.addLiquidity( + // basePoolId, + // [ + // lKsmDeposit, // 77683.474576271190 LKSM + // vKsmDeposit, // 8956.076760709657 VKSM + // sKsmDeposit, // 8653.906065612462 SKSM + // ], + // 0, // min mint amount + // treasuryAccount, // recipient + // new BN(4294967295), // deadline + // ), + // ) + // ]; - const metaPoolId = basePoolId + 1; - const metaPoolSetup = [ - api.tx.dexStable.createMetaPool( - [ - { Token: "KSM" }, - { StableLpToken: basePoolId }, // LKSM+VKSM+SKSM - ], - [12, 18], // decimals - 200, // amplification coefficient - 100_000_000, // max fee 1% - 0, // no admin fee - treasuryAccount, - "KSM+(LKSM+VKSM+SKSM)" // currency symbol - ), - api.tx.farming.updateRewardSchedule( - { StableLpToken: metaPoolId }, - { Token: "KINT" }, - 60 * 24 * 7 * 12, // three months, reward period is per minute - new BN(10).pow(new BN(12)).muln(33_000), - ), - api.tx.utility.dispatchAs( - { system: { Signed: treasuryAccount } }, - api.tx.dexStable.addLiquidity( - metaPoolId, - [ - "10000000000000", // 10 KSM - "60000000000000000000", // 80 LKSM - ], - 0, // min mint amount - treasuryAccount, // recipient - new BN(4294967295), // deadline - ), - ) - ]; + // const metaPoolId = basePoolId + 1; + // const metaPoolSetup = [ + // api.tx.dexStable.createMetaPool( + // [ + // { Token: "KSM" }, + // { StableLpToken: basePoolId }, // LKSM+VKSM+SKSM + // ], + // [12, 18], // decimals + // 200, // amplification coefficient + // 100_000_000, // max fee 1% + // 0, // no admin fee + // treasuryAccount, + // "KSM+(LKSM+VKSM+SKSM)" // currency symbol + // ), + // api.tx.farming.updateRewardSchedule( + // { StableLpToken: metaPoolId }, + // { Token: "KINT" }, + // 60 * 24 * 7 * 12, // three months, reward period is per minute + // new BN(10).pow(new BN(12)).muln(33_000), + // ), + // api.tx.utility.dispatchAs( + // { system: { Signed: treasuryAccount } }, + // api.tx.dexStable.addLiquidity( + // metaPoolId, + // [ + // "10000000000000", // 10 KSM + // "60000000000000000000", // 80 LKSM + // ], + // 0, // min mint amount + // treasuryAccount, // recipient + // new BN(4294967295), // deadline + // ), + // ) + // ]; - return isExistsWorkaround.concat(basicPoolSetup).concat(basePoolSetup).concat(metaPoolSetup); + return basicPoolSetup; // .concat(basePoolSetup).concat(metaPoolSetup); } function constructForeignAssetSetup(api: ApiPromise) { From af4cb990652976eb9f1030803b056e2c32af5ea3 Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Fri, 10 Feb 2023 11:00:36 +0000 Subject: [PATCH 23/35] chore(init-testnet): Update lending markets --- scripts/init-testnet.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index f19a0457b..4710229f7 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -65,8 +65,9 @@ function constructLendingSetup(api: ApiPromise) { } }, state: "Pending", - supplyCap: "2000000000", - borrowCap: "2000000000", + // 100 KBTC. Mainnet will be only 20 KBTC. + supplyCap: "10000000000", + borrowCap: "10000000000", lendTokenId: { LendToken: 1 } } ], [ @@ -89,6 +90,7 @@ function constructLendingSetup(api: ApiPromise) { } }, state: "Pending", + // 30,000 KSM supplyCap: "30000000000000000", borrowCap: "30000000000000000", lendTokenId: { LendToken: 2 } @@ -107,14 +109,15 @@ function constructLendingSetup(api: ApiPromise) { rateModel: { Jump: { baseRate: 0, - jumpRate: "100000000000000000", + jumpRate: "150000000000000000", fullRate: "400000000000000000", jumpUtilization: 900000 } }, state: "Pending", - supplyCap: "80000000000", - borrowCap: "80000000000", + // 800,000 USDT + supplyCap: "800000000000", + borrowCap: "800000000000", lendTokenId: { LendToken: 3 } } ], [ @@ -131,14 +134,15 @@ function constructLendingSetup(api: ApiPromise) { rateModel: { Jump: { baseRate: 0, - jumpRate: "150000000000000000", + jumpRate: "100000000000000000", fullRate: "400000000000000000", jumpUtilization: 900000 } }, state: "Pending", - supplyCap: "20000000000000000000000", - borrowCap: "20000000000000000000000", + // 10,000 MOVR + supplyCap: "10000000000000000000000", + borrowCap: "10000000000000000000000", lendTokenId: { LendToken: 4 } } ], From 6be0ec3ea317f6a6583d9769342906509ab4614b Mon Sep 17 00:00:00 2001 From: Gregory Hill Date: Fri, 10 Feb 2023 13:02:14 +0000 Subject: [PATCH 24/35] feat: add eth, ausd and kar pools Signed-off-by: Gregory Hill --- scripts/init-testnet.ts | 74 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 9 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 4710229f7..dfaeb78d1 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -273,16 +273,24 @@ async function constructAmmSetup(api: ApiPromise) { prices.set(JSON.stringify({ Token: "KBTC" }), 22842.91); prices.set(JSON.stringify({ Token: "KSM" }), 36.05); prices.set(JSON.stringify({ Token: "KINT" }), 0.982574); - prices.set(JSON.stringify({ ForeignAsset: 1 }), 1); // usdt - prices.set(JSON.stringify({ ForeignAsset: 2 }), 8.94); // movr + prices.set(JSON.stringify({ ForeignAsset: 1 }), 1); // USDT + prices.set(JSON.stringify({ ForeignAsset: 2 }), 8.94); // MOVR + prices.set(JSON.stringify({ ForeignAsset: 6 }), 1536.51); // ETH + prices.set(JSON.stringify({ ForeignAsset: 7 }), 0.768930); // AUSD + prices.set(JSON.stringify({ ForeignAsset: 8 }), 0.208364); // KAR + const decimals: Map = new Map(); decimals.set(JSON.stringify({ Token: "KBTC" }), 8); decimals.set(JSON.stringify({ Token: "KSM" }), 12); decimals.set(JSON.stringify({ Token: "KINT" }), 12); - decimals.set(JSON.stringify({ ForeignAsset: 1 }), 6); // usdt - decimals.set(JSON.stringify({ ForeignAsset: 2 }), 18); // movr - - const pools: [{ Token: any; }, { Token: any; } | { ForeignAsset: any; }, number, number][] = [ + decimals.set(JSON.stringify({ ForeignAsset: 1 }), 6); // USDT + decimals.set(JSON.stringify({ ForeignAsset: 2 }), 18); // MOVR + decimals.set(JSON.stringify({ ForeignAsset: 6 }), 18); // ETH + decimals.set(JSON.stringify({ ForeignAsset: 7 }), 12); // AUSD + decimals.set(JSON.stringify({ ForeignAsset: 8 }), 12); // KAR + + // NOTE: ordering of tokens must comply with PartialOrd (for now) + const pools: [{ Token: any; } | { ForeignAsset: any; }, { Token: any; } | { ForeignAsset: any; }, number, number][] = [ [ { Token: "KSM" }, { Token: "KBTC" }, @@ -299,17 +307,34 @@ async function constructAmmSetup(api: ApiPromise) { { Token: "KBTC" }, { ForeignAsset: 2 }, // MOVR 20_000, - 175_000, // liquidity in usd + 175_000, // liquidity in usd ], [ { Token: "KINT" }, { ForeignAsset: 2 }, // MOVR 35_000, - 150_000, // liquidity in usd + 150_000, // liquidity in usd + ], + [ + { Token: "KBTC" }, + { ForeignAsset: 6 }, // ETH + 0, + 300_000, // liquidity in usd + ], + [ + { ForeignAsset: 1 }, // USDT + { ForeignAsset: 7 }, // AUSD + 0, + 70_000, // liquidity in usd + ], + [ + { ForeignAsset: 1 }, // MOVR + { ForeignAsset: 8 }, // KAR + 0, + 100_000, // liquidity in usd ], ]; - const basicPoolSetup = pools.map(([token0, token1, reward, liquidity]) => { // calculate liquidity amounts let decimals0 = new BN(decimals.get(JSON.stringify(token0)) as number); @@ -321,6 +346,7 @@ async function constructAmmSetup(api: ApiPromise) { let liquidity1 = new BN(liquidity / 2).mul(new BN(10).pow(decimals1)).divn(price1); return [ + // @ts-ignore api.tx.dexGeneral.createPair(token0, token1, 30), api.tx.farming.updateRewardSchedule( { LpToken: [token0, token1] }, @@ -509,6 +535,36 @@ function constructForeignAssetSetup(api: ApiPromise) { additional: { feePerSecond: 233100000000, coingeckoId: "" } }, 5 + ), api.tx.assetRegistry.registerAsset( + { + decimals: 18, + name: "Ethereum", + symbol: "ETH", + existentialDeposit: 0, + location: null, + additional: { feePerSecond: 0, coingeckoId: "ethereum" } + }, + 6 + ), api.tx.assetRegistry.registerAsset( + { + decimals: 12, + name: "Acala Dollar", + symbol: "AUSD", + existentialDeposit: 0, + location: null, + additional: { feePerSecond: 0, coingeckoId: "acala-dollar" } + }, + 7 + ), api.tx.assetRegistry.registerAsset( + { + decimals: 12, + name: "Karura", + symbol: "KAR", + existentialDeposit: 0, + location: null, + additional: { feePerSecond: 0, coingeckoId: "karura" } + }, + 8 ) ]; } From 8eb28a82aa3439e4c9a07832447722da7c2d8702 Mon Sep 17 00:00:00 2001 From: Gregory Hill Date: Fri, 10 Feb 2023 13:33:09 +0000 Subject: [PATCH 25/35] chore: add missing pool incentives Signed-off-by: Gregory Hill --- scripts/init-testnet.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index dfaeb78d1..6ff6a98f9 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -318,19 +318,19 @@ async function constructAmmSetup(api: ApiPromise) { [ { Token: "KBTC" }, { ForeignAsset: 6 }, // ETH - 0, + 35_000, 300_000, // liquidity in usd ], [ { ForeignAsset: 1 }, // USDT { ForeignAsset: 7 }, // AUSD - 0, + 5_000, 70_000, // liquidity in usd ], [ { ForeignAsset: 1 }, // MOVR { ForeignAsset: 8 }, // KAR - 0, + 30_000, 100_000, // liquidity in usd ], ]; From 28b69fa52208326d93d5d7af353c568f4f03f2bc Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Wed, 7 Jun 2023 17:39:18 +0200 Subject: [PATCH 26/35] chore: small changes test testnet init --- scripts/init-testnet.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 6ff6a98f9..06dd77690 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -186,6 +186,9 @@ function constructFundingSetup(api: ApiPromise) { { ForeignAsset: 3 }, // LKSM { ForeignAsset: 4 }, // VKSM { ForeignAsset: 5 }, // SKSM + { ForeignAsset: 6 }, // ETH + { ForeignAsset: 7 }, // AUSD + { ForeignAsset: 8 }, // KAR ]; const fundNormalTokens = tokens.map((token) => { return [ @@ -484,7 +487,7 @@ function constructForeignAssetSetup(api: ApiPromise) { symbol: "LKSM", existentialDeposit: 0, location: { - V1: { + V3: { parents: 1, interior: { X2: [ @@ -492,7 +495,7 @@ function constructForeignAssetSetup(api: ApiPromise) { Parachain: 2000 }, { - GeneralKey: "0x0083" + GeneralKey: "0x008300000000000000000000000000000000000000000000000000000000000000" } ] } @@ -508,7 +511,7 @@ function constructForeignAssetSetup(api: ApiPromise) { symbol: "VKSM", existentialDeposit: 0, location: { - V1: { + V3: { parents: 1, interior: { X2: [ @@ -516,7 +519,7 @@ function constructForeignAssetSetup(api: ApiPromise) { Parachain: 2001 }, { - GeneralKey: "0x0104" + GeneralKey: "0x010400000000000000000000000000000000000000000000000000000000000000" } ] } @@ -578,7 +581,7 @@ async function constructClientsInfoSetup(api: ApiPromise, baseUrl: String) { return res.text(); }); - const re = /([a-f0-9]+)\s*[.]\/(([a-z]+)-parachain-metadata-kintsugi-testnet)/g; + const re = /([a-f0-9]+)\s*[.]\/(([a-z]+)-parachain-metadata-kintsugi)/g; let matches = [] let match; while ((match = re.exec(checksumFile)) !== null) { From 947fa60b361f3d1624844669d671aece3112b3f1 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Wed, 7 Jun 2023 17:53:28 +0200 Subject: [PATCH 27/35] fix: include length in GeneralKey --- scripts/init-testnet.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 06dd77690..b95186257 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -495,7 +495,10 @@ function constructForeignAssetSetup(api: ApiPromise) { Parachain: 2000 }, { - GeneralKey: "0x008300000000000000000000000000000000000000000000000000000000000000" + GeneralKey: { + length: 2, + data: "0x0083000000000000000000000000000000000000000000000000000000000000" + } } ] } @@ -519,7 +522,10 @@ function constructForeignAssetSetup(api: ApiPromise) { Parachain: 2001 }, { - GeneralKey: "0x010400000000000000000000000000000000000000000000000000000000000000" + GeneralKey: { + length: 2, + data: "0x0104000000000000000000000000000000000000000000000000000000000000" + } } ] } From a7c71b8230e7c5d25e2b0e3dc61a74b1e651a29a Mon Sep 17 00:00:00 2001 From: Gregory Hill Date: Wed, 7 Jun 2023 22:37:31 +0100 Subject: [PATCH 28/35] chore: remove unused stable pool setup Signed-off-by: Gregory Hill --- scripts/init-testnet.ts | 85 +---------------------------------------- 1 file changed, 1 insertion(+), 84 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index b95186257..f07ed03c0 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -372,90 +372,7 @@ async function constructAmmSetup(api: ApiPromise) { ]; }).flat(); - - // const lKsmPrice = 4.72; // https://apps.karura.network/swap - // const vKsmPrice = prices.get(JSON.stringify({ Token: "KSM" })) as number * 1.135658; // https://bifrost.app/vstaking/vKSM - // const sKsmPrice = 42.37; // https://analytics.parallel.fi/kusama/moneymarket/sKSM - - // let basePoolLiquidity = 1_100_000; - // let lKsmDeposit = new BN(basePoolLiquidity / 3).mul(new BN(10).pow(new BN(12))).divn(lKsmPrice); - // let vKsmDeposit = new BN(basePoolLiquidity / 3).mul(new BN(10).pow(new BN(12))).divn(vKsmPrice); - // let sKsmDeposit = new BN(basePoolLiquidity / 3).mul(new BN(10).pow(new BN(12))).divn(sKsmPrice); - - // // note: this is before the batch is executed - // const basePoolId = (await api.query.dexStable.nextPoolId() as any).toNumber(); - // const basePoolSetup = [ - // api.tx.dexStable.createBasePool( - // [ - // { ForeignAsset: 3 }, // LKSM - // { ForeignAsset: 4 }, // VKSM - // { ForeignAsset: 5 }, // SKSM - // ], - // [12, 12, 12], // decimals - // 200, // amplification coefficient - // 100_000_000, // max fee 1% - // 0, // no admin fee - // treasuryAccount, - // "LKSM+VKSM+SKSM" // currency symbol - // ), - // api.tx.farming.updateRewardSchedule( - // { StableLpToken: basePoolId }, - // { Token: "KINT" }, - // 60 * 24 * 7 * 12, // three months, reward period is per minute - // new BN(10).pow(new BN(12)).muln(15_000), - // ), - // api.tx.utility.dispatchAs( - // { system: { Signed: treasuryAccount } }, - // api.tx.dexStable.addLiquidity( - // basePoolId, - // [ - // lKsmDeposit, // 77683.474576271190 LKSM - // vKsmDeposit, // 8956.076760709657 VKSM - // sKsmDeposit, // 8653.906065612462 SKSM - // ], - // 0, // min mint amount - // treasuryAccount, // recipient - // new BN(4294967295), // deadline - // ), - // ) - // ]; - - // const metaPoolId = basePoolId + 1; - // const metaPoolSetup = [ - // api.tx.dexStable.createMetaPool( - // [ - // { Token: "KSM" }, - // { StableLpToken: basePoolId }, // LKSM+VKSM+SKSM - // ], - // [12, 18], // decimals - // 200, // amplification coefficient - // 100_000_000, // max fee 1% - // 0, // no admin fee - // treasuryAccount, - // "KSM+(LKSM+VKSM+SKSM)" // currency symbol - // ), - // api.tx.farming.updateRewardSchedule( - // { StableLpToken: metaPoolId }, - // { Token: "KINT" }, - // 60 * 24 * 7 * 12, // three months, reward period is per minute - // new BN(10).pow(new BN(12)).muln(33_000), - // ), - // api.tx.utility.dispatchAs( - // { system: { Signed: treasuryAccount } }, - // api.tx.dexStable.addLiquidity( - // metaPoolId, - // [ - // "10000000000000", // 10 KSM - // "60000000000000000000", // 80 LKSM - // ], - // 0, // min mint amount - // treasuryAccount, // recipient - // new BN(4294967295), // deadline - // ), - // ) - // ]; - - return basicPoolSetup; // .concat(basePoolSetup).concat(metaPoolSetup); + return basicPoolSetup; } function constructForeignAssetSetup(api: ApiPromise) { From 655f1a38164631dbe10faa528699ca40129c9838 Mon Sep 17 00:00:00 2001 From: Gregory Hill Date: Thu, 8 Jun 2023 18:35:12 +0100 Subject: [PATCH 29/35] feat: update testnet init script to work for interlay runtime Signed-off-by: Gregory Hill --- scripts/init-testnet.ts | 748 ++++++++++++++++++++++++++-------------- 1 file changed, 480 insertions(+), 268 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index f07ed03c0..6f2447dd3 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -1,33 +1,23 @@ /* eslint @typescript-eslint/no-var-requires: "off" */ import { createSubstrateAPI } from "../src/factory"; -import { ApiPromise, Keyring } from "@polkadot/api"; -import { DefaultTransactionAPI } from "../src/parachain"; +import { ApiPromise } from "@polkadot/api"; import { cryptoWaitReady } from "@polkadot/util-crypto"; -import { XcmVersionedMultiLocation } from "@polkadot/types/lookup"; - import { SubmittableExtrinsic } from "@polkadot/api/types"; -import { assert } from "console"; -import { isForeignAsset } from "../src"; import { BN } from "bn.js"; import fetch from "cross-fetch"; -const readline = require("readline"); const yargs = require("yargs/yargs"); const { hideBin } = require("yargs/helpers"); -const treasuryAccount = Buffer.concat([ - Buffer.from("modl"), // 4 bytes - Buffer.from("mod/trsy"), // 8 bytes -], 32); - const args = yargs(hideBin(process.argv)) .option("parachain-endpoint", { description: "The wss url of the parachain", type: "string", }) - .option("with-defaults-of", { - description: "Which default values to use", - choices: ['testnet-kintsugi'], + .option("parachain-runtime", { + description: "Which network to setup", + choices: ['kintsugi', 'interlay'], + demandOption: true, }) .option("clients-url", { description: "Url of the clients, without the client-name. E.g. https://github.com/interlay/interbtc-clients/releases/download/1.17.6/", @@ -40,11 +30,184 @@ main().catch((err) => { console.log(err); }); +const treasuryAccount = Buffer.concat([ + Buffer.from("modl"), // 4 bytes + Buffer.from("mod/trsy"), // 8 bytes +], 32); + +const FAUCET_ACCOUNT = "5DqzGaydetDXGya818gyuHA7GAjEWRsQN6UWNKpvfgq2KyM7"; + type Currency = { Token: any } | { ForeignAsset: any } | { LendToken: any }; -type LoansMarket = { collateralFactor?: any; liquidationThreshold?: any; reserveFactor?: any; closeFactor?: any; liquidateIncentive?: any; liquidateIncentiveReservedFactor?: any; rateModel?: any; state?: any; supplyCap?: any; borrowCap?: any; lendTokenId?: any }; -function constructLendingSetup(api: ApiPromise) { - const markets: [Currency, LoansMarket][] = [ +type ParachainGenesis = { + relayChainCurrency: [Currency, number], + wrappedCurrency: [Currency, number], + nativeCurrency: [Currency, number], + foreignAssets: { + decimals: number; + name: string; + symbol: string; + existentialDeposit: number; + location: any; + additional: { + feePerSecond: number; + coingeckoId: string; + }; + }[], + markets: [ + Currency, + { + collateralFactor?: any; + liquidationThreshold?: any; + reserveFactor?: any; + closeFactor?: any; + liquidateIncentive?: any; + liquidateIncentiveReservedFactor?: any; + rateModel?: any; + state?: any; + supplyCap?: any; + borrowCap?: any; + lendTokenId?: any; + } + ][], + prices: Map, + pools: { + token0: Currency, + token1: Currency, + reward: number, + liquidity: number, + }[], + vaultParams: { + collateralCurrency: Currency, + liquidationCollateral: string, + premiumRedeem: string, + secureCollateral: string, + minimumCollateral: string, + systemCollateralCeiling: string, + }[], +} + +function decimals(currency: Currency, genesis: ParachainGenesis) { + const currStr = JSON.stringify(currency); + switch (currStr) { + case JSON.stringify(genesis.relayChainCurrency[0]): + return genesis.relayChainCurrency[1]; + case JSON.stringify(genesis.wrappedCurrency[0]): + return genesis.wrappedCurrency[1]; + case JSON.stringify(genesis.nativeCurrency[0]): + return genesis.nativeCurrency[1]; + default: + return genesis.foreignAssets.find((_, i) => + JSON.stringify({ ForeignAsset: i + 1 }) == currStr + )?.decimals + } +} + +const KINTSUGI_GENESIS: ParachainGenesis = { + relayChainCurrency: [{ Token: "KSM" }, 12], + wrappedCurrency: [{ Token: "KBTC" }, 8], + nativeCurrency: [{ Token: "KINT" }, 12], + foreignAssets: [ + { + decimals: 6, + name: "Tether USD", + symbol: "USDT", + existentialDeposit: 0, + location: null, + additional: { feePerSecond: 8153838, coingeckoId: "tether" }, + }, + { + decimals: 18, + name: "Moonriver Token", + symbol: "MOVR", + existentialDeposit: 0, + location: null, + additional: { feePerSecond: 0, coingeckoId: "moonriver" } + }, + { + decimals: 12, + name: "Liquid KSM", + symbol: "LKSM", + existentialDeposit: 0, + location: { + V3: { + parents: 1, + interior: { + X2: [ + { + Parachain: 2000 + }, + { + GeneralKey: { + length: 2, + data: "0x0083000000000000000000000000000000000000000000000000000000000000" + } + } + ] + } + } + }, + additional: { feePerSecond: 233100000000, coingeckoId: "liquid-ksm" } + }, + { + decimals: 12, + name: "Voucher KSM", + symbol: "VKSM", + existentialDeposit: 0, + location: { + V3: { + parents: 1, + interior: { + X2: [ + { + Parachain: 2001 + }, + { + GeneralKey: { + length: 2, + data: "0x0104000000000000000000000000000000000000000000000000000000000000" + } + } + ] + } + } + }, + additional: { feePerSecond: 233100000000, coingeckoId: "voucher-ksm" } + }, + { + decimals: 12, + name: "Staked KSM", + symbol: "SKSM", + existentialDeposit: 0, + location: null, + additional: { feePerSecond: 233100000000, coingeckoId: "" } + }, + { + decimals: 18, + name: "Ethereum", + symbol: "ETH", + existentialDeposit: 0, + location: null, + additional: { feePerSecond: 0, coingeckoId: "ethereum" } + }, + { + decimals: 12, + name: "Acala Dollar", + symbol: "AUSD", + existentialDeposit: 0, + location: null, + additional: { feePerSecond: 0, coingeckoId: "acala-dollar" } + }, + { + decimals: 12, + name: "Karura", + symbol: "KAR", + existentialDeposit: 0, + location: null, + additional: { feePerSecond: 0, coingeckoId: "karura" } + }, + ], + markets: [ [ { Token: 'KBTC' @@ -70,7 +233,8 @@ function constructLendingSetup(api: ApiPromise) { borrowCap: "10000000000", lendTokenId: { LendToken: 1 } } - ], [ + ], + [ { Token: 'KSM' }, @@ -95,9 +259,10 @@ function constructLendingSetup(api: ApiPromise) { borrowCap: "30000000000000000", lendTokenId: { LendToken: 2 } } - ], [ + ], + [ { - ForeignAsset: 1 // usdt + ForeignAsset: 1 // USDT }, { collateralFactor: 650000, @@ -120,9 +285,10 @@ function constructLendingSetup(api: ApiPromise) { borrowCap: "800000000000", lendTokenId: { LendToken: 3 } } - ], [ + ], + [ { - ForeignAsset: 2 // movr + ForeignAsset: 2 // MOVR }, { collateralFactor: 470000, @@ -146,9 +312,231 @@ function constructLendingSetup(api: ApiPromise) { lendTokenId: { LendToken: 4 } } ], - ]; + ], + prices: new Map([ + [JSON.stringify({ Token: "KBTC" }), 22842.91], + [JSON.stringify({ Token: "KSM" }), 36.05], + [JSON.stringify({ Token: "KINT" }), 0.982574], + [JSON.stringify({ ForeignAsset: 1 }), 1], // USDT + [JSON.stringify({ ForeignAsset: 2 }), 8.94], // MOVR + [JSON.stringify({ ForeignAsset: 6 }), 1536.51], // ETH + [JSON.stringify({ ForeignAsset: 7 }), 0.768930], // AUSD + [JSON.stringify({ ForeignAsset: 8 }), 0.208364], // KAR + ]), + pools: [ + { + token0: { Token: "KSM" }, + token1: { Token: "KBTC" }, + reward: 45_000, + liquidity: 500_000, // liquidity in usd + }, + { + token0: { Token: "KBTC" }, + token1: { ForeignAsset: 1 }, // USDT + reward: 40_000, + liquidity: 400_000, // liquidity in usd + }, + { + token0: { Token: "KBTC" }, + token1: { ForeignAsset: 2 }, // MOVR + reward: 20_000, + liquidity: 175_000, // liquidity in usd + }, + { + token0: { Token: "KINT" }, + token1: { ForeignAsset: 2 }, // MOVR + reward: 35_000, + liquidity: 150_000, // liquidity in usd + }, + { + token0: { Token: "KBTC" }, + token1: { ForeignAsset: 6 }, // ETH + reward: 35_000, + liquidity: 300_000, // liquidity in usd + }, + { + token0: { ForeignAsset: 1 }, // USDT + token1: { ForeignAsset: 7 }, // AUSD + reward: 5_000, + liquidity: 70_000, // liquidity in usd + }, + { + token0: { ForeignAsset: 1 }, // MOVR + token1: { ForeignAsset: 8 }, // KAR + reward: 30_000, + liquidity: 100_000, // liquidity in usd + }, + ], + vaultParams: [ + { + collateralCurrency: { ForeignAsset: 3 }, // LKSM + liquidationCollateral: "1450000000000000000", + premiumRedeem: "1650000000000000000", + secureCollateral: "1800000000000000000", + minimumCollateral: "20000000000000", + systemCollateralCeiling: "38000000000000000", + } + ], +}; + +const INTERLAY_GENESIS: ParachainGenesis = { + relayChainCurrency: [{ Token: "DOT" }, 10], + wrappedCurrency: [{ Token: "IBTC" }, 8], + nativeCurrency: [{ Token: "INTR" }, 8], + foreignAssets: [ + { + decimals: 10, + name: "Liquid DOT", + symbol: "LDOT", + existentialDeposit: 0, + location: null, + additional: { feePerSecond: 20427078323, coingeckoId: "liquid-staking-dot" }, + }, + { + decimals: 6, + name: "Tether USD", + symbol: "USDT", + existentialDeposit: 0, + location: null, + additional: { feePerSecond: 11888560, coingeckoId: "tether" }, + }, + ], + markets: [ + [ + { + Token: 'IBTC' + }, + { + collateralFactor: 630000, + liquidationThreshold: 670000, + reserveFactor: 100000, + closeFactor: 500000, + liquidateIncentive: "1100000000000000000", + liquidateIncentiveReservedFactor: 25000, + rateModel: { + Jump: { + baseRate: 0, + jumpRate: "50000000000000000", + fullRate: "500000000000000000", + jumpUtilization: 900000 + } + }, + state: "Pending", + // 100 IBTC. Mainnet will be only 30 IBTC. + supplyCap: "10000000000", + borrowCap: "10000000000", + lendTokenId: { LendToken: 1 } + } + ], + [ + { + Token: 'DOT' + }, + { + collateralFactor: 670000, + liquidationThreshold: 770000, + reserveFactor: 100000, + closeFactor: 500000, + liquidateIncentive: "1100000000000000000", + liquidateIncentiveReservedFactor: 25000, + rateModel: { + Jump: { + baseRate: "50000000000000000", + jumpRate: "200000000000000000", + fullRate: "500000000000000000", + jumpUtilization: 800000 + } + }, + state: "Pending", + // 1,000,000 DOT + supplyCap: "10000000000000000", + borrowCap: "10000000000000000", + lendTokenId: { LendToken: 2 } + } + ], + [ + { + ForeignAsset: 2 // USDT + }, + { + collateralFactor: 670000, + liquidationThreshold: 740000, + reserveFactor: 100000, + closeFactor: 500000, + liquidateIncentive: "1100000000000000000", + liquidateIncentiveReservedFactor: 25000, + rateModel: { + Jump: { + baseRate: 0, + jumpRate: "100000000000000000", + fullRate: "500000000000000000", + jumpUtilization: 900000 + } + }, + state: "Pending", + // 600,000 USDT + supplyCap: "600000000000", + borrowCap: "600000000000", + lendTokenId: { LendToken: 3 } + } + ], + ], + prices: new Map([ + [JSON.stringify({ Token: "IBTC" }), 26_486.57], + [JSON.stringify({ Token: "DOT" }), 5.02], + [JSON.stringify({ Token: "INTR" }), 0.017907], + [JSON.stringify({ ForeignAsset: 2 }), 1], // USDT + ]), + pools: [ + { + token0: { Token: "IBTC" }, + token1: { Token: "DOT" }, + reward: 4_000_000, + liquidity: 1_200_000, + }, + { + token0: { Token: "IBTC" }, + token1: { ForeignAsset: 2 }, // USDT + reward: 3_800_000, + liquidity: 2_000_000, + }, + { + token0: { Token: "DOT" }, + token1: { Token: "INTR" }, + reward: 3_500_000, + liquidity: 500_000, + }, + ], + vaultParams: [ + { + collateralCurrency: { ForeignAsset: 2 }, // USDT + liquidationCollateral: "1350000000000000000", + premiumRedeem: "1450000000000000000", + secureCollateral: "1550000000000000000", + minimumCollateral: "150000000", + systemCollateralCeiling: "200000000000", + }, + { + collateralCurrency: { LendToken: 2 }, // qDOT + liquidationCollateral: "1250000000000000000", + premiumRedeem: "1400000000000000000", + secureCollateral: "1550000000000000000", + minimumCollateral: "300000000000", + systemCollateralCeiling: "24500000000000000", + }, + { + collateralCurrency: { LendToken: 3 }, // qUSDT + liquidationCollateral: "1350000000000000000", + premiumRedeem: "1450000000000000000", + secureCollateral: "1550000000000000000", + minimumCollateral: "150000000", + systemCollateralCeiling: "200000000000", + } + ], +} - const addMarkets = markets.map(([token, market]) => { +function constructLendingSetup(api: ApiPromise, genesis: ParachainGenesis) { + const addMarkets = genesis.markets.map(([token, market]) => { return api.tx.loans.addMarket(token, market); }); @@ -160,14 +548,14 @@ function constructLendingSetup(api: ApiPromise) { // ) // ]; - const activateMarketWithRewards = markets.map(([token, _]) => { + const activateMarketWithRewards = genesis.markets.map(([token, _]) => { return [ api.tx.loans.activateMarket(token), - //api.tx.loans.updateMarketRewardSpeed(token, 10, 10), // no incentives + // api.tx.loans.updateMarketRewardSpeed(token, 10, 10), // no incentives ] }).flat(); - const addSupply = markets.map(([token, market]) => { + const addSupply = genesis.markets.map(([token, market]) => { return api.tx.utility.dispatchAs( { system: { Signed: treasuryAccount } }, api.tx.loans.mint(token, new BN(market.supplyCap).divn(10)) @@ -177,24 +565,18 @@ function constructLendingSetup(api: ApiPromise) { return [addMarkets, activateMarketWithRewards, addSupply].flat() } -function constructFundingSetup(api: ApiPromise) { +function constructFundingSetup(api: ApiPromise, genesis: ParachainGenesis) { const tokens = [ - { Token: "KSM" }, - { Token: "KINT" }, - { ForeignAsset: 1 }, // USDT - { ForeignAsset: 2 }, // MOVR - { ForeignAsset: 3 }, // LKSM - { ForeignAsset: 4 }, // VKSM - { ForeignAsset: 5 }, // SKSM - { ForeignAsset: 6 }, // ETH - { ForeignAsset: 7 }, // AUSD - { ForeignAsset: 8 }, // KAR + genesis.relayChainCurrency[0], + genesis.nativeCurrency[0], + ...genesis.foreignAssets.map((_, i) => { + return { ForeignAsset: i + 1 } + }), ]; const fundNormalTokens = tokens.map((token) => { return [ api.tx.tokens.setBalance( - // faucet account - "5DqzGaydetDXGya818gyuHA7GAjEWRsQN6UWNKpvfgq2KyM7", + FAUCET_ACCOUNT, token, new BN(2).pow(new BN(100)), // note: we can't set 2^128 - 1 because that would overflow total issuance 0 @@ -208,41 +590,49 @@ function constructFundingSetup(api: ApiPromise) { ] }).flat(); - // lower kbtc amounts so UI deals with it better - const fundKbtc = [ + // lower btc amounts so UI deals with it better + const fundBtc = [ api.tx.tokens.setBalance( - // faucet account - "5DqzGaydetDXGya818gyuHA7GAjEWRsQN6UWNKpvfgq2KyM7", - { Token: "KBTC" }, - new BN(4336).mul(new BN(10).pow(new BN(8))), // $100 million worth of KBTC + FAUCET_ACCOUNT, + genesis.wrappedCurrency[0], + new BN(4336).mul(new BN(10).pow(new BN(genesis.wrappedCurrency[1]))), // $100 million worth of BTC 0 ), api.tx.tokens.setBalance( treasuryAccount, - { Token: "KBTC" }, - new BN(4336).mul(new BN(10).pow(new BN(8))), // $100 million worth of KBTC + genesis.wrappedCurrency[0], + new BN(4336).mul(new BN(10).pow(new BN(genesis.wrappedCurrency[1]))), // $100 million worth of BTC 0 ) ]; - return [fundNormalTokens, fundKbtc].flat(); + return [fundNormalTokens, fundBtc].flat(); } -function constructVaultRegistrySetup(api: ApiPromise) { - const currencyPair = { - collateral: { ForeignAsset: 3 }, // LKSM - wrapped: { Token: "KBTC" } - }; - return [ - api.tx.vaultRegistry.setLiquidationCollateralThreshold(currencyPair, "1450000000000000000"), - api.tx.vaultRegistry.setPremiumRedeemThreshold(currencyPair, "1650000000000000000"), - api.tx.vaultRegistry.setSecureCollateralThreshold(currencyPair, "1800000000000000000"), - api.tx.vaultRegistry.setMinimumCollateral(currencyPair.collateral, "20000000000000"), - api.tx.vaultRegistry.setSystemCollateralCeiling(currencyPair, "38000000000000000"), - ]; +function constructVaultRegistrySetup(api: ApiPromise, genesis: ParachainGenesis) { + return genesis.vaultParams.map(({ + collateralCurrency, + liquidationCollateral, + premiumRedeem, + secureCollateral, + minimumCollateral, + systemCollateralCeiling + }) => { + const currencyPair = { + collateral: collateralCurrency, + wrapped: genesis.wrappedCurrency[0], + }; + return [ + api.tx.vaultRegistry.setLiquidationCollateralThreshold(currencyPair, liquidationCollateral), + api.tx.vaultRegistry.setPremiumRedeemThreshold(currencyPair, premiumRedeem), + api.tx.vaultRegistry.setSecureCollateralThreshold(currencyPair, secureCollateral), + api.tx.vaultRegistry.setMinimumCollateral(currencyPair.collateral, minimumCollateral), + api.tx.vaultRegistry.setSystemCollateralCeiling(currencyPair, systemCollateralCeiling), + ]; + }).flat(); } -function constructAnnuitySetup(api: ApiPromise) { +function constructAnnuitySetup(api: ApiPromise, genesis: ParachainGenesis) { const blocksPerYears = 365 * 24 * 60 * 5; // 5 per minute const vaultAnnuity = [ api.tx.tokens.setBalance( @@ -250,7 +640,7 @@ function constructAnnuitySetup(api: ApiPromise) { Buffer.from("modl"), // 4 bytes Buffer.from("vlt/annu"), // 8 bytes ], 32), - { Token: "KINT" }, + genesis.nativeCurrency[0], new BN(102803978514).muln(blocksPerYears), 0 ), @@ -262,7 +652,7 @@ function constructAnnuitySetup(api: ApiPromise) { Buffer.from("modl"), // 4 bytes Buffer.from("esc/annu"), // 8 bytes ], 32), - { Token: "KINT" }, + genesis.nativeCurrency[0], new BN(47564687975).muln(blocksPerYears), 0 ), @@ -271,81 +661,16 @@ function constructAnnuitySetup(api: ApiPromise) { return vaultAnnuity.concat(escrowAnnuity); } -async function constructAmmSetup(api: ApiPromise) { - const prices: Map = new Map(); - prices.set(JSON.stringify({ Token: "KBTC" }), 22842.91); - prices.set(JSON.stringify({ Token: "KSM" }), 36.05); - prices.set(JSON.stringify({ Token: "KINT" }), 0.982574); - prices.set(JSON.stringify({ ForeignAsset: 1 }), 1); // USDT - prices.set(JSON.stringify({ ForeignAsset: 2 }), 8.94); // MOVR - prices.set(JSON.stringify({ ForeignAsset: 6 }), 1536.51); // ETH - prices.set(JSON.stringify({ ForeignAsset: 7 }), 0.768930); // AUSD - prices.set(JSON.stringify({ ForeignAsset: 8 }), 0.208364); // KAR - - const decimals: Map = new Map(); - decimals.set(JSON.stringify({ Token: "KBTC" }), 8); - decimals.set(JSON.stringify({ Token: "KSM" }), 12); - decimals.set(JSON.stringify({ Token: "KINT" }), 12); - decimals.set(JSON.stringify({ ForeignAsset: 1 }), 6); // USDT - decimals.set(JSON.stringify({ ForeignAsset: 2 }), 18); // MOVR - decimals.set(JSON.stringify({ ForeignAsset: 6 }), 18); // ETH - decimals.set(JSON.stringify({ ForeignAsset: 7 }), 12); // AUSD - decimals.set(JSON.stringify({ ForeignAsset: 8 }), 12); // KAR - +async function constructAmmSetup(api: ApiPromise, genesis: ParachainGenesis) { // NOTE: ordering of tokens must comply with PartialOrd (for now) - const pools: [{ Token: any; } | { ForeignAsset: any; }, { Token: any; } | { ForeignAsset: any; }, number, number][] = [ - [ - { Token: "KSM" }, - { Token: "KBTC" }, - 45_000, - 500_000, // liquidity in usd - ], - [ - { Token: "KBTC" }, - { ForeignAsset: 1 }, // USDT - 40_000, - 400_000, // liquidity in usd - ], - [ - { Token: "KBTC" }, - { ForeignAsset: 2 }, // MOVR - 20_000, - 175_000, // liquidity in usd - ], - [ - { Token: "KINT" }, - { ForeignAsset: 2 }, // MOVR - 35_000, - 150_000, // liquidity in usd - ], - [ - { Token: "KBTC" }, - { ForeignAsset: 6 }, // ETH - 35_000, - 300_000, // liquidity in usd - ], - [ - { ForeignAsset: 1 }, // USDT - { ForeignAsset: 7 }, // AUSD - 5_000, - 70_000, // liquidity in usd - ], - [ - { ForeignAsset: 1 }, // MOVR - { ForeignAsset: 8 }, // KAR - 30_000, - 100_000, // liquidity in usd - ], - ]; - - const basicPoolSetup = pools.map(([token0, token1, reward, liquidity]) => { + const basicPoolSetup = genesis.pools.map(({ token0, token1, reward, liquidity }) => { // calculate liquidity amounts - let decimals0 = new BN(decimals.get(JSON.stringify(token0)) as number); - let price0 = prices.get(JSON.stringify(token0)) as number; + let decimals0 = new BN(decimals(token0, genesis) as number); + let price0 = genesis.prices.get(JSON.stringify(token0)) as number; let liquidity0 = new BN(liquidity / 2).mul(new BN(10).pow(decimals0)).divn(price0); - let decimals1 = new BN(decimals.get(JSON.stringify(token1)) as number); - let price1 = prices.get(JSON.stringify(token1)) as number; + let decimals1 = new BN(decimals(token1, genesis) as number); + let price1 = genesis.prices.get(JSON.stringify(token1)) as number; let liquidity1 = new BN(liquidity / 2).mul(new BN(10).pow(decimals1)).divn(price1); return [ @@ -353,7 +678,7 @@ async function constructAmmSetup(api: ApiPromise) { api.tx.dexGeneral.createPair(token0, token1, 30), api.tx.farming.updateRewardSchedule( { LpToken: [token0, token1] }, - { Token: "KINT" }, + genesis.nativeCurrency[0], 60 * 24 * 7 * 12, // three months, reward period is per minute new BN(10).pow(new BN(12)).muln(reward as any), ), @@ -375,124 +700,8 @@ async function constructAmmSetup(api: ApiPromise) { return basicPoolSetup; } -function constructForeignAssetSetup(api: ApiPromise) { - return [ - api.tx.assetRegistry.registerAsset( - { - decimals: 6, - name: "Tether USD", - symbol: "USDT", - existentialDeposit: 0, - location: null, - additional: { feePerSecond: 8153838, coingeckoId: "tether" } - }, - 1 - ), api.tx.assetRegistry.registerAsset( - { - decimals: 18, - name: "Moonriver Token", - symbol: "MOVR", - existentialDeposit: 0, - location: null, - additional: { feePerSecond: 0, coingeckoId: "moonriver" } - }, - 2 - ), api.tx.assetRegistry.registerAsset( - { - decimals: 12, - name: "Liquid KSM", - symbol: "LKSM", - existentialDeposit: 0, - location: { - V3: { - parents: 1, - interior: { - X2: [ - { - Parachain: 2000 - }, - { - GeneralKey: { - length: 2, - data: "0x0083000000000000000000000000000000000000000000000000000000000000" - } - } - ] - } - } - }, - additional: { feePerSecond: 233100000000, coingeckoId: "liquid-ksm" } - }, - 3 - ), api.tx.assetRegistry.registerAsset( - { - decimals: 12, - name: "Voucher KSM", - symbol: "VKSM", - existentialDeposit: 0, - location: { - V3: { - parents: 1, - interior: { - X2: [ - { - Parachain: 2001 - }, - { - GeneralKey: { - length: 2, - data: "0x0104000000000000000000000000000000000000000000000000000000000000" - } - } - ] - } - } - }, - additional: { feePerSecond: 233100000000, coingeckoId: "voucher-ksm" } - }, - 4 - ), api.tx.assetRegistry.registerAsset( - { - decimals: 12, - name: "Staked KSM", - symbol: "SKSM", - existentialDeposit: 0, - location: null, - additional: { feePerSecond: 233100000000, coingeckoId: "" } - }, - 5 - ), api.tx.assetRegistry.registerAsset( - { - decimals: 18, - name: "Ethereum", - symbol: "ETH", - existentialDeposit: 0, - location: null, - additional: { feePerSecond: 0, coingeckoId: "ethereum" } - }, - 6 - ), api.tx.assetRegistry.registerAsset( - { - decimals: 12, - name: "Acala Dollar", - symbol: "AUSD", - existentialDeposit: 0, - location: null, - additional: { feePerSecond: 0, coingeckoId: "acala-dollar" } - }, - 7 - ), api.tx.assetRegistry.registerAsset( - { - decimals: 12, - name: "Karura", - symbol: "KAR", - existentialDeposit: 0, - location: null, - additional: { feePerSecond: 0, coingeckoId: "karura" } - }, - 8 - ) - ]; +function constructForeignAssetSetup(api: ApiPromise, genesis: ParachainGenesis) { + return genesis.foreignAssets.map((metadata, i) => api.tx.assetRegistry.registerAsset(metadata, i + 1)); } async function constructClientsInfoSetup(api: ApiPromise, baseUrl: String) { @@ -504,7 +713,7 @@ async function constructClientsInfoSetup(api: ApiPromise, baseUrl: String) { return res.text(); }); - const re = /([a-f0-9]+)\s*[.]\/(([a-z]+)-parachain-metadata-kintsugi)/g; + const re = new RegExp("([a-f0-9]+)\\s*[.]\/(([a-z]+)-parachain-metadata-" + args['parachain-runtime'] + ")\\n", "g"); let matches = [] let match; while ((match = re.exec(checksumFile)) !== null) { @@ -529,17 +738,17 @@ function toUrl(extrinsic: SubmittableExtrinsic<"promise">, endpoint: string) { extrinsic.method.toHex(); } -async function setupParachain() { +async function setupParachain(genesis: ParachainGenesis) { const paraApi = await createSubstrateAPI(args['parachain-endpoint']); let calls = [ await constructClientsInfoSetup(paraApi, args["clients-url"]), - constructForeignAssetSetup(paraApi), - constructFundingSetup(paraApi), - constructLendingSetup(paraApi), - constructVaultRegistrySetup(paraApi), - constructAnnuitySetup(paraApi), - await constructAmmSetup(paraApi), + constructForeignAssetSetup(paraApi, genesis), + constructFundingSetup(paraApi, genesis), + constructLendingSetup(paraApi, genesis), + constructVaultRegistrySetup(paraApi, genesis), + constructAnnuitySetup(paraApi, genesis), + await constructAmmSetup(paraApi, genesis), ].flat(); const batched = paraApi.tx.utility.batchAll(calls); @@ -557,15 +766,18 @@ async function main(): Promise { await cryptoWaitReady(); - switch (args['with-defaults-of']) { - case 'testnet-kintsugi': + switch (args['parachain-runtime']) { + case 'kintsugi': if (args['parachain-endpoint'] === undefined) { args['parachain-endpoint'] = "wss://api-dev-kintsugi.interlay.io/parachain"; } - break; + return setupParachain(KINTSUGI_GENESIS); + case 'interlay': + if (args['parachain-endpoint'] === undefined) { + args['parachain-endpoint'] = "wss://api-testnet.interlay.io/parachain"; + } + return setupParachain(INTERLAY_GENESIS); } - - await setupParachain(); } From fe8f86b77d3cf55cd5380dbc53769533f690eff5 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Mon, 12 Jun 2023 10:23:20 +0200 Subject: [PATCH 30/35] chore: remove qToken vaults from init (by request of peter) --- scripts/init-testnet.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 6f2447dd3..bebb2706e 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -515,22 +515,6 @@ const INTERLAY_GENESIS: ParachainGenesis = { secureCollateral: "1550000000000000000", minimumCollateral: "150000000", systemCollateralCeiling: "200000000000", - }, - { - collateralCurrency: { LendToken: 2 }, // qDOT - liquidationCollateral: "1250000000000000000", - premiumRedeem: "1400000000000000000", - secureCollateral: "1550000000000000000", - minimumCollateral: "300000000000", - systemCollateralCeiling: "24500000000000000", - }, - { - collateralCurrency: { LendToken: 3 }, // qUSDT - liquidationCollateral: "1350000000000000000", - premiumRedeem: "1450000000000000000", - secureCollateral: "1550000000000000000", - minimumCollateral: "150000000", - systemCollateralCeiling: "200000000000", } ], } From 77d8fab673e7dbece2a1c3917e9750ea36aad4d5 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Tue, 20 Jun 2023 13:12:50 +0200 Subject: [PATCH 31/35] fix: use 10 decimals for intr rewards --- scripts/init-testnet.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index bebb2706e..51dff6683 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -664,7 +664,7 @@ async function constructAmmSetup(api: ApiPromise, genesis: ParachainGenesis) { { LpToken: [token0, token1] }, genesis.nativeCurrency[0], 60 * 24 * 7 * 12, // three months, reward period is per minute - new BN(10).pow(new BN(12)).muln(reward as any), + new BN(10).pow(new BN(genesis.nativeCurrency[1])).muln(reward as any), ), api.tx.utility.dispatchAs( { system: { Signed: treasuryAccount } }, From 7cf4e6e2b3be2e6fdb9b787b653a6a7f35370bd2 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Tue, 20 Jun 2023 13:14:50 +0200 Subject: [PATCH 32/35] fix: interlay dex pools + rewards --- scripts/init-testnet.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 51dff6683..be6414647 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -491,20 +491,20 @@ const INTERLAY_GENESIS: ParachainGenesis = { { token0: { Token: "IBTC" }, token1: { Token: "DOT" }, - reward: 4_000_000, - liquidity: 1_200_000, + reward: 2_000_000, + liquidity: 400_000, }, { token0: { Token: "IBTC" }, token1: { ForeignAsset: 2 }, // USDT reward: 3_800_000, - liquidity: 2_000_000, + liquidity: 1_000_000, }, { - token0: { Token: "DOT" }, - token1: { Token: "INTR" }, - reward: 3_500_000, - liquidity: 500_000, + token0: { Token: "INTR" }, + token1: { ForeignAsset: 2 }, // USDT + reward: 2_000_000, + liquidity: 200_000, }, ], vaultParams: [ From 23e43713ffa17b86d4d4698d61959ab0d83707ac Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Tue, 20 Jun 2023 13:17:40 +0200 Subject: [PATCH 33/35] fix: disable swap fees on interlay, set to 15 on kintsugi --- scripts/init-testnet.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index be6414647..9a8e6cde0 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -77,6 +77,7 @@ type ParachainGenesis = { reward: number, liquidity: number, }[], + dexFees: number, vaultParams: { collateralCurrency: Currency, liquidationCollateral: string, @@ -367,6 +368,7 @@ const KINTSUGI_GENESIS: ParachainGenesis = { liquidity: 100_000, // liquidity in usd }, ], + dexFees: 15, vaultParams: [ { collateralCurrency: { ForeignAsset: 3 }, // LKSM @@ -507,6 +509,7 @@ const INTERLAY_GENESIS: ParachainGenesis = { liquidity: 200_000, }, ], + dexFees: 0, vaultParams: [ { collateralCurrency: { ForeignAsset: 2 }, // USDT @@ -659,7 +662,7 @@ async function constructAmmSetup(api: ApiPromise, genesis: ParachainGenesis) { return [ // @ts-ignore - api.tx.dexGeneral.createPair(token0, token1, 30), + api.tx.dexGeneral.createPair(token0, token1, genesis.dexFees), api.tx.farming.updateRewardSchedule( { LpToken: [token0, token1] }, genesis.nativeCurrency[0], From 75e4cf80afbc6b308234b096b7c37544da31100b Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Tue, 20 Jun 2023 13:44:19 +0200 Subject: [PATCH 34/35] fix: lending supply incentives --- scripts/init-testnet.ts | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 9a8e6cde0..7d77f8548 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -68,6 +68,7 @@ type ParachainGenesis = { supplyCap?: any; borrowCap?: any; lendTokenId?: any; + supplyIncentivesPerBlock: number, } ][], prices: Map, @@ -232,7 +233,8 @@ const KINTSUGI_GENESIS: ParachainGenesis = { // 100 KBTC. Mainnet will be only 20 KBTC. supplyCap: "10000000000", borrowCap: "10000000000", - lendTokenId: { LendToken: 1 } + lendTokenId: { LendToken: 1 }, + supplyIncentivesPerBlock: 0 } ], [ @@ -258,7 +260,8 @@ const KINTSUGI_GENESIS: ParachainGenesis = { // 30,000 KSM supplyCap: "30000000000000000", borrowCap: "30000000000000000", - lendTokenId: { LendToken: 2 } + lendTokenId: { LendToken: 2 }, + supplyIncentivesPerBlock: 0 } ], [ @@ -284,7 +287,8 @@ const KINTSUGI_GENESIS: ParachainGenesis = { // 800,000 USDT supplyCap: "800000000000", borrowCap: "800000000000", - lendTokenId: { LendToken: 3 } + lendTokenId: { LendToken: 3 }, + supplyIncentivesPerBlock: 0 } ], [ @@ -310,7 +314,8 @@ const KINTSUGI_GENESIS: ParachainGenesis = { // 10,000 MOVR supplyCap: "10000000000000000000000", borrowCap: "10000000000000000000000", - lendTokenId: { LendToken: 4 } + lendTokenId: { LendToken: 4 }, + supplyIncentivesPerBlock: 0 } ], ], @@ -427,7 +432,8 @@ const INTERLAY_GENESIS: ParachainGenesis = { // 100 IBTC. Mainnet will be only 30 IBTC. supplyCap: "10000000000", borrowCap: "10000000000", - lendTokenId: { LendToken: 1 } + lendTokenId: { LendToken: 1 }, + supplyIncentivesPerBlock: 0 } ], [ @@ -453,7 +459,8 @@ const INTERLAY_GENESIS: ParachainGenesis = { // 1,000,000 DOT supplyCap: "10000000000000000", borrowCap: "10000000000000000", - lendTokenId: { LendToken: 2 } + lendTokenId: { LendToken: 2 }, + supplyIncentivesPerBlock: 7440476190 } ], [ @@ -479,7 +486,8 @@ const INTERLAY_GENESIS: ParachainGenesis = { // 600,000 USDT supplyCap: "600000000000", borrowCap: "600000000000", - lendTokenId: { LendToken: 3 } + lendTokenId: { LendToken: 3 }, + supplyIncentivesPerBlock: 3472222222 } ], ], @@ -535,10 +543,15 @@ function constructLendingSetup(api: ApiPromise, genesis: ParachainGenesis) { // ) // ]; - const activateMarketWithRewards = genesis.markets.map(([token, _]) => { + const activateMarketWithRewards = genesis.markets.map(([token, market]) => { return [ api.tx.loans.activateMarket(token), - // api.tx.loans.updateMarketRewardSpeed(token, 10, 10), // no incentives + api.tx.loans.updateMarketRewardSpeed(token, market.supplyIncentivesPerBlock, 0), + api.tx.utility.dispatchAs( + { system: { Signed: treasuryAccount } }, + // add one year's worth. Plus one so that the 0 case doesn't error + api.tx.loans.addReward(new BN(market.supplyIncentivesPerBlock).muln(5*60*24*365).addn(1)) + ) ] }).flat(); From 1372eaf45db4d885e26271585cc329196ddbadbc Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Wed, 28 Jun 2023 10:11:08 +0200 Subject: [PATCH 35/35] fix: testnet config & bugfix --- scripts/init-testnet.ts | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/scripts/init-testnet.ts b/scripts/init-testnet.ts index 7d77f8548..ee7e115c7 100644 --- a/scripts/init-testnet.ts +++ b/scripts/init-testnet.ts @@ -389,7 +389,7 @@ const KINTSUGI_GENESIS: ParachainGenesis = { const INTERLAY_GENESIS: ParachainGenesis = { relayChainCurrency: [{ Token: "DOT" }, 10], wrappedCurrency: [{ Token: "IBTC" }, 8], - nativeCurrency: [{ Token: "INTR" }, 8], + nativeCurrency: [{ Token: "INTR" }, 10], foreignAssets: [ { decimals: 10, @@ -419,7 +419,7 @@ const INTERLAY_GENESIS: ParachainGenesis = { reserveFactor: 100000, closeFactor: 500000, liquidateIncentive: "1100000000000000000", - liquidateIncentiveReservedFactor: 25000, + liquidateIncentiveReservedFactor: 0, rateModel: { Jump: { baseRate: 0, @@ -430,8 +430,8 @@ const INTERLAY_GENESIS: ParachainGenesis = { }, state: "Pending", // 100 IBTC. Mainnet will be only 30 IBTC. - supplyCap: "10000000000", - borrowCap: "10000000000", + supplyCap: "3000000000", + borrowCap: "3000000000", lendTokenId: { LendToken: 1 }, supplyIncentivesPerBlock: 0 } @@ -446,7 +446,7 @@ const INTERLAY_GENESIS: ParachainGenesis = { reserveFactor: 100000, closeFactor: 500000, liquidateIncentive: "1100000000000000000", - liquidateIncentiveReservedFactor: 25000, + liquidateIncentiveReservedFactor: 0, rateModel: { Jump: { baseRate: "50000000000000000", @@ -460,7 +460,7 @@ const INTERLAY_GENESIS: ParachainGenesis = { supplyCap: "10000000000000000", borrowCap: "10000000000000000", lendTokenId: { LendToken: 2 }, - supplyIncentivesPerBlock: 7440476190 + supplyIncentivesPerBlock: 6793478260 } ], [ @@ -473,7 +473,7 @@ const INTERLAY_GENESIS: ParachainGenesis = { reserveFactor: 100000, closeFactor: 500000, liquidateIncentive: "1100000000000000000", - liquidateIncentiveReservedFactor: 25000, + liquidateIncentiveReservedFactor: 0, rateModel: { Jump: { baseRate: 0, @@ -487,7 +487,7 @@ const INTERLAY_GENESIS: ParachainGenesis = { supplyCap: "600000000000", borrowCap: "600000000000", lendTokenId: { LendToken: 3 }, - supplyIncentivesPerBlock: 3472222222 + supplyIncentivesPerBlock: 3170289855 } ], ], @@ -544,15 +544,22 @@ function constructLendingSetup(api: ApiPromise, genesis: ParachainGenesis) { // ]; const activateMarketWithRewards = genesis.markets.map(([token, market]) => { - return [ - api.tx.loans.activateMarket(token), + const activate = [api.tx.loans.activateMarket(token)]; + const threeMonths = 5*60*24*92; // 92 days + const setRewards = market.supplyIncentivesPerBlock === 0 ? [] : [ api.tx.loans.updateMarketRewardSpeed(token, market.supplyIncentivesPerBlock, 0), + // add 12 weeks worth api.tx.utility.dispatchAs( { system: { Signed: treasuryAccount } }, - // add one year's worth. Plus one so that the 0 case doesn't error - api.tx.loans.addReward(new BN(market.supplyIncentivesPerBlock).muln(5*60*24*365).addn(1)) - ) - ] + api.tx.loans.addReward(new BN(market.supplyIncentivesPerBlock).muln(threeMonths)) + ), + // stop in 12 weeks + api.tx.scheduler.scheduleAfter(threeMonths - 1, null, 32, api.tx.loans.updateMarketRewardSpeed(token, 0, 0)), + ]; + return [ + activate, + setRewards + ].flat(); }).flat(); const addSupply = genesis.markets.map(([token, market]) => { @@ -679,7 +686,7 @@ async function constructAmmSetup(api: ApiPromise, genesis: ParachainGenesis) { api.tx.farming.updateRewardSchedule( { LpToken: [token0, token1] }, genesis.nativeCurrency[0], - 60 * 24 * 7 * 12, // three months, reward period is per minute + 60 * 24 * 92, // 92 days, reward period is per minute new BN(10).pow(new BN(genesis.nativeCurrency[1])).muln(reward as any), ), api.tx.utility.dispatchAs(