Skip to content

Groypfi 2#6299

Open
Renryog wants to merge 32 commits intoDefiLlama:masterfrom
Renryog:Groypfi-2
Open

Groypfi 2#6299
Renryog wants to merge 32 commits intoDefiLlama:masterfrom
Renryog:Groypfi-2

Conversation

@Renryog
Copy link
Copy Markdown
Contributor

@Renryog Renryog commented Mar 30, 2026

GroypFi DefiLlama Adapters

Dimension adapters for listing GroypFi on DefiLlama.

What is GroypFi?

GroypFi is a DEX aggregator on TON that routes swaps across DeDust, STON.fi, Tonco, and Bidask for optimal pricing. It charges a 1% platform fee on every swap, with 100% of fees used for GROYP token buybacks.

Products:

  • Swap Widget (web app)
  • Terminal Quick Buy (web app)
  • Launchpad token trading (web app)
  • @groypfi_bot (Telegram trading bot)

Adapters

Dashboard File Returns
aggregators aggregators/groypfi/index.ts dailyVolume
fees fees/groypfi/index.ts dailyFees, dailyRevenue, dailyProtocolRevenue, dailyHoldersRevenue

How It Works

Both adapters query the house fee wallet on-chain via TON API:

Wallet (UF): UQDu4AiT__JKuqT0Znje0RoXIQMPcj4uIGYZme3UK4hFlE_Q
Wallet (raw): 0:eee0084ffffc92aea4f46679ded118172103f723e2e206619a9eddf42b8845d4
  • Fees adapter: Sums all incoming TON transfers to the fee wallet for the day.
  • Aggregators adapter: Reverse-calculates volume from fees: volume = fees / 0.01.

Fee Structure

Source Fee Destination
All swaps (web + bot) 1% House fee wallet
Revenue usage 100% GROYP token buybacks

Links

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 30, 2026

Summary by CodeRabbit

  • New Features

    • Added DEX volume tracking for Groypfi on the TON network, starting from January 1, 2025.
  • Updates

    • Enhanced fee metrics with improved USD pricing calculations and added user fee tracking alongside protocol revenue.

Walkthrough

A new DEX adapter for GroypFi on TON is introduced alongside a refactored fee adapter that compute aggregation volume and fees by reverse-calculating from platform fee inflows via paginated TonAPI transaction queries and TON/USD rate conversion.

Changes

Cohort / File(s) Summary
New DEX Adapter
dexs/groypfi/index.ts
New module that computes daily TON DEX aggregation volume by reverse-calculating from platform fees using the formula volume = fee / 0.01. Implements paginated TonAPI transaction fetching for the house fee wallet, sums successful incoming TON transaction values, converts nanotons to TON, and applies TON/USD pricing (defaulting to 3.5 USD if unavailable).
Refactored Fee Adapter
fees/groypfi/index.ts
Restructured fee calculation logic: replaces single-query TONAPI calls with paginated fetchDayTransactions() using before_lt pagination. Now filters transactions by success status and positive in_msg.value, sums nanoton fees, converts to USD via TONAPI rates, and reorganizes the exported adapter configuration from flat chains/start/methodology structure to per-chain adapter map with nested meta.methodology.

Sequence Diagram

sequenceDiagram
    participant Adapter as DEX/Fee Adapter
    participant TonAPI as TonAPI
    participant RateEndpoint as TonAPI Rates
    
    Adapter->>TonAPI: Fetch transactions for fee wallet<br/>(within time window)
    Note over TonAPI: Paginate via before_lt<br/>until startTimestamp reached
    TonAPI-->>Adapter: Transaction batch
    
    Adapter->>Adapter: Filter: success=true &<br/>in_msg.value > 0
    Adapter->>Adapter: Sum nanoton fees
    
    Adapter->>RateEndpoint: GET /rates?tokens=ton<br/>&currencies=usd
    RateEndpoint-->>Adapter: TON/USD rate<br/>(default 3.5)
    
    Adapter->>Adapter: Convert fees to TON (÷1e9)
    Adapter->>Adapter: Multiply by TON/USD rate
    
    Note over Adapter: DEX: volume = fee / 0.01<br/>Fee: return dailyFees in USD
    Adapter-->>Adapter: Return aggregated metrics
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • DefiLlama/dimension-adapters#5621: Modifies the same GroypFi adapter files with identical TonAPI paginated transaction fetching, BigInt fee accumulation, and fee-to-volume reverse-calculation logic.

