Hydration: Add revenue streams + fix fee calculation#6388
Hydration: Add revenue streams + fix fee calculation#6388bheluga merged 3 commits intoDefiLlama:masterfrom
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
Summary by CodeRabbit
WalkthroughRefactors Omnipool fee allocation to split asset vs protocol fees and allocate holders/LPs, and adds external protocol-fee streams plus HOLLAR borrow-interest capture to the HydraDX fee adapter. Methodology strings and breakdown mappings were updated accordingly. Changes
Sequence Diagram(s)sequenceDiagram
participant Adapter
participant FEES_API
participant ChainData
participant PricingService
Adapter->>FEES_API: fetchProtocolStream(productType, streamType, 24h)
FEES_API-->>Adapter: periodAggregate (>=0)
Adapter->>ChainData: read reserves, totalDebt, borrowRate
ChainData-->>Adapter: reserve data (including HOLLAR)
Adapter->>PricingService: convert amounts to USD
PricingService-->>Adapter: USD values
Adapter->>Adapter: compute assetFee/protocolFee, split to LPs/holders, add protocol streams, add HOLLAR borrow-interest
Adapter-->>Adapter: populate dailyFees, dailySupplySideRevenue, dailyHoldersRevenue, dailyProtocolRevenue
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested labels
🚥 Pre-merge checks | ✅ 1 | ❌ 5❌ Failed checks (4 warnings, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches✨ Simplify 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. Comment |
|
The hydradx adapter exports: |
|
The hydradx.ts adapter exports: |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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/hydradx/index.ts`:
- Line 55: The fee label "Omnipool Asset Fees To Stakers & Referrals" used in
dailyHoldersRevenue.addUSDValue (and similar labels used in the other add()
calls around lines 93-110) is missing from the breakdownMethodology object; add
a HoldersRevenue section to breakdownMethodology that includes entries for each
new labeled series (e.g., "Omnipool Asset Fees To Stakers & Referrals") and map
them to the appropriate implementation/description per the adapter guideline so
every label used by dailyHoldersRevenue.addUSDValue and other .add() calls is
present in breakdownMethodology; update the breakdownMethodology constant in
this file to include these HoldersRevenue mappings.
- Around line 46-62: The current code hardcodes an 80/20 asset/protocol split
and routes all protocol fees to Treasury and the entire non‑LP asset half to
holders; instead, read the actual runtime/config values exposed by the node
(e.g., fields on node such as omnipoolFeeVolNorm, BurnProtocolFee, and any
referral/trader/staker split or referral tier config) and compute splits
dynamically: compute omnipoolFee from node.omnipoolFeeVolNorm, derive
protocolFee proportion using the runtime BurnProtocolFee (split protocolFee into
burned vs treasury per BurnProtocolFee) and derive assetFee = omnipoolFee -
protocolFee, then record revenues by calling
dailySupplySideRevenue.addUSDValue(assetFee * 0.5, ...) for LPs and allocate the
remaining assetFee * 0.5 across
dailyHoldersRevenue/dailyReferralRevenue/dailyTraderRevenue according to the
runtime referral/tier split (or a configurable fallback if the runtime split is
not present); update dailyProtocolRevenue.addUSDValue to only include the
treasury portion (not the burned portion) and log or expose when you must use a
documented default fallback so the split isn’t silently hardcoded.
In `@fees/hydradx.ts`:
- Around line 154-166: The new protocol streams added via EXTRA_PROTOCOL_STREAMS
(labels: "Liquidation Penalty", "PEPL Liquidation Profit", "HSM Revenue") are
recorded with dailyFees.addUSDValue and dailyProtocolRevenue.addUSDValue but are
not documented in the adapter's breakdownMethodology, violating the
label→methodology contract; add entries for each of these labels to the fees
adapter's breakdownMethodology object with concise descriptions and link them to
the corresponding implementation (e.g., mention EXTRA_PROTOCOL_STREAMS usage),
ensuring every label used in .add()/.addUSDValue calls appears in
breakdownMethodology.
- Around line 81-95: The HOLLAR borrow-interest block (use HOLLAR, hollarIndex,
totalDebt, borrowRate) currently adds amounts to dailyFees and
dailyProtocolRevenue without explicit labels; update the calls so
dailyFees.addUSDValue uses a clear source label like "Borrow Interest" and
dailyProtocolRevenue.addUSDValue uses a source→destination label like "Borrow
Interest → Treasury" (or "Borrow Interest To Treasury") and apply the same
labeling convention to the analogous block around lines 154–166 (where
liquidation/other revenue is recorded) so every .add/.addUSDValue call includes
explicit source for fees and source→destination for protocol 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: 56167f78-b2f5-49a7-8923-e037a059effd
📒 Files selected for processing (2)
dexs/hydradx/index.tsfees/hydradx.ts
| // Omnipool has two independent fee types combined in omnipoolFeeVolNorm: | ||
| // Asset fee (≈80% of total): 50% stays in pool → LPs, 50% → Referral pallet (stakers/referrers/traders) | ||
| // Protocol fee (≈20% of total): 100% → Treasury (BurnProtocolFee = 0% in runtime) | ||
| // Ratio approximated from fee ranges: asset 0.15-5%, protocol 0.05-0.25% | ||
| const omnipoolFee = Number(node.omnipoolFeeVolNorm); | ||
| const assetFee = omnipoolFee * 0.8; | ||
| const protocolFee = omnipoolFee * 0.2; | ||
|
|
||
| dailySupplySideRevenue.addUSDValue(assetFee * 0.5, 'Omnipool Asset Fees To LPs'); | ||
| dailyHoldersRevenue.addUSDValue(assetFee * 0.5, 'Omnipool Asset Fees To Stakers & Referrals'); | ||
|
|
||
| // BurnProtocolFee = 0% in runtime (hydration-node/runtime/hydradx/src/assets.rs) | ||
| // 100% of protocol fee goes to Treasury; nothing is burned currently | ||
| dailyProtocolRevenue.addUSDValue(protocolFee, 'Omnipool Protocol Fees To Treasury'); | ||
|
|
||
| dailyProtocolRevenue.addUSDValue(revenueProtocol, 'Omni Pool Fees To Hydration DEX'); | ||
| dailyRevenue.addUSDValue(assetFee * 0.5, 'Omnipool Asset Fees To Stakers & Referrals'); | ||
| dailyRevenue.addUSDValue(protocolFee, 'Omnipool Protocol Fees To Treasury'); |
There was a problem hiding this comment.
The Omnipool split is hardcoded against a fee model that is not fixed.
Hydration’s public docs describe Omnipool asset fees as 50% to LPs and 50% split across stakers/referrers/traders depending on referral state/tier, while protocol fees are described as half burned and half sent to Treasury. The runtime also exposes a non-zero BurnProtocolFee. Hardcoding omnipoolFeeVolNorm into a fixed 80/20 asset/protocol split and then routing all protocol fees to Treasury will overstate dailyRevenue/dailyProtocolRevenue, and booking the whole non-LP asset-fee half into dailyHoldersRevenue also misclassifies referral/trader payouts. (docs.hydration.net)
As per coding guidelines, "Use web search to verify protocol's fee structure if unclear."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@dexs/hydradx/index.ts` around lines 46 - 62, The current code hardcodes an
80/20 asset/protocol split and routes all protocol fees to Treasury and the
entire non‑LP asset half to holders; instead, read the actual runtime/config
values exposed by the node (e.g., fields on node such as omnipoolFeeVolNorm,
BurnProtocolFee, and any referral/trader/staker split or referral tier config)
and compute splits dynamically: compute omnipoolFee from
node.omnipoolFeeVolNorm, derive protocolFee proportion using the runtime
BurnProtocolFee (split protocolFee into burned vs treasury per BurnProtocolFee)
and derive assetFee = omnipoolFee - protocolFee, then record revenues by calling
dailySupplySideRevenue.addUSDValue(assetFee * 0.5, ...) for LPs and allocate the
remaining assetFee * 0.5 across
dailyHoldersRevenue/dailyReferralRevenue/dailyTraderRevenue according to the
runtime referral/tier split (or a configurable fallback if the runtime split is
not present); update dailyProtocolRevenue.addUSDValue to only include the
treasury portion (not the burned portion) and log or expose when you must use a
documented default fallback so the split isn’t silently hardcoded.
There was a problem hiding this comment.
Changes are done according to the actual code. Docs are not up to date with latest changes.
There was a problem hiding this comment.
@green-jay, thanks for the clarification! That makes sense — if the runtime currently has BurnProtocolFee = 0% (as referenced in hydration-node/runtime/hydradx/src/assets.rs) and the docs haven't caught up, then the implementation accurately reflects on-chain behavior. The 80/20 asset/protocol approximation derived from the documented fee ranges (asset: 0.15–5%, protocol: 0.05–0.25%) is a reasonable pragmatic approach given the indexer doesn't expose the split directly.
I'll note this for future reviews.
✏️ Learnings added
Learnt from: green-jay
Repo: DefiLlama/dimension-adapters PR: 6388
File: dexs/hydradx/index.ts:46-62
Timestamp: 2026-04-14T07:51:22.331Z
Learning: In DefiLlama/dimension-adapters, the Hydration DEX (`dexs/hydradx/index.ts`) Omnipool fee split uses a hardcoded 80/20 approximation (assetFee = 80%, protocolFee = 20%) derived from the runtime fee ranges (asset fee: 0.15–5%, protocol fee: 0.05–0.25%). `BurnProtocolFee` is currently set to 0% in the runtime (`hydration-node/runtime/hydradx/src/assets.rs`), so 100% of protocol fees go to Treasury with nothing burned. The official docs may describe an older model (half burned / half treasury) and should not be used as reference. The assetFee is split 50/50 between LPs (`dailySupplySideRevenue`) and stakers/referrals (`dailyHoldersRevenue`).
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: fees/GUIDELINES.md:0-0
Timestamp: 2026-03-30T12:06:41.566Z
Learning: Applies to fees/**/*.ts : Include `dailyHoldersRevenue` dimension when applicable - represents all value to token holders including buybacks, burns, distributions, external airdrops, and bribes
Learnt from: CopsLikeDonuts
Repo: DefiLlama/dimension-adapters PR: 6353
File: fees/thorwallet/index.ts:18-23
Timestamp: 2026-04-08T11:58:26.321Z
Learning: In DefiLlama/dimension-adapters, THORWallet (`fees/thorwallet/index.ts`) collects only affiliate fees from swaps and perpetual close fees. There are no supply-side parties (no LPs, lenders, stakers, or external integrators), so 100% of collected fees are protocol revenue. `dailyRevenue = dailyFees` is correct and intentional. The `dailyProtocolRevenue` (~45%) and `dailyHoldersRevenue` (~50%) entries represent internal allocations, not cost-of-funds, so `dailySupplySideRevenue` should not be added to this adapter.
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: GUIDELINES.md:0-0
Timestamp: 2026-04-03T10:25:08.836Z
Learning: For Fees adapters: must provide `dailyFees` (all fees from all sources - Gross Protocol Revenue), `dailyRevenue` (portion kept by protocol), and when applicable `dailySupplySideRevenue` (portion to LPs, lenders, stakers, integrators, referrers, creators). Optionally provide `dailyUserFees`, `dailyProtocolRevenue`, and `dailyHoldersRevenue`
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: fees/GUIDELINES.md:0-0
Timestamp: 2026-03-30T12:06:41.566Z
Learning: Applies to fees/**/*.ts : Include `dailySupplySideRevenue` dimension when applicable - maps to Cost of Funds and represents portion to LPs, lenders, stakers, integrators, referrers, creators
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: fees/GUIDELINES.md:0-0
Timestamp: 2026-03-30T12:06:41.566Z
Learning: Applies to fees/**/*.ts : Include `dailyProtocolRevenue` dimension when applicable - represents portion allocated to treasury
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: fees/GUIDELINES.md:0-0
Timestamp: 2026-03-30T12:06:41.566Z
Learning: Applies to fees/**/*.ts : Include external tokenholder income in `dailyHoldersRevenue` such as airdrops and bribes from other protocols
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: aggregator-derivatives/GUIDELINES.md:0-0
Timestamp: 2026-03-30T12:05:47.814Z
Learning: Applies to aggregator-derivatives/**/*.{js,ts,tsx} : If the derivatives aggregator charges fees, track `dailyFees` (all fees collected), `dailyRevenue` (aggregator's portion), and `dailySupplySideRevenue` (partner/integration fees) following the guidelines in `fees/GUIDELINES.md`
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-03-30T12:07:15.631Z
Learning: Applies to **/*adapter*.{ts,js} : For fees adapters: verify dailyFees represents Gross Protocol Revenue (all potential fees), dailyRevenue represents Gross Profit (protocol's portion), and dailySupplySideRevenue represents Cost of Funds (supplier payments). Ensure dailyRevenue = dailyFees - dailySupplySideRevenue conceptually.
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: dexs/GUIDELINES.md:0-0
Timestamp: 2026-03-30T12:06:25.918Z
Learning: Applies to dexs/**/*.ts : Track dailyFees, dailyRevenue, and dailySupplySideRevenue dimensions with appropriate breakdown labels and breakdownMethodology when tracking fees/revenue in DEX adapters
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: fees/GUIDELINES.md:0-0
Timestamp: 2026-03-30T12:06:41.566Z
Learning: Applies to fees/**/*.ts : Use source and destination labels for `dailySupplySideRevenue` dimension in fees adapters (e.g., 'Borrow Interest To Lenders', 'Swap Fees To LPs')
Learnt from: 0xCatalyst
Repo: DefiLlama/dimension-adapters PR: 6355
File: fees/neverland.ts:541-541
Timestamp: 2026-04-14T07:31:51.018Z
Learning: In DefiLlama/dimension-adapters, the shared Aave V3 helper (`helpers/aave.ts` `getPoolFees`) records only `flashloanPremiumForProtocol` (derived from `FLASHLOAN_PREMIUM_TO_PROTOCOL`) under the `FLASHLOAN_FEES` breakdown label. The LP/lender share of flashloan premiums is NOT captured under this label — it accrues through the Aave liquidity index and is already reflected in `BORROW_INTEREST`. Consequently, in adapters using this helper (e.g., `fees/neverland.ts`), the `FLASHLOAN_FEES` breakdown description should accurately describe the protocol/treasury portion only, not gross flashloan fees.
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: fees/GUIDELINES.md:0-0
Timestamp: 2026-03-30T12:06:41.566Z
Learning: Ensure `dailyFees` (Gross Protocol Revenue) includes everything the protocol COULD charge, including fees that go to other parties - represents what protocol could theoretically take if they became greedy
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: fees/GUIDELINES.md:0-0
Timestamp: 2026-03-30T12:06:41.566Z
Learning: Applies to fees/**/*.ts : Include `dailyFees` dimension in fees adapters - maps to Gross Protocol Revenue and should include all fees from all sources (total value flow into protocol ecosystem)
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: fees/GUIDELINES.md:0-0
Timestamp: 2026-03-30T12:06:41.566Z
Learning: Applies to fees/**/*.ts : Use distribution type labels for `dailyHoldersRevenue` dimension in fees adapters (e.g., 'Token Buy Back', 'Staking Distributions')
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: GUIDELINES.md:0-0
Timestamp: 2026-04-03T10:25:08.836Z
Learning: Applies to adapters/**/*.ts : Do not use deprecated fields `dailyBribesRevenue` and `dailyTokenTaxes`; put these as sub-sections within `dailyHoldersRevenue` instead
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: fees/GUIDELINES.md:0-0
Timestamp: 2026-03-30T12:06:41.566Z
Learning: Applies to fees/**/*.ts : Include `dailyRevenue` dimension in fees adapters - maps to Gross Profit and should equal `dailyFees - dailySupplySideRevenue` (what protocol keeps)
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: fees/GUIDELINES.md:0-0
Timestamp: 2026-03-30T12:06:41.566Z
Learning: Applies to fees/**/*.ts : Use source and destination labels for `dailyRevenue` dimension in fees adapters (e.g., 'Borrow Interest To Treasury', 'Swap Fees To Protocol')
Learnt from: CR
Repo: DefiLlama/dimension-adapters PR: 0
File: options/GUIDELINES.md:0-0
Timestamp: 2026-03-30T12:07:11.033Z
Learning: If adapter returns fee/revenue dimensions, follow the guidelines in `fees/GUIDELINES.md` - options protocols typically track trading fees (on premium), settlement fees (on exercise/settlement), and vault management fees
|
The hydradx adapter exports: |
|
The hydradx.ts adapter exports: |
| const protocolFee = omnipoolFee * 0.2; | ||
|
|
||
| dailySupplySideRevenue.addUSDValue(assetFee * 0.5, 'Omnipool Asset Fees To LPs'); | ||
| dailyHoldersRevenue.addUSDValue(assetFee * 0.5, 'Omnipool Asset Fees To Stakers & Referrals'); |
There was a problem hiding this comment.
referrals should be supply side revenue, is there any fixed percentage to them/any way to track them? if yes you can add or else leave as it is
There was a problem hiding this comment.
referrals should be supply side revenue, is there any fixed percentage to them/any way to track them? if yes you can add or else leave as it is
There is no way to track it. Our indexer doesn't track referrals. My recommendation: leave as-is. holdersRevenue is the correct bucket for this - the majority recipient is HDX stakers, which is exactly what holdersRevenue represents. Reclassifying to supplySideRevenue would be semantically wrong
|
The hydradx adapter exports: |
|
The hydradx.ts adapter exports: |
No description provided.