Skip to content

Add Frankencoin protocol revenue adapter #3880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
79 changes: 79 additions & 0 deletions fees/frankencoin/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { FetchOptions, SimpleAdapter } from "../../adapters/types";
import { CHAIN } from "../../helpers/chains";
import { request, gql } from "graphql-request";

// GraphQL endpoint for Frankencoin
const FRANKENCOIN_GRAPH_URL = "https://ponder.test.frankencoin.com"; // TODO: change to production URL

// ZCHF token address on Ethereum
const ZCHF_ADDRESS = "0xB58E61C3098d85632Df34EecfB899A1Ed80921cB";

const PROFIT_LOSS_QUERY = gql`
query GetProfitLoss {
frankencoinProfitLosss(
orderBy: "count",
orderDirection: "desc",
limit: 1,
) {
items {
profits
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need more information regarding the how profit/loss are calculated? as daily ~1M revenue for 30m TVL looks very high, so please provide more information, thanks

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hoi

the graph table is just an entry of all profits and losses. And therefore its the accumulated profits/losses of all times. I thought the defillama api is regularly fetching the numbers and calculate the difference between the fetches and therefore knows how much the daily values would be.

{
  "amount": "167395000000000000000", **<-- individual change per this entry**
  "chainId": 1,
  "count": "353",
  "created": "1754328179",
  "kind": "Profit", **<-- this entry reflects a profit change**
  "losses": "20513419393164404266345", **<-- all time losses (accum.)**
  "minter": "0x5ed0d010e20c262cc264aaf060fb9e3037cd383e",
  "perFPS": "90297226610802112896",
  "profits": "802597897386182421051766" **<-- all time profits (accum.)**
},

maybe i have to refactor this.
So you need explicitly the daily p/l?
How does the fetcher function know which date it is?

Copy link
Member

@treeoflife2 treeoflife2 Aug 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samclassix you can read more about how dimension adapter works here(https://docs.llama.fi/list-your-project/other-dashboards)
but i will give you tldr

we run it each day at UTC 00:00 if it's version 1 adapter(default)
so we have options in fetch function, which has options.starttimestamp and options.endtimestamp
which will be previous day start and end timestamp.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't understand how all profit goes to protocol, isn't there any yield for token holders?

losses
}
}
}
`;

const fetch = async (options: FetchOptions) => {
const dailyFees = options.createBalances();
const dailyRevenue = options.createBalances();

try {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove try-catch as we have to let the adapter fail in case any errors, so we can fix the issue

const { frankencoinProfitLosss } = await request(FRANKENCOIN_GRAPH_URL, PROFIT_LOSS_QUERY);

const profits = frankencoinProfitLosss?.items?.[0]?.profits ?? "0";
const losses = frankencoinProfitLosss?.items?.[0]?.losses ?? "0";

// Convert string values to BigInt for calculations
const profitsBigInt = BigInt(profits);
const lossesBigInt = BigInt(losses);

// Fees are the total profits in ZCHF
dailyFees.add(ZCHF_ADDRESS, profitsBigInt);

// Revenue is profits minus losses in ZCHF
const revenue = profitsBigInt - lossesBigInt;
dailyRevenue.add(ZCHF_ADDRESS, revenue);

return {
dailyFees,
dailyRevenue,
dailyProtocolRevenue: dailyRevenue,
};
} catch (error) {
console.error("Error fetching Frankencoin data:", error);
return {
dailyFees,
dailyRevenue,
dailyProtocolRevenue: dailyRevenue,
};
}
};

const adapter: SimpleAdapter = {
version: 2,
adapter: {
[CHAIN.ETHEREUM]: {
fetch,
start: '2023-10-28',
meta: {
methodology: {
Fees: "Total profits generated by the Frankencoin protocol in ZCHF tokens",
Revenue: "Net revenue calculated as profits minus losses in ZCHF tokens",
ProtocolRevenue: "All net revenue is retained by the protocol in ZCHF tokens",
}
}
}
}
};

export default adapter;
Loading