Suggested labels

fees, dexs, aggregators, new-adapter, methodology

🚥 Pre-merge checks | ✅ 2 | ❌ 4

❌ Failed checks (2 warnings, 2 inconclusive)

Check name Status Explanation Resolution
Breakdown Methodology Check ⚠️ Warning The fees/groypfi/index.ts adapter is missing the required breakdownMethodology object that documents all fee breakdown labels used. Add a breakdownMethodology constant documenting each fee dimension (e.g., Platform Swap Fees, Token Buy Back) and export it in the adapter's meta configuration.
Income Statement Compliance ⚠️ Warning The adapter is missing the required dailySupplySideRevenue metric for Income Statement Compliance. While the business model has zero supplier costs, explicit declaration is required. Add dailySupplySideRevenue: 0 and dailyHoldersRevenue: dailyFeesUSD to the return statement to fully comply with the income statement model.
Title check ❓ Inconclusive The title 'Groypfi 2' is vague and does not follow the required format [type] protocol-name - description, providing minimal insight into the actual changes. Revise title to follow format: '[feat] groypfi - add fees and aggregator adapters' or similar, clearly describing what is being added.
Version 2 Required ❓ Inconclusive Unable to execute shell commands to verify adapter files and version format compliance. Manual inspection of groypfi adapter files is required to confirm version 2 format usage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The PR description is comprehensive and directly addresses the PR purpose, covering protocol details, adapter functionality, fee structure, and relevant links.
Docstring Coverage ✅ Passed Docstring coverage is 50.00% which is sufficient. The required threshold is 50.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch Groypfi-2
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@dexs/groypfi/index.ts`:
- Around line 31-84: The TonTransaction, TxPage, RatesResponse interfaces and
the fetchDayTransactions function are duplicated; extract them into a shared
helper module (e.g., helpers/ton/groypfi.ts) and export TonTransaction, TxPage,
RatesResponse and fetchDayTransactions from that file, then replace the local
duplicates in dexs/groypfi/index.ts and fees/groypfi/index.ts with imports from
the new helper; ensure the helper exports the same symbol names (TonTransaction,
TxPage, RatesResponse, fetchDayTransactions) and update any references to those
symbols in both files so they use the centralized implementation and remove the
duplicate declarations.
- Line 92: The code currently uses a hardcoded fallback const tonPrice =
rates.rates?.TON?.prices?.USD ?? 3.5 which is risky; remove the 3.5 literal and
instead handle missing/invalid price by either throwing an error or emitting an
explicit warning so operators see the fallback: check
rates.rates?.TON?.prices?.USD, and if undefined call your logger (e.g.,
processLogger.warn or logger.warn) with a clear message and either throw a
descriptive Error or set tonPrice only after a validated value is present;
update any callers of tonPrice to handle the thrown error if you choose the
throw approach.
- Around line 86-115: The fetch function should catch errors from external calls
(httpGet to TON_API and fetchDayTransactions) so the adapter doesn't throw; wrap
the body of fetch (or at least the calls to httpGet and fetchDayTransactions) in
a try-catch, log the error (e.g., using an existing logger or console.error)
including context like "groypfi fetch" and the caught error, and return a safe
recoverable response { dailyVolume: 0 } on failure; ensure you reference the
same symbols (fetch, TON_API, httpGet, fetchDayTransactions, RatesResponse) so
the changes are local and clearly handle chain-specific failures.
- Around line 107-110: Avoid converting the large BigInt volumeNano directly to
Number; instead perform integer division in the BigInt domain and only convert
the bounded pieces to Number to preserve precision. Replace the current
conversion in volumeTon with BigInt math: compute wholeTons = volumeNano /
1_000_000_000n and remainderNanos = volumeNano % 1_000_000_000n, then set
volumeTon = Number(wholeTons) + Number(remainderNanos) / 1e9 before computing
dailyVolumeUSD; update references to feeNano and volumeNano accordingly so the
division happens as BigInt first and only the small remainder is converted to
Number.

In `@fees/groypfi/index.ts`:
- Around line 23-71: The TonTransaction, TxPage, RatesResponse interfaces and
fetchDayTransactions function are duplicated; extract them into a shared helper
module (e.g., helpers/ton/groypfi.ts) and update both fees/groypfi/index.ts and
dexs/groypfi/index.ts to import the shared symbols. Move the interfaces
TonTransaction, TxPage, RatesResponse and the function fetchDayTransactions into
the new helper, export them, remove the local duplicates, and replace the local
definitions/usages in functions that call fetchDayTransactions (and any type
annotations) with imports from the helper so both adapters reference the single
source of truth.
- Line 51: Add the missing ESLint disable comment above the infinite loop in
fees/groypfi/index.ts: place a line with "// eslint-disable-next-line
no-constant-condition" immediately before the "while (true) {" statement (same
style as dexs/groypfi/index.ts) to suppress the linter warning and keep
consistency.
- Line 79: The hardcoded fallback 3.5 for tonPrice (const tonPrice =
rates.rates?.TON?.prices?.USD ?? 3.5) is unsafe; replace it with a configurable
or validated fallback and handle missing price explicitly: read a default from
configuration/env (e.g., DEFAULT_TON_PRICE) or return/throw an error when
rates.rates?.TON?.prices?.USD is undefined, and add a clear warning log so
callers of this module (where tonPrice is used) can decide how to proceed
instead of silently using an arbitrary number.
- Around line 104-108: Add a new breakdownMethodology object that documents
every label used in the existing methodology (e.g., "Fees", "UserFees",
"Revenue") and provide a short explanatory string for each label; name it
breakdownMethodology and mirror the keys from the methodology object. Then
include this breakdownMethodology in the adapter meta export alongside the
existing methodology (where the adapter/meta is constructed), so the adapter
exposes both methodology and breakdownMethodology for the fees labels used.
Ensure the labels match exactly the keys in the methodology object to satisfy
the fees adapter guideline.
- Around line 96-101: The return object currently sets dailyFees, dailyUserFees,
and dailyRevenue to dailyFeesUSD but omits the required dailyHoldersRevenue for
GROYP buybacks; update the returned object (the object containing dailyFees,
dailyUserFees, dailyRevenue in fees/groypfi/index.ts) to include
dailyHoldersRevenue with the same value as dailyFeesUSD and annotate it with the
label "Token Buy Back" (i.e., set dailyHoldersRevenue to { value: dailyFeesUSD,
label: "Token Buy Back" } or the project’s standard structure for labeled
revenue dimensions) so buybacks are tracked as holders' revenue.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2e0a6747-debf-4b48-b961-ec6d66705773

📥 Commits

Reviewing files that changed from the base of the PR and between ceebc11 and 5b2405d.

📒 Files selected for processing (2)
  • dexs/groypfi/index.ts
  • fees/groypfi/index.ts

Comment on lines +31 to +84
interface TonTransaction {
hash: string;
lt: string;
utime: number;
success: boolean;
in_msg?: {
value: number;
msg_type: string;
source?: { address: string };
};
}

interface TxPage {
transactions: TonTransaction[];
}

interface RatesResponse {
rates: Record<string, { prices: Record<string, number> }>;
}

/**
* Paginate through all transactions in the [startOfDay, endOfDay) window.
* TonAPI returns newest-first; we stop when we pass startOfDay.
*/
async function fetchDayTransactions(
startTs: number,
endTs: number,
): Promise<TonTransaction[]> {
const collected: TonTransaction[] = [];
let beforeLt: string | undefined;
const limit = 256;

// eslint-disable-next-line no-constant-condition
while (true) {
let url = `${TON_API}/blockchain/accounts/${FEE_WALLET_RAW}/transactions?limit=${limit}&sort_order=desc`;
if (beforeLt) url += `&before_lt=${beforeLt}`;

const page: TxPage = await httpGet(url);
const txs = page.transactions ?? [];
if (txs.length === 0) break;

for (const tx of txs) {
if (tx.utime < startTs) return collected; // past our window
if (tx.utime < endTs && tx.utime >= startTs) {
collected.push(tx);
}
}

beforeLt = txs[txs.length - 1].lt;
if (txs.length < limit) break; // no more pages
}

return collected;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Extract shared code to a helper module to avoid duplication.

The TonTransaction, TxPage, RatesResponse interfaces and fetchDayTransactions function are duplicated verbatim in fees/groypfi/index.ts. Per coding guidelines, shared logic should be extracted to helpers/. Consider creating helpers/ton/groypfi.ts with these shared utilities.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dexs/groypfi/index.ts` around lines 31 - 84, The TonTransaction, TxPage,
RatesResponse interfaces and the fetchDayTransactions function are duplicated;
extract them into a shared helper module (e.g., helpers/ton/groypfi.ts) and
export TonTransaction, TxPage, RatesResponse and fetchDayTransactions from that
file, then replace the local duplicates in dexs/groypfi/index.ts and
fees/groypfi/index.ts with imports from the new helper; ensure the helper
exports the same symbol names (TonTransaction, TxPage, RatesResponse,
fetchDayTransactions) and update any references to those symbols in both files
so they use the centralized implementation and remove the duplicate
declarations.

