Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions examples/wrapper/get-complete-fee-info.ts
Original file line number Diff line number Diff line change
@@ -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,
);
})();
24 changes: 24 additions & 0 deletions examples/wrapper/get-historical-fee-info.ts
Original file line number Diff line number Diff line change
@@ -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,
);
})();
25 changes: 21 additions & 4 deletions examples/wrapper/utils/getWrapperBags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand All @@ -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");
}
Expand All @@ -27,5 +31,18 @@ export async function getWrapperBags() {
throw new Error("Could not find protocol_fees bag ID");
}

return { deepReservesBagId, protocolFeesBagId };
}
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,
};
}
56 changes: 56 additions & 0 deletions examples/wrapper/utils/processHistoricalFeeBag.ts
Original file line number Diff line number Diff line change
@@ -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 u256 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<CoinType> -> u256
if (fieldName && typeof fieldName === "object" && "type" in fieldName) {
const nameType = (fieldName as any).type;

// Extract coin type from the ChargedFeeKey<CoinType> type
if (nameType.includes("ChargedFeeKey<")) {
const coinType = nameType.substring(
nameType.indexOf("ChargedFeeKey<") + "ChargedFeeKey<".length,
nameType.length - 1,
);

// The historical amount is stored directly as u256 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 };
}
30 changes: 28 additions & 2 deletions packages/deepbook-wrapper/sources/wrapper.move
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public struct Wrapper has key, store {
deep_reserves: Balance<DEEP>,
deep_reserves_coverage_fees: Bag,
protocol_fees: Bag,
historical_coverage_fees: Bag,
historical_protocol_fees: Bag,
}

/// Capability for managing funds in the wrapper
Expand Down Expand Up @@ -108,34 +110,56 @@ public(package) fun join_deep_reserves_coverage_fee<CoinType>(
wrapper: &mut Wrapper,
fee: Balance<CoinType>,
) {
if (fee.value() == 0) {
let fee_amount = fee.value();
if (fee_amount == 0) {
fee.destroy_zero();
return
};

let key = ChargedFeeKey<CoinType> { 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 u256);
} else {
wrapper.historical_coverage_fees.add(key, fee_amount as u256);
};
}

/// Add collected protocol fees to the wrapper's fee storage
public(package) fun join_protocol_fee<CoinType>(wrapper: &mut Wrapper, fee: Balance<CoinType>) {
if (fee.value() == 0) {
let fee_amount = fee.value();
if (fee_amount == 0) {
fee.destroy_zero();
return
};

let key = ChargedFeeKey<CoinType> { 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 u256);
} else {
wrapper.historical_protocol_fees.add(key, fee_amount as u256);
};
}

/// Get the splitted DEEP coin from the reserves
Expand All @@ -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
Expand Down