From f501bfaf618dde9d7e19c02a9ad580aab3757a45 Mon Sep 17 00:00:00 2001 From: bathord Date: Fri, 27 Jun 2025 21:34:55 +0300 Subject: [PATCH 1/3] Add historical fees fields to Wrapper & upd join funs --- .../deepbook-wrapper/sources/wrapper.move | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/packages/deepbook-wrapper/sources/wrapper.move b/packages/deepbook-wrapper/sources/wrapper.move index fe885a2a..594c579c 100644 --- a/packages/deepbook-wrapper/sources/wrapper.move +++ b/packages/deepbook-wrapper/sources/wrapper.move @@ -24,6 +24,8 @@ public struct Wrapper has key, store { deep_reserves: Balance, deep_reserves_coverage_fees: Bag, protocol_fees: Bag, + historical_coverage_fees: Bag, + historical_protocol_fees: Bag, } /// Capability for managing funds in the wrapper @@ -108,34 +110,56 @@ public(package) fun join_deep_reserves_coverage_fee( wrapper: &mut Wrapper, fee: Balance, ) { - if (fee.value() == 0) { + let fee_amount = fee.value(); + if (fee_amount == 0) { fee.destroy_zero(); return }; let key = ChargedFeeKey { dummy_field: false }; + + // Update current fees if (wrapper.deep_reserves_coverage_fees.contains(key)) { let balance = wrapper.deep_reserves_coverage_fees.borrow_mut(key); balance::join(balance, fee); } else { wrapper.deep_reserves_coverage_fees.add(key, fee); }; + + // Update historical total + if (wrapper.historical_coverage_fees.contains(key)) { + let current_total = wrapper.historical_coverage_fees.borrow_mut(key); + *current_total = *current_total + (fee_amount as u128); + } else { + wrapper.historical_coverage_fees.add(key, fee_amount as u128); + }; } /// Add collected protocol fees to the wrapper's fee storage public(package) fun join_protocol_fee(wrapper: &mut Wrapper, fee: Balance) { - if (fee.value() == 0) { + let fee_amount = fee.value(); + if (fee_amount == 0) { fee.destroy_zero(); return }; let key = ChargedFeeKey { dummy_field: false }; + + // Update current fees if (wrapper.protocol_fees.contains(key)) { let balance = wrapper.protocol_fees.borrow_mut(key); balance::join(balance, fee); } else { wrapper.protocol_fees.add(key, fee); }; + + // Update historical total + if (wrapper.historical_protocol_fees.contains(key)) { + let current_total = wrapper.historical_protocol_fees.borrow_mut(key); + *current_total = *current_total + (fee_amount as u128); + } else { + wrapper.historical_protocol_fees.add(key, fee_amount as u128); + }; } /// Get the splitted DEEP coin from the reserves @@ -158,6 +182,8 @@ fun init(ctx: &mut TxContext) { deep_reserves: balance::zero(), deep_reserves_coverage_fees: bag::new(ctx), protocol_fees: bag::new(ctx), + historical_coverage_fees: bag::new(ctx), + historical_protocol_fees: bag::new(ctx), }; // Create a fund capability for the deployer From 30253a1790421ae8912f10dd7d4100f1aa4f75a1 Mon Sep 17 00:00:00 2001 From: bathord Date: Sat, 28 Jun 2025 12:22:02 +0300 Subject: [PATCH 2/3] Create scripts for fetching historical fees --- examples/wrapper/get-complete-fee-info.ts | 42 ++++++++++++++ examples/wrapper/get-historical-fee-info.ts | 24 ++++++++ examples/wrapper/utils/getWrapperBags.ts | 25 +++++++-- .../wrapper/utils/processHistoricalFeeBag.ts | 56 +++++++++++++++++++ 4 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 examples/wrapper/get-complete-fee-info.ts create mode 100644 examples/wrapper/get-historical-fee-info.ts create mode 100644 examples/wrapper/utils/processHistoricalFeeBag.ts diff --git a/examples/wrapper/get-complete-fee-info.ts b/examples/wrapper/get-complete-fee-info.ts new file mode 100644 index 00000000..902b0f20 --- /dev/null +++ b/examples/wrapper/get-complete-fee-info.ts @@ -0,0 +1,42 @@ +import { getWrapperBags } from "./utils/getWrapperBags"; +import { processFeesBag } from "./utils/processFeeBag"; +import { processHistoricalFeeBag } from "./utils/processHistoricalFeeBag"; +import { printFeeSummary } from "./utils/printFeeSummary"; + +// yarn ts-node examples/wrapper/get-complete-fee-info.ts > complete-fee-info.log 2>&1 +(async () => { + const { deepReservesBagId, protocolFeesBagId, historicalCoverageFeesBagId, historicalProtocolFeesBagId } = + await getWrapperBags(); + + console.log("=== CURRENT FEES ==="); + + // Process current fee types + const deepReservesFees = await processFeesBag(deepReservesBagId); + const protocolFees = await processFeesBag(protocolFeesBagId); + + // Print current fees summaries + printFeeSummary( + "Current Deep Reserves Coverage Fees", + deepReservesFees.coinsMapByCoinType, + deepReservesFees.coinsMetadataMapByCoinType, + ); + printFeeSummary("Current Protocol Fees", protocolFees.coinsMapByCoinType, protocolFees.coinsMetadataMapByCoinType); + + console.log("\n=== HISTORICAL FEES ==="); + + // Process historical fee types + const historicalCoverageFees = await processHistoricalFeeBag(historicalCoverageFeesBagId); + const historicalProtocolFees = await processHistoricalFeeBag(historicalProtocolFeesBagId); + + // Print historical fees summaries + printFeeSummary( + "Historical Deep Reserves Coverage Fees", + historicalCoverageFees.coinsMapByCoinType, + historicalCoverageFees.coinsMetadataMapByCoinType, + ); + printFeeSummary( + "Historical Protocol Fees", + historicalProtocolFees.coinsMapByCoinType, + historicalProtocolFees.coinsMetadataMapByCoinType, + ); +})(); diff --git a/examples/wrapper/get-historical-fee-info.ts b/examples/wrapper/get-historical-fee-info.ts new file mode 100644 index 00000000..9d97cd82 --- /dev/null +++ b/examples/wrapper/get-historical-fee-info.ts @@ -0,0 +1,24 @@ +import { getWrapperBags } from "./utils/getWrapperBags"; +import { processHistoricalFeeBag } from "./utils/processHistoricalFeeBag"; +import { printFeeSummary } from "./utils/printFeeSummary"; + +// yarn ts-node examples/wrapper/get-historical-fee-info.ts > historical-fee-info.log 2>&1 +(async () => { + const { historicalCoverageFeesBagId, historicalProtocolFeesBagId } = await getWrapperBags(); + + // Process both historical fee types + const historicalCoverageFees = await processHistoricalFeeBag(historicalCoverageFeesBagId); + const historicalProtocolFees = await processHistoricalFeeBag(historicalProtocolFeesBagId); + + // Print summaries + printFeeSummary( + "Historical Deep Reserves Coverage Fees", + historicalCoverageFees.coinsMapByCoinType, + historicalCoverageFees.coinsMetadataMapByCoinType, + ); + printFeeSummary( + "Historical Protocol Fees", + historicalProtocolFees.coinsMapByCoinType, + historicalProtocolFees.coinsMetadataMapByCoinType, + ); +})(); diff --git a/examples/wrapper/utils/getWrapperBags.ts b/examples/wrapper/utils/getWrapperBags.ts index 50592010..8ddbb3ae 100644 --- a/examples/wrapper/utils/getWrapperBags.ts +++ b/examples/wrapper/utils/getWrapperBags.ts @@ -2,7 +2,7 @@ import { provider } from "../../common"; import { WRAPPER_OBJECT_ID } from "../../constants"; export async function getWrapperBags() { - // Fetch the wrapper object using its ID + // Fetch the wrapper object using its ID const wrapperObjectResponse = await provider.getObject({ id: WRAPPER_OBJECT_ID, options: { showContent: true }, @@ -15,10 +15,14 @@ export async function getWrapperBags() { const wrapperObject = wrapperObjectResponse.data.content.fields; - // Get the bag IDs for both fee types + // Get the bag IDs for current fees const deepReservesBagId = (wrapperObject as any).deep_reserves_coverage_fees?.fields?.id?.id; const protocolFeesBagId = (wrapperObject as any).protocol_fees?.fields?.id?.id; + // Get the bag IDs for historical fees + const historicalCoverageFeesBagId = (wrapperObject as any).historical_coverage_fees?.fields?.id?.id; + const historicalProtocolFeesBagId = (wrapperObject as any).historical_protocol_fees?.fields?.id?.id; + if (!deepReservesBagId) { throw new Error("Could not find deep_reserves_coverage_fees bag ID"); } @@ -27,5 +31,18 @@ export async function getWrapperBags() { throw new Error("Could not find protocol_fees bag ID"); } - return { deepReservesBagId, protocolFeesBagId }; -} \ No newline at end of file + if (!historicalCoverageFeesBagId) { + throw new Error("Could not find historical_coverage_fees bag ID"); + } + + if (!historicalProtocolFeesBagId) { + throw new Error("Could not find historical_protocol_fees bag ID"); + } + + return { + deepReservesBagId, + protocolFeesBagId, + historicalCoverageFeesBagId, + historicalProtocolFeesBagId, + }; +} diff --git a/examples/wrapper/utils/processHistoricalFeeBag.ts b/examples/wrapper/utils/processHistoricalFeeBag.ts new file mode 100644 index 00000000..d4707c3c --- /dev/null +++ b/examples/wrapper/utils/processHistoricalFeeBag.ts @@ -0,0 +1,56 @@ +import { CoinsMapByCoinType, CoinsMetadataMapByCoinType } from "./types"; +import { provider } from "../../common"; +import { getCoinMetadata } from "./getCoinMetadata"; + +// Process historical fees from a specific bag (stored as u128 values) +export async function processHistoricalFeeBag(bagId: string): Promise<{ + coinsMapByCoinType: CoinsMapByCoinType; + coinsMetadataMapByCoinType: CoinsMetadataMapByCoinType; +}> { + const coinsMapByCoinType: CoinsMapByCoinType = {}; + const coinsMetadataMapByCoinType: CoinsMetadataMapByCoinType = {}; + + // Fetch all dynamic fields in the bag + const dynamicFields = await provider.getDynamicFields({ parentId: bagId }); + + // Fetch each field's content + for (const field of dynamicFields.data) { + const fieldObject = await provider.getDynamicFieldObject({ + parentId: bagId, + name: field.name, + }); + + // Extract coin type and historical amount information + if (fieldObject.data?.content?.dataType === "moveObject") { + const fieldName = field.name; + const fieldValue = fieldObject.data.content.fields; + + // The field name should contain the coin type information + // Historical fees are stored as ChargedFeeKey -> u128 + if (fieldName && typeof fieldName === "object" && "type" in fieldName) { + const nameType = (fieldName as any).type; + + // Extract coin type from the ChargedFeeKey type + if (nameType.includes("ChargedFeeKey<")) { + const coinType = nameType.substring( + nameType.indexOf("ChargedFeeKey<") + "ChargedFeeKey<".length, + nameType.length - 1, + ); + + // The historical amount is stored directly as u128 in the field value + const historicalAmount = (fieldValue as any).value || fieldValue; + + // Add to summary + coinsMapByCoinType[coinType] = BigInt(historicalAmount); + + // Fetch coin metadata if we haven't already + if (!coinsMetadataMapByCoinType[coinType]) { + coinsMetadataMapByCoinType[coinType] = await getCoinMetadata(coinType); + } + } + } + } + } + + return { coinsMapByCoinType, coinsMetadataMapByCoinType }; +} From f6fde2f574f147c32293d40a43f26b020b4c4c93 Mon Sep 17 00:00:00 2001 From: bathord Date: Sun, 29 Jun 2025 20:58:25 +0300 Subject: [PATCH 3/3] Store historical fees as u256 instead of u128 --- examples/wrapper/utils/processHistoricalFeeBag.ts | 6 +++--- packages/deepbook-wrapper/sources/wrapper.move | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/wrapper/utils/processHistoricalFeeBag.ts b/examples/wrapper/utils/processHistoricalFeeBag.ts index d4707c3c..b32a110b 100644 --- a/examples/wrapper/utils/processHistoricalFeeBag.ts +++ b/examples/wrapper/utils/processHistoricalFeeBag.ts @@ -2,7 +2,7 @@ import { CoinsMapByCoinType, CoinsMetadataMapByCoinType } from "./types"; import { provider } from "../../common"; import { getCoinMetadata } from "./getCoinMetadata"; -// Process historical fees from a specific bag (stored as u128 values) +// Process historical fees from a specific bag (stored as u256 values) export async function processHistoricalFeeBag(bagId: string): Promise<{ coinsMapByCoinType: CoinsMapByCoinType; coinsMetadataMapByCoinType: CoinsMetadataMapByCoinType; @@ -26,7 +26,7 @@ export async function processHistoricalFeeBag(bagId: string): Promise<{ const fieldValue = fieldObject.data.content.fields; // The field name should contain the coin type information - // Historical fees are stored as ChargedFeeKey -> u128 + // Historical fees are stored as ChargedFeeKey -> u256 if (fieldName && typeof fieldName === "object" && "type" in fieldName) { const nameType = (fieldName as any).type; @@ -37,7 +37,7 @@ export async function processHistoricalFeeBag(bagId: string): Promise<{ nameType.length - 1, ); - // The historical amount is stored directly as u128 in the field value + // The historical amount is stored directly as u256 in the field value const historicalAmount = (fieldValue as any).value || fieldValue; // Add to summary diff --git a/packages/deepbook-wrapper/sources/wrapper.move b/packages/deepbook-wrapper/sources/wrapper.move index 594c579c..23145332 100644 --- a/packages/deepbook-wrapper/sources/wrapper.move +++ b/packages/deepbook-wrapper/sources/wrapper.move @@ -129,9 +129,9 @@ public(package) fun join_deep_reserves_coverage_fee( // Update historical total if (wrapper.historical_coverage_fees.contains(key)) { let current_total = wrapper.historical_coverage_fees.borrow_mut(key); - *current_total = *current_total + (fee_amount as u128); + *current_total = *current_total + (fee_amount as u256); } else { - wrapper.historical_coverage_fees.add(key, fee_amount as u128); + wrapper.historical_coverage_fees.add(key, fee_amount as u256); }; } @@ -156,9 +156,9 @@ public(package) fun join_protocol_fee(wrapper: &mut Wrapper, fee: Bala // Update historical total if (wrapper.historical_protocol_fees.contains(key)) { let current_total = wrapper.historical_protocol_fees.borrow_mut(key); - *current_total = *current_total + (fee_amount as u128); + *current_total = *current_total + (fee_amount as u256); } else { - wrapper.historical_protocol_fees.add(key, fee_amount as u128); + wrapper.historical_protocol_fees.add(key, fee_amount as u256); }; }