From 003861a7b9370954e851aca3e0eb39db9ed0363c Mon Sep 17 00:00:00 2001 From: 0xPatrick Date: Fri, 17 Jan 2025 14:43:23 -0500 Subject: [PATCH] chore: remove `maxVariable` from `FeeConfig` --- .../fast-usdc/snapshots/fast-usdc.test.ts.md | 4 -- .../snapshots/fast-usdc.test.ts.snap | Bin 3399 -> 3363 bytes .../fast-usdc/start-fast-usdc.build.js | 5 +- packages/fast-usdc/src/type-guards.js | 1 - packages/fast-usdc/src/types.ts | 4 +- packages/fast-usdc/src/utils/fees.js | 7 +-- .../fast-usdc/test/config-marshal.test.js | 2 - packages/fast-usdc/test/exos/advancer.test.ts | 2 +- packages/fast-usdc/test/mocks.ts | 1 - packages/fast-usdc/test/utils/fees.test.ts | 56 ++---------------- 10 files changed, 13 insertions(+), 69 deletions(-) diff --git a/packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.md b/packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.md index b223719d6ec..99dc6e9c685 100644 --- a/packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.md +++ b/packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.md @@ -114,10 +114,6 @@ Generated by [AVA](https://avajs.dev). brand: Object @Alleged: USDC brand {}, value: 10000n, }, - maxVariable: { - brand: Object @Alleged: USDC brand {}, - value: 5000000n, - }, variableRate: { denominator: { brand: Object @Alleged: USDC brand {}, diff --git a/packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.snap b/packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.snap index 48697d3e3c23878c14b6d7c15b43ea3e01505438..fa6abe6d012b4a334b4fd9d82945248bb40d64e7 100644 GIT binary patch literal 3363 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 literal 3399 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 { /** @param {string} numeral */ const toRatio = numeral => parseRatio(numeral, USDC); const parseFeeConfigArgs = () => { - const { flatFee, variableRate, maxVariableFee, contractRate } = fees; + const { flatFee, variableRate, contractRate } = fees; return { flat: toAmount(flatFee), variableRate: toRatio(variableRate), - maxVariable: toAmount(maxVariableFee), contractRate: toRatio(contractRate), }; }; diff --git a/packages/fast-usdc/src/type-guards.js b/packages/fast-usdc/src/type-guards.js index 82f801044c2..3bc2a3c2a49 100644 --- a/packages/fast-usdc/src/type-guards.js +++ b/packages/fast-usdc/src/type-guards.js @@ -113,7 +113,6 @@ const NatAmountShape = { brand: BrandShape, value: M.nat() }; export const FeeConfigShape = { flat: NatAmountShape, variableRate: RatioShape, - maxVariable: NatAmountShape, contractRate: RatioShape, }; harden(FeeConfigShape); diff --git a/packages/fast-usdc/src/types.ts b/packages/fast-usdc/src/types.ts index bc9bf5cd4ca..7af6768366a 100644 --- a/packages/fast-usdc/src/types.ts +++ b/packages/fast-usdc/src/types.ts @@ -62,9 +62,11 @@ export interface PendingTx extends CctpTxEvidence { } export type FeeConfig = { + /** flat fee charged for every advance */ flat: Amount<'nat'>; + /** proportion of advance kept as a fee */ variableRate: Ratio; - maxVariable: Amount<'nat'>; + /** proportion of fees that goes to the contract (remaining goes to LPs) */ contractRate: Ratio; }; diff --git a/packages/fast-usdc/src/utils/fees.js b/packages/fast-usdc/src/utils/fees.js index 08b14c81991..a38a8f4ab3a 100644 --- a/packages/fast-usdc/src/utils/fees.js +++ b/packages/fast-usdc/src/utils/fees.js @@ -4,7 +4,7 @@ import { Fail } from '@endo/errors'; import { mustMatch } from '@endo/patterns'; import { FeeConfigShape } from '../type-guards.js'; -const { add, isGTE, min, subtract } = AmountMath; +const { add, isGTE, subtract } = AmountMath; /** * @import {Amount} from '@agoric/ertp'; @@ -15,7 +15,7 @@ const { add, isGTE, min, subtract } = AmountMath; /** @param {FeeConfig} feeConfig */ export const makeFeeTools = feeConfig => { mustMatch(feeConfig, FeeConfigShape, 'Must provide feeConfig'); - const { flat, variableRate, maxVariable } = feeConfig; + const { flat, variableRate } = feeConfig; const feeTools = harden({ /** * Calculate the net amount to advance after withholding fees. @@ -34,8 +34,7 @@ export const makeFeeTools = feeConfig => { * @throws {Error} if requested does not exceed fees */ calculateAdvanceFee(requested) { - const variable = min(multiplyBy(requested, variableRate), maxVariable); - const fee = add(variable, flat); + const fee = add(multiplyBy(requested, variableRate), flat); !isGTE(fee, requested) || Fail`Request must exceed fees.`; return fee; }, diff --git a/packages/fast-usdc/test/config-marshal.test.js b/packages/fast-usdc/test/config-marshal.test.js index 37909e9d852..682c0166644 100644 --- a/packages/fast-usdc/test/config-marshal.test.js +++ b/packages/fast-usdc/test/config-marshal.test.js @@ -29,7 +29,6 @@ test('cross-vat configuration of Fast USDC FeeConfig', t => { const config = harden({ flat: make(USDC, 100n), variableRate: makeRatio(1n, USDC), - maxVariable: make(USDC, 100_000n), contractRate: makeRatio(20n, USDC), }); testMatches(t, config, FeeConfigShape); @@ -51,7 +50,6 @@ test('cross-vat configuration of Fast USDC FeeConfig', t => { }, }, flat: { brand: '$0', value: '+100' }, - maxVariable: { brand: '$0', value: '+100000' }, variableRate: { denominator: { brand: '$0', diff --git a/packages/fast-usdc/test/exos/advancer.test.ts b/packages/fast-usdc/test/exos/advancer.test.ts index b86ca9e6a13..ce6f8448793 100644 --- a/packages/fast-usdc/test/exos/advancer.test.ts +++ b/packages/fast-usdc/test/exos/advancer.test.ts @@ -298,7 +298,7 @@ test('updates status to OBSERVED on insufficient pool funds', async t => { [ 'Advancer error:', Error( - `Cannot borrow. Requested ${q(usdc.make(294999999n))} must be less than pool balance ${q(usdc.make(1n))}.`, + `Cannot borrow. Requested ${q(usdc.make(293999999n))} must be less than pool balance ${q(usdc.make(1n))}.`, ), ], ]); diff --git a/packages/fast-usdc/test/mocks.ts b/packages/fast-usdc/test/mocks.ts index 05af9ab6273..f4c4ed6ae2d 100644 --- a/packages/fast-usdc/test/mocks.ts +++ b/packages/fast-usdc/test/mocks.ts @@ -89,6 +89,5 @@ export const makeTestFeeConfig = (usdc: Omit): FeeConfig => harden({ flat: usdc.make(1n), variableRate: makeRatio(2n, usdc.brand), - maxVariable: usdc.units(5), contractRate: makeRatio(20n, usdc.brand), }); diff --git a/packages/fast-usdc/test/utils/fees.test.ts b/packages/fast-usdc/test/utils/fees.test.ts index a544b69eef2..36eeb48d013 100644 --- a/packages/fast-usdc/test/utils/fees.test.ts +++ b/packages/fast-usdc/test/utils/fees.test.ts @@ -22,7 +22,6 @@ const USDCRatio = (numerator: bigint, denominator: bigint = 100n) => const aFeeConfig: FeeConfig = { flat: USDC(10n), variableRate: USDCRatio(2n), - maxVariable: USDC(100n), contractRate: USDCRatio(20n), }; harden(aFeeConfig); @@ -69,32 +68,6 @@ const feeToolsScenario = test.macro({ }, }); -test(feeToolsScenario, { - name: 'below max variable fee', - requested: USDC(1000n), - expected: { - totalFee: USDC(30n), // 10 flat + 20 variable - advance: USDC(970n), - split: { - ContractFee: USDC(6n), - PoolFee: USDC(24n), - }, - }, -}); - -test(feeToolsScenario, { - name: 'above max variable fee', - requested: USDC(10000n), - expected: { - totalFee: USDC(110n), // 10 flat + 100 max - advance: USDC(9890n), - split: { - ContractFee: USDC(22n), - PoolFee: USDC(88n), - }, - }, -}); - test(feeToolsScenario, { name: 'zero variable fee', requested: USDC(1000n), @@ -147,25 +120,6 @@ test(feeToolsScenario, { }, }); -test(feeToolsScenario, { - // TODO consider behavior where 0 or undefined means "no fee cap" - name: 'only flat is charged if `maxVariable: 0`', - requested: USDC(10000n), - config: { - ...aFeeConfig, - variableRate: USDCRatio(20n), - maxVariable: USDC(0n), - }, - expected: { - totalFee: USDC(10n), // only flat - advance: USDC(9990n), - split: { - ContractFee: USDC(2n), - PoolFee: USDC(8n), - }, - }, -}); - test(feeToolsScenario, { name: 'AGORIC_PLUS_OSMO with commonPrivateArgs.feeConfig', // 150_000_000n @@ -173,7 +127,7 @@ test(feeToolsScenario, { // same as commonPrivateArgs.feeConfig from `CommonSetup` config: makeTestFeeConfig(withAmountUtils(issuerKits.USDC)), expected: { - totalFee: USDC(3000001n), // 1n + min(2% of 150USDC, 5USDC) + totalFee: USDC(3000001n), // 1n + 2% of 150USDC advance: USDC(146999999n), split: { ContractFee: USDC(600000n), // 20% of fee @@ -189,11 +143,11 @@ test(feeToolsScenario, { // same as commonPrivateArgs.feeConfig from `CommonSetup` config: makeTestFeeConfig(withAmountUtils(issuerKits.USDC)), expected: { - totalFee: USDC(5000001n), // 1n + min(2% of 300USDC, 5USDC) - advance: USDC(294999999n), + totalFee: USDC(6000001n), // 1n + 2% of 300USDC + advance: USDC(293999999n), split: { - ContractFee: USDC(1000000n), // 20% of fee - PoolFee: USDC(4000001n), + ContractFee: USDC(1200000n), // 20% of fee + PoolFee: USDC(4800001n), }, }, });