diff --git a/test/helpers/block.ts b/test/helpers/block.ts index 4b052d860f..354662c76f 100644 --- a/test/helpers/block.ts +++ b/test/helpers/block.ts @@ -4,7 +4,6 @@ import { type BlockRangeOption, EXTRINSIC_BASE_WEIGHT, WEIGHT_PER_GAS, - calculateFeePortions, mapExtrinsics, } from "@moonwall/util"; import type { ApiPromise } from "@polkadot/api"; @@ -17,6 +16,8 @@ import type { AccountId20, Block } from "@polkadot/types/interfaces/runtime/type import chalk from "chalk"; import type { Debugger } from "debug"; import Debug from "debug"; +import { calculateFeePortions, split } from "./fees.ts"; +import { getFeesTreasuryProportion } from "./parameters.ts"; const debug = Debug("test:blocks"); @@ -149,6 +150,8 @@ export const verifyBlockFees = async ( ? (event.data[0] as DispatchInfo) : (event.data[1] as DispatchInfo); + const feesTreasuryProportion = await getFeesTreasuryProportion(context); + // We are only interested in fee paying extrinsics: // Either ethereum transactions or signed extrinsics with fees (substrate tx) if ( @@ -191,24 +194,29 @@ export const verifyBlockFees = async ( effectiveTipPerGas = 0n; } - // Calculate the fees paid for base fee independently from tip fee. Both are subject - // to 80/20 split (burn/treasury) but calculating these over the sum of the two + // Calculate the fees paid for base fee independently of tip fee. Both are subject + // to split between (burn/treasury) but calculating these over the sum of the two // rather than independently leads to off-by-one errors. const baseFeesPaid = gasUsed * baseFeePerGas; const tipAsFeesPaid = gasUsed * effectiveTipPerGas; - // TODO: [calculateFeePortions] needs to be updated. - const baseFeePortions = calculateFeePortions(baseFeesPaid); - // we send tips to collator - // const tipFeePortions = calculateFeePortions(tipAsFeesPaid); + const { burnt: baseFeePortionsBurnt } = calculateFeePortions( + feesTreasuryProportion, + baseFeesPaid + ); txFees += baseFeesPaid + tipAsFeesPaid; - txBurnt += baseFeePortions.burnt; - // txBurnt += tipFeePortions.burnt; + txBurnt += baseFeePortionsBurnt; } else { // For a regular substrate tx, we use the partialFee - const feePortions = calculateFeePortions(fee.partialFee.toBigInt()); - const tipPortions = calculateFeePortions(extrinsic.tip.toBigInt()); + const feePortions = calculateFeePortions( + feesTreasuryProportion, + fee.partialFee.toBigInt() + ); + const tipPortions = calculateFeePortions( + extrinsic.tip.toBigInt(), + feesTreasuryProportion + ); txFees += fee.partialFee.toBigInt() + extrinsic.tip.toBigInt(); txBurnt += feePortions.burnt + tipPortions.burnt; diff --git a/test/helpers/fees.ts b/test/helpers/fees.ts new file mode 100644 index 0000000000..2b832c77d9 --- /dev/null +++ b/test/helpers/fees.ts @@ -0,0 +1,31 @@ +import { BN } from "@polkadot/util"; + +/// Recreation of fees.ration(burn_part, treasury_part) +export const split = (value: BN, part1: BN, part2: BN): [BN, BN] => { + const total = part1.add(part2); + if (total.eq(new BN(0)) || value.eq(new BN(0))) { + return [new BN(0), new BN(0)]; + } + const part1BN = value.mul(part1).div(total); + const part2BN = value.sub(part1BN); + return [part1BN, part2BN]; +}; + +export const calculateFeePortions = ( + feesTreasuryProportion: bigint, + fees: bigint +): { + burnt: bigint; + treasury: bigint; +} => { + const feesBN = new BN(fees.toString()); + const treasuryPartBN = new BN(feesTreasuryProportion.toString()); + const burntPartBN = new BN(1e9).sub(treasuryPartBN); + + const [burntBN, treasuryBN] = split(feesBN, burntPartBN, treasuryPartBN); + + return { + burnt: BigInt(burntBN.toString()), + treasury: BigInt(treasuryBN.toString()), + }; +}; diff --git a/test/helpers/index.ts b/test/helpers/index.ts index 3c64aadda8..71efcf002a 100644 --- a/test/helpers/index.ts +++ b/test/helpers/index.ts @@ -24,3 +24,5 @@ export * from "./voting"; export * from "./wormhole"; export * from "./xcm"; export * from "./tracingFns"; +export * from "./fees.ts"; +export * from "./parameters.ts"; diff --git a/test/helpers/parameters.ts b/test/helpers/parameters.ts new file mode 100644 index 0000000000..1bdb6d0c5c --- /dev/null +++ b/test/helpers/parameters.ts @@ -0,0 +1,14 @@ +import type { DevModeContext } from "@moonwall/cli"; + +export const getFeesTreasuryProportion = async (context: DevModeContext): Promise => { + const parameter = await context.polkadotJs().query.parameters.parameters({ + RuntimeConfig: "FeesTreasuryProportion", + }); + + // 20% default value + let feesTreasuryProportion = 200_000_000n; + if (parameter.isSome) { + feesTreasuryProportion = parameter.value.asRuntimeConfig.asFeesTreasuryProportion.toBigInt(); + } + return feesTreasuryProportion; +}; diff --git a/test/suites/dev/moonbase/test-parameters/test-parameters-runtime-FeesTreasuryProportion.ts b/test/suites/dev/moonbase/test-parameters/test-parameters-runtime-FeesTreasuryProportion.ts index 6328406e05..1629dc8d97 100644 --- a/test/suites/dev/moonbase/test-parameters/test-parameters-runtime-FeesTreasuryProportion.ts +++ b/test/suites/dev/moonbase/test-parameters/test-parameters-runtime-FeesTreasuryProportion.ts @@ -10,6 +10,7 @@ import { } from "@moonwall/util"; import { parameterType, UNIT } from "./test-parameters"; import { BN } from "@polkadot/util"; +import { calculateFeePortions } from "../../../../helpers"; interface TestCase { proportion: Perbill; @@ -18,17 +19,6 @@ interface TestCase { tipAmount: bigint; } -// Recreation on fees.ration(burn_part, treasury_part) -const split = (value: BN, part1: BN, part2: BN): [BN, BN] => { - const total = part1.add(part2); - if (total.eq(new BN(0)) || value.eq(new BN(0))) { - return [new BN(0), new BN(0)]; - } - const part1BN = value.mul(part1).div(total); - const part2BN = value.sub(part1BN); - return [part1BN, part2BN]; -}; - describeSuite({ id: "DTemp03", title: "Parameters - RuntimeConfig", @@ -80,10 +70,9 @@ describeSuite({ ]; for (const t of testCases) { - const burnProportion = new Perbill(new BN(1e9).sub(t.proportion.value())); - + const treasuryPerbill = new BN(1e9).sub(t.proportion.value()); const treasuryPercentage = t.proportion.value().toNumber() / 1e7; - const burnPercentage = burnProportion.value().toNumber() / 1e7; + const burnPercentage = 100 - treasuryPercentage; const calcTreasuryIncrease = (feeWithTip: bigint, tip?: bigint): bigint => { const issuanceDecrease = calcIssuanceDecrease(feeWithTip, tip); @@ -92,13 +81,9 @@ describeSuite({ }; const calcIssuanceDecrease = (feeWithTip: bigint, tip?: bigint): bigint => { const feeWithTipBN = new BN(feeWithTip.toString()); - const [burnFeeWithTipPart, _treasuryFeeWithTipPart] = split( - feeWithTipBN, - burnProportion.value(), - t.proportion.value() - ); + const { burnt } = calculateFeePortions(treasuryPerbill, feeWithTipBN); - return BigInt(burnFeeWithTipPart.toString()); + return BigInt(burnt.toString()); }; for (const txnType of TransactionTypes) {