Comment on lines +86 to +115
const fetch = async (options: FetchOptions) => {
const { startTimestamp, endTimestamp } = options;

// 1. Get TON price in USD
const ratesUrl = `${TON_API}/rates?tokens=ton&currencies=usd`;
const rates: RatesResponse = await httpGet(ratesUrl);
const tonPrice = rates.rates?.TON?.prices?.USD ?? 3.5;

// 2. Collect all incoming TON transfers in the day window
const txs = await fetchDayTransactions(startTimestamp, endTimestamp);

let feeNano = 0n;

for (const tx of txs) {
if (!tx.success) continue;
// Only count incoming TON value (in_msg with value > 0)
if (tx.in_msg && tx.in_msg.value > 0) {
feeNano += BigInt(tx.in_msg.value);
}
}

// 3. Volume = fee / 0.01 (1% fee → multiply by 100)
const volumeNano = feeNano * 100n;
const volumeTon = Number(volumeNano) / 1e9;
const dailyVolumeUSD = volumeTon * tonPrice;

return {
dailyVolume: dailyVolumeUSD,
};
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Add error handling around external API calls.

Per guidelines, for recoverable chain-specific failures, return 0 and log the error. Currently, if TONAPI is unreachable or returns malformed data, the adapter throws and halts. Wrapping the fetch logic in try-catch would improve resilience.

Proposed approach
 const fetch = async (options: FetchOptions) => {
   const { startTimestamp, endTimestamp } = options;
+  try {
     // 1. Get TON price in USD
     const ratesUrl = `${TON_API}/rates?tokens=ton&currencies=usd`;
     ...
     return {
       dailyVolume: dailyVolumeUSD,
     };
+  } catch (error) {
+    console.error(`[groypfi] Failed to fetch volume: ${error}`);
+    return { dailyVolume: 0 };
+  }
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dexs/groypfi/index.ts` around lines 86 - 115, The fetch function should catch
errors from external calls (httpGet to TON_API and fetchDayTransactions) so the
adapter doesn't throw; wrap the body of fetch (or at least the calls to httpGet
and fetchDayTransactions) in a try-catch, log the error (e.g., using an existing
logger or console.error) including context like "groypfi fetch" and the caught
error, and return a safe recoverable response { dailyVolume: 0 } on failure;
ensure you reference the same symbols (fetch, TON_API, httpGet,
fetchDayTransactions, RatesResponse) so the changes are local and clearly handle
chain-specific failures.

// 1. Get TON price in USD
const ratesUrl = `${TON_API}/rates?tokens=ton&currencies=usd`;
const rates: RatesResponse = await httpGet(ratesUrl);
const tonPrice = rates.rates?.TON?.prices?.USD ?? 3.5;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Hardcoded fallback price of 3.5 USD is risky.

TON price fluctuates significantly. If the rates API fails or returns unexpected data, using a stale fallback could produce wildly inaccurate volume figures. Consider either throwing an error when price cannot be fetched, or logging a warning so operators notice the fallback is being used.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dexs/groypfi/index.ts` at line 92, The code currently uses a hardcoded
fallback const tonPrice = rates.rates?.TON?.prices?.USD ?? 3.5 which is risky;
remove the 3.5 literal and instead handle missing/invalid price by either
throwing an error or emitting an explicit warning so operators see the fallback:
check rates.rates?.TON?.prices?.USD, and if undefined call your logger (e.g.,
processLogger.warn or logger.warn) with a clear message and either throw a
descriptive Error or set tonPrice only after a validated value is present;
update any callers of tonPrice to handle the thrown error if you choose the
throw approach.

Comment on lines +107 to +110
// 3. Volume = fee / 0.01 (1% fee → multiply by 100)
const volumeNano = feeNano * 100n;
const volumeTon = Number(volumeNano) / 1e9;
const dailyVolumeUSD = volumeTon * tonPrice;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Potential precision loss converting large BigInt to Number.

Number(volumeNano) loses precision for values exceeding Number.MAX_SAFE_INTEGER (~9e15). Since volumeNano is already multiplied by 100, extremely high daily volume could overflow safe integer range. Consider keeping the division in BigInt domain longer:

Proposed fix
-  const volumeNano = feeNano * 100n;
-  const volumeTon = Number(volumeNano) / 1e9;
-  const dailyVolumeUSD = volumeTon * tonPrice;
+  // Keep precision: volume = fee * 100, then convert to TON
+  const volumeNano = feeNano * 100n;
+  const volumeTon = Number(volumeNano / 1_000_000_000n) + Number(volumeNano % 1_000_000_000n) / 1e9;
+  const dailyVolumeUSD = volumeTon * tonPrice;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dexs/groypfi/index.ts` around lines 107 - 110, Avoid converting the large
BigInt volumeNano directly to Number; instead perform integer division in the
BigInt domain and only convert the bounded pieces to Number to preserve
precision. Replace the current conversion in volumeTon with BigInt math: compute
wholeTons = volumeNano / 1_000_000_000n and remainderNanos = volumeNano %
1_000_000_000n, then set volumeTon = Number(wholeTons) + Number(remainderNanos)
/ 1e9 before computing dailyVolumeUSD; update references to feeNano and
volumeNano accordingly so the division happens as BigInt first and only the
small remainder is converted to Number.

Comment on lines +23 to +71
interface TonTransaction {
hash: string;
lt: string;
utime: number;
success: boolean;
in_msg?: {
value: number;
msg_type: string;
source?: { address: string };
};
}

interface TxPage {
transactions: TonTransaction[];
}

interface RatesResponse {
rates: Record<string, { prices: Record<string, number> }>;
}

async function fetchDayTransactions(
startTs: number,
endTs: number,
): Promise<TonTransaction[]> {
const collected: TonTransaction[] = [];
let beforeLt: string | undefined;
const limit = 256;

const FEE_RECIPIENT = "0:eee00893fff24abaa4f46678ded11a1721030f723e2e20661999edd42b884594";
while (true) {
let url = `${TON_API}/blockchain/accounts/${FEE_WALLET_RAW}/transactions?limit=${limit}&sort_order=desc`;
if (beforeLt) url += `&before_lt=${beforeLt}`;

const page: TxPage = await httpGet(url);
const txs = page.transactions ?? [];
if (txs.length === 0) break;

for (const tx of txs) {
if (tx.utime < startTs) return collected;
if (tx.utime < endTs && tx.utime >= startTs) {
collected.push(tx);
}
}

beforeLt = txs[txs.length - 1].lt;
if (txs.length < limit) break;
}

return collected;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Duplicated code with dexs/groypfi/index.ts.

Interfaces TonTransaction, TxPage, RatesResponse and function fetchDayTransactions are identical to the DEX adapter. Extract to a shared helper (e.g., helpers/ton/groypfi.ts) to reduce maintenance burden and ensure consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@fees/groypfi/index.ts` around lines 23 - 71, The TonTransaction, TxPage,
RatesResponse interfaces and fetchDayTransactions function are duplicated;
extract them into a shared helper module (e.g., helpers/ton/groypfi.ts) and
update both fees/groypfi/index.ts and dexs/groypfi/index.ts to import the shared
symbols. Move the interfaces TonTransaction, TxPage, RatesResponse and the
function fetchDayTransactions into the new helper, export them, remove the local
duplicates, and replace the local definitions/usages in functions that call
fetchDayTransactions (and any type annotations) with imports from the helper so
both adapters reference the single source of truth.

const limit = 256;

const FEE_RECIPIENT = "0:eee00893fff24abaa4f46678ded11a1721030f723e2e20661999edd42b884594";
while (true) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Add eslint-disable comment for the infinite loop.

The equivalent loop in dexs/groypfi/index.ts has // eslint-disable-next-line no-constant-condition but this file omits it. Add for consistency and to suppress linter warnings.

Proposed fix
+  // eslint-disable-next-line no-constant-condition
   while (true) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
while (true) {
// eslint-disable-next-line no-constant-condition
while (true) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@fees/groypfi/index.ts` at line 51, Add the missing ESLint disable comment
above the infinite loop in fees/groypfi/index.ts: place a line with "//
eslint-disable-next-line no-constant-condition" immediately before the "while
(true) {" statement (same style as dexs/groypfi/index.ts) to suppress the linter
warning and keep consistency.

// 1. TON price
const ratesUrl = `${TON_API}/rates?tokens=ton&currencies=usd`;
const rates: RatesResponse = await httpGet(ratesUrl);
const tonPrice = rates.rates?.TON?.prices?.USD ?? 3.5;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Same hardcoded fallback price concern as DEX adapter.

Using 3.5 USD fallback when TON price fetch fails could produce significantly inaccurate fee values if the actual price differs substantially.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@fees/groypfi/index.ts` at line 79, The hardcoded fallback 3.5 for tonPrice
(const tonPrice = rates.rates?.TON?.prices?.USD ?? 3.5) is unsafe; replace it
with a configurable or validated fallback and handle missing price explicitly:
read a default from configuration/env (e.g., DEFAULT_TON_PRICE) or return/throw
an error when rates.rates?.TON?.prices?.USD is undefined, and add a clear
warning log so callers of this module (where tonPrice is used) can decide how to
proceed instead of silently using an arbitrary number.

Comment on lines 96 to 101
// 100% of fees = protocol revenue (GROYP buybacks)
return {
dailyFees,
dailyRevenue: dailyFees,
dailyProtocolRevenue: dailyFees,
dailyFees: dailyFeesUSD,
dailyUserFees: dailyFeesUSD,
dailyRevenue: dailyFeesUSD,
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Missing dailyHoldersRevenue for GROYP buybacks.

The PR description and comments state that 100% of collected fees are used for GROYP token buybacks. Per guidelines, buybacks should be tracked as dailyHoldersRevenue with a label like "Token Buy Back". This dimension is required when protocol distributes value to holders.

Proposed fix
   // 100% of fees = protocol revenue (GROYP buybacks)
   return {
     dailyFees: dailyFeesUSD,
     dailyUserFees: dailyFeesUSD,
     dailyRevenue: dailyFeesUSD,
+    dailyHoldersRevenue: dailyFeesUSD,
   };

Based on learnings: "Include dailyHoldersRevenue dimension when applicable - represents all value to token holders including buybacks, burns, distributions"

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@fees/groypfi/index.ts` around lines 96 - 101, The return object currently
sets dailyFees, dailyUserFees, and dailyRevenue to dailyFeesUSD but omits the
required dailyHoldersRevenue for GROYP buybacks; update the returned object (the
object containing dailyFees, dailyUserFees, dailyRevenue in
fees/groypfi/index.ts) to include dailyHoldersRevenue with the same value as
dailyFeesUSD and annotate it with the label "Token Buy Back" (i.e., set
dailyHoldersRevenue to { value: dailyFeesUSD, label: "Token Buy Back" } or the
project’s standard structure for labeled revenue dimensions) so buybacks are
tracked as holders' revenue.

Comment on lines 104 to +108
const methodology = {
Fees: "1% fee on lending, DEX swaps, cross-chain swaps, perps, staking, and NFT marketplace",
Revenue: "All the fees are revenue",
ProtocolRevenue: "All the revnue goes to protocol"
}
Fees: "Total 1% platform fees collected from all swap sources (Swap Widget, Terminal, Launchpad, @groypfi_bot).",
UserFees: "Same as Fees — users pay the 1% platform fee on every swap.",
Revenue: "100% of fees are protocol revenue used for GROYP token buybacks.",
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Add breakdownMethodology object documenting fee breakdown labels.

Per fees adapter guidelines, every label used should have a corresponding entry in breakdownMethodology. Even with a single fee source, this provides clarity and future-proofs the adapter.

Proposed fix
 const methodology = {
   Fees: "Total 1% platform fees collected from all swap sources (Swap Widget, Terminal, Launchpad, `@groypfi_bot`).",
   UserFees: "Same as Fees — users pay the 1% platform fee on every swap.",
   Revenue: "100% of fees are protocol revenue used for GROYP token buybacks.",
+  HoldersRevenue: "100% of fees used for GROYP token buybacks benefit holders.",
 };
+
+const breakdownMethodology = {
+  "Platform Swap Fees": "1% fee on all swaps routed through GroypFi aggregator across all products.",
+  "Token Buy Back": "100% of platform fees used for GROYP token buybacks.",
+};

Then include in adapter meta:

       meta: { methodology },
+      meta: { methodology, breakdownMethodology },

As per coding guidelines: "Include breakdownMethodology object in fees adapters that documents all labels used"

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@fees/groypfi/index.ts` around lines 104 - 108, Add a new breakdownMethodology
object that documents every label used in the existing methodology (e.g.,
"Fees", "UserFees", "Revenue") and provide a short explanatory string for each
label; name it breakdownMethodology and mirror the keys from the methodology
object. Then include this breakdownMethodology in the adapter meta export
alongside the existing methodology (where the adapter/meta is constructed), so
the adapter exposes both methodology and breakdownMethodology for the fees
labels used. Ensure the labels match exactly the keys in the methodology object
to satisfy the fees adapter guideline.

@bheluga bheluga self-assigned this Mar 30, 2026
Copy link
Copy Markdown
Member

@bheluga bheluga left a comment

Choose a reason for hiding this comment

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

@Renryog thanks for the PR.
we already track groypfi fees and volume here https://defillama.com/protocol/groypfi
Let me know if you intended to do something else

@Renryog
Copy link
Copy Markdown
Contributor Author

Renryog commented Mar 31, 2026

Hey @bheluga, the last PR for GroypFi has many issues as it is not being updated defillama anymore and wasn't tracking correctly fees and revenue. This PR is to replace the last one with corrected adapters.

@bheluga
Copy link
Copy Markdown
Member

bheluga commented Mar 31, 2026

Hey @bheluga, the last PR for GroypFi has many issues as it is not being updated defillama anymore and wasn't tracking correctly fees and revenue. This PR is to replace the last one with corrected adapters.

Please resolve merge conflicts

@Renryog
Copy link
Copy Markdown
Contributor Author

Renryog commented Apr 4, 2026

Hi @bheluga i've resolved merge conflicts. Sorry for the delay.

fetchDayTransactions,
getTonPrice,
nanoToTon,
} from "../../helpers/ton/groypfi";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I dont see this helper file anywhere.
Did i miss something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants