hikari reapplication for defi Llama#5789
Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📝 WalkthroughWalkthroughA new TypeScript fee/revenue adapter for the Hikari pool and staking contracts on the Katana chain. It ingests on-chain events (STAKED, KATANA_CLAIMED, FEE, REWARD_CLAIMED), maps rewards to USD, applies a fixed revenue-splitting model, and produces daily aggregates for user fees, protocol revenue, total revenue, and supply-side revenue. Changes
Sequence Diagram(s)sequenceDiagram
participant Adapter as Adapter (fees/hikari.ts)
participant RPC as Blockchain RPC
participant Staking as Staking Contract
participant Pool as Pool Contract
participant Price as Price Oracle
Adapter->>RPC: query logs (STAKED, KATANA_CLAIMED, FEE, REWARD_CLAIMED)
RPC->>Staking: return staking logs
RPC->>Pool: return pool logs
Adapter->>Price: request token price for ausd/KATANA
Price-->>Adapter: return USD prices
Adapter->>Adapter: convert amounts, apply split (ausd / 0.03, 70% user/revenue), aggregate daily metrics
Adapter-->>Consumer: expose dailyUserFees, dailyFees, dailyProtocolRevenue, dailyRevenue, dailySupplySideRevenue
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
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 hikari.ts adapter exports: |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@dexs/hikari.ts`:
- Around line 28-31: The equality check in logs.forEach comparing log.recipient
to BASELINE_CONTRACT is case-sensitive and can miss matches; update the
comparison to normalize both sides (e.g., toLowerCase()) before comparing so
that log.recipient.toLowerCase() === BASELINE_CONTRACT.toLowerCase() is used,
ensuring dailyFees.add(AUSD_TOKEN, log.amount0) runs for matching addresses;
adjust any related references to BASELINE_CONTRACT or log.recipient comparisons
in this block to use the same normalization.
- Around line 33-37: The volume calculation currently divides swapLog.amount0 by
1e6 and calls dailyVolume.addUSDValue, which bypasses the framework pricing;
instead update the swapLogs.forEach handler to call dailyVolume.add with
AUSD_TOKEN and the absolute raw amount (use Math.abs on swapLog.amount0) so it
matches the fee pattern (dailyFees.add(AUSD_TOKEN, ...)) and lets the framework
handle token decimals and USD conversion; locate the swapLogs.forEach block and
replace the addUSDValue/division logic with dailyVolume.add(AUSD_TOKEN,
Math.abs(swapLog.amount0)).
🧹 Nitpick comments (3)
dexs/hikari.ts (3)
4-6: Minor naming inconsistency.
hikariPooluses camelCase while the other constants use SCREAMING_SNAKE_CASE. Consider renaming toHIKARI_POOLfor consistency.
39-43:dailyRevenuereferences the same object asdailyFees.Assigning
dailyRevenue: dailyFeesmeans both properties reference the sameBalancesobject. If the framework mutates one after return, it will affect the other. If revenue should always equal fees for this protocol, consider creating a separate balances object or cloning.♻️ Proposed fix: clarify intent with a comment or separate object
If the intent is that revenue equals fees:
+ // Revenue equals 100% of fees for this protocol return { dailyFees, dailyRevenue: dailyFees, dailyVolume: dailyVolume, };Or create a separate balances object if independence is needed:
+ const dailyRevenue = options.createBalances(); + logs.forEach((log) => { + if (log.recipient.toLowerCase() === BASELINE_CONTRACT.toLowerCase()) + dailyRevenue.add(AUSD_TOKEN, log.amount0); + }); + return { dailyFees, - dailyRevenue: dailyFees, + dailyRevenue, dailyVolume: dailyVolume, };
53-58: Replacefetch: fetch as anywith properly typed fetch implementation.The
as anytype cast masks type errors. WhileCHAIN.KATANAis correctly defined in helpers/chains.ts, the fetch handler should use explicit typing instead of type casting, matching patterns used throughout the codebase (e.g., async functions withFetchOptionsparameter or helper functions likegetUniV2LogAdapter).
dexs/hikari.ts
Outdated
| logs.forEach((log) => { | ||
| if (log.recipient === BASELINE_CONTRACT) | ||
| dailyFees.add(AUSD_TOKEN, log.amount0); | ||
| }); |
There was a problem hiding this comment.
Case-sensitive address comparison will likely fail.
Ethereum addresses returned from event logs may be in different case formats (lowercase or checksummed). The strict equality check log.recipient === BASELINE_CONTRACT will fail if the cases don't match, causing fees to be silently ignored.
🐛 Proposed fix: normalize addresses to lowercase
logs.forEach((log) => {
- if (log.recipient === BASELINE_CONTRACT)
+ if (log.recipient.toLowerCase() === BASELINE_CONTRACT.toLowerCase())
dailyFees.add(AUSD_TOKEN, log.amount0);
});📝 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.
| logs.forEach((log) => { | |
| if (log.recipient === BASELINE_CONTRACT) | |
| dailyFees.add(AUSD_TOKEN, log.amount0); | |
| }); | |
| logs.forEach((log) => { | |
| if (log.recipient.toLowerCase() === BASELINE_CONTRACT.toLowerCase()) | |
| dailyFees.add(AUSD_TOKEN, log.amount0); | |
| }); |
🤖 Prompt for AI Agents
In `@dexs/hikari.ts` around lines 28 - 31, The equality check in logs.forEach
comparing log.recipient to BASELINE_CONTRACT is case-sensitive and can miss
matches; update the comparison to normalize both sides (e.g., toLowerCase())
before comparing so that log.recipient.toLowerCase() ===
BASELINE_CONTRACT.toLowerCase() is used, ensuring dailyFees.add(AUSD_TOKEN,
log.amount0) runs for matching addresses; adjust any related references to
BASELINE_CONTRACT or log.recipient comparisons in this block to use the same
normalization.
dexs/hikari.ts
Outdated
| swapLogs.forEach((swapLog) => { | ||
| const amount0 = Number(swapLog.amount0) / 1e6; | ||
| if (amount0 > 0) dailyVolume.addUSDValue(amount0); | ||
| else dailyVolume.addUSDValue(-amount0); | ||
| }); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Check how other DEX adapters handle swap volume calculations
rg -n -A5 'addUSDValue' --glob 'dexs/*.ts' | head -100Repository: DefiLlama/dimension-adapters
Length of output: 5165
🏁 Script executed:
# Check for similar swap patterns with amount0/amount1
rg -n -B2 -A5 'Swap.*amount0.*amount1' --glob 'dexs/*.ts' | head -100Repository: DefiLlama/dimension-adapters
Length of output: 7132
🏁 Script executed:
# Look at the full hikari.ts file to understand AUSD token configuration
cat dexs/hikari.tsRepository: DefiLlama/dimension-adapters
Length of output: 1850
🏁 Script executed:
# Check if there are any token configurations or decimal references for AUSD
rg -n 'AUSD\|amount0\|1e6' dexs/hikari.tsRepository: DefiLlama/dimension-adapters
Length of output: 54
Fix volume calculation to match fee handling and use the framework's token mechanism.
The code divides amount0 by 1e6 and passes it to addUSDValue, but this is inconsistent with how fees are correctly handled using dailyFees.add(AUSD_TOKEN, log.amount0). The swap event's amount0 is a raw contract value, not a USD value—dividing by an arbitrary decimal count does not convert it to USD. This bypasses the framework's pricing mechanism.
Use dailyVolume.add(AUSD_TOKEN, Math.abs(swapLog.amount0)) to match the fee calculation pattern and let the framework handle token decimals and USD conversion properly.
🤖 Prompt for AI Agents
In `@dexs/hikari.ts` around lines 33 - 37, The volume calculation currently
divides swapLog.amount0 by 1e6 and calls dailyVolume.addUSDValue, which bypasses
the framework pricing; instead update the swapLogs.forEach handler to call
dailyVolume.add with AUSD_TOKEN and the absolute raw amount (use Math.abs on
swapLog.amount0) so it matches the fee pattern (dailyFees.add(AUSD_TOKEN, ...))
and lets the framework handle token decimals and USD conversion; locate the
swapLogs.forEach block and replace the addUSDValue/division logic with
dailyVolume.add(AUSD_TOKEN, Math.abs(swapLog.amount0)).
noateden
left a comment
There was a problem hiding this comment.
hi, why are you counting Uniswap pool swaps as volume for hikari?
|
The hikari.ts adapter exports: |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@fees/hikari.ts`:
- Around line 52-54: The code is passing raw token amounts into
dailyRevenue.addUSDValue by iterating feesLogs and using feeLog.amount0; confirm
whether amount0 is a USD-denominated value (e.g. AUSD with 1:1 peg and proper
decimals) and if not, convert the token amount to USD before calling
dailyRevenue.addUSDValue: look up the token of the Collect event (feeLog token
identifier), normalize decimals for amount0, fetch or compute the token USD
price (use existing pricing helpers or oracle functions), multiply normalized
amount0 by price to get USD, and only then call dailyRevenue.addUSDValue; if
AUSD is guaranteed to be 1:1 ensure decimal normalization is applied instead of
raw amount0.
- Around line 69-75: The returned object leaves dailyFees empty; populate
dailyFees from feesLogs the same way dailyRevenue is derived so fees collected
from Collect events are reported. Locate the processing of feesLogs and the
variables dailyUserFees, dailyRevenue and dailyFees inside the function (where
feesLogs is iterated and dailyRevenue is computed) and add logic to accumulate
per-day fee amounts into dailyFees (mirroring the aggregation used for
dailyRevenue), then return the populated dailyFees alongside dailyUserFees and
dailyRevenue.
🧹 Nitpick comments (3)
fees/hikari.ts (3)
11-18: Remove unused event definitions.
SWAP_EVENTandUNSTAKED_EVENTare defined but never used in the fetch function. Consider removing them to reduce confusion about what events the adapter actually processes.🧹 Proposed cleanup
-const SWAP_EVENT = - "event Swap(address indexed sender, address indexed recipient, int256 amount0, int256 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick)"; - const STAKED_EVENT = "event Staked(address user, uint256 amount, address pool, uint256 time)"; -const UNSTAKED_EVENT = - "event Unstaked(address user, uint256 amount, address pool, uint256 time, uint256 matureTime)"; - const REWARD_CLAIMED_EVENT =
32-35: Remove unused log fetch.
stakedLogsis fetched but never used in the function. This is a wasted RPC call and dead code.🧹 Proposed cleanup
- const stakedLogs = await options.getLogs({ - target: hikariStaking, - eventAbi: STAKED_EVENT, - }); - const katanaLogs = await options.getLogs({
89-89: Avoidas anytype cast.Casting to
anybypasses TypeScript's type safety and can mask legitimate type errors. If there's a type mismatch with the expected fetch function signature, consider fixing the return type or using a more specific type assertion.
| feesLogs.forEach((feeLog) => { | ||
| dailyRevenue.addUSDValue(feeLog.amount0); | ||
| }); |
There was a problem hiding this comment.
Verify amount0 is actually a USD value.
addUSDValue() expects a value denominated in USD, but amount0 from the Collect event is the raw token amount collected (likely in token decimals). If the collected token is not a USD-pegged stablecoin with 1:1 value, this will produce incorrect revenue figures.
Consider whether you need to convert amount0 to USD using token pricing, or if AUSD is indeed 1:1 pegged with appropriate decimal handling.
🤖 Prompt for AI Agents
In `@fees/hikari.ts` around lines 52 - 54, The code is passing raw token amounts
into dailyRevenue.addUSDValue by iterating feesLogs and using feeLog.amount0;
confirm whether amount0 is a USD-denominated value (e.g. AUSD with 1:1 peg and
proper decimals) and if not, convert the token amount to USD before calling
dailyRevenue.addUSDValue: look up the token of the Collect event (feeLog token
identifier), normalize decimals for amount0, fetch or compute the token USD
price (use existing pricing helpers or oracle functions), multiply normalized
amount0 by price to get USD, and only then call dailyRevenue.addUSDValue; if
AUSD is guaranteed to be 1:1 ensure decimal normalization is applied instead of
raw amount0.
| return { | ||
| dailyUserFees, | ||
| dailyFees, | ||
| dailyProtocolRevenue: dailyUserFees, | ||
| dailyRevenue, | ||
| dailySupplySideRevenue, | ||
| }; |
There was a problem hiding this comment.
dailyFees is never populated.
dailyFees is initialized on line 28 but never has any values added to it. It's returned empty, which means the adapter will always report 0 for daily fees despite the methodology claiming to track "Fees collected from the Hikari pool's Concentrated Liquidity."
Was this intentional, or should dailyFees be populated from feesLogs similar to dailyRevenue?
🐛 Possible fix if dailyFees should mirror dailyRevenue from Collect events
feesLogs.forEach((feeLog) => {
+ dailyFees.addUSDValue(feeLog.amount0);
dailyRevenue.addUSDValue(feeLog.amount0);
});🤖 Prompt for AI Agents
In `@fees/hikari.ts` around lines 69 - 75, The returned object leaves dailyFees
empty; populate dailyFees from feesLogs the same way dailyRevenue is derived so
fees collected from Collect events are reported. Locate the processing of
feesLogs and the variables dailyUserFees, dailyRevenue and dailyFees inside the
function (where feesLogs is iterated and dailyRevenue is computed) and add logic
to accumulate per-day fee amounts into dailyFees (mirroring the aggregation used
for dailyRevenue), then return the populated dailyFees alongside dailyUserFees
and dailyRevenue.
|
The hikari.ts adapter exports: |
hello I readjust and resubmit it as Yield Platforms, sorry for the hassle. Kindly see and correct it if you need necessary detail |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@fees/hikari.ts`:
- Around line 66-69: The code is dividing katanaLog.tokens by 1e6 before calling
dailySupplySideRevenue.add, but add expects raw token amounts (the framework
normalizes decimals), so remove the manual normalization; pass katanaLog.tokens
(or Number(katanaLog.tokens)) directly to
dailySupplySideRevenue.add(KATANA_TOKEN, ...) inside the katanaLogs.forEach loop
to match how rewardClaimedLog.ausd is passed.
🧹 Nitpick comments (3)
fees/hikari.ts (3)
12-19: Unused event definitions:SWAP_EVENTandUNSTAKED_EVENT.These event ABIs are defined but never used anywhere in the code. If they're not needed for the current implementation, consider removing them to reduce dead code. If they're intended for future use, this may indicate incomplete implementation.
🧹 Remove unused event definitions
-const SWAP_EVENT = - "event Swap(address indexed sender, address indexed recipient, int256 amount0, int256 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick)"; - const STAKED_EVENT = "event Staked(address user, uint256 amount, address pool, uint256 time)"; -const UNSTAKED_EVENT = - "event Unstaked(address user, uint256 amount, address pool, uint256 time, uint256 matureTime)"; -
33-36:stakedLogsis fetched but never used.The logs are retrieved from the staking contract but are never processed or used in any calculations. This is either dead code (unnecessary RPC call) or indicates missing logic to incorporate staking data into the metrics.
🧹 Remove unused fetch if not needed
- const stakedLogs = await options.getLogs({ - target: hikariStaking, - eventAbi: STAKED_EVENT, - }); -
57-64: Fee calculation logic is undocumented and potentially confusing.The calculation assumes
rewardClaimedis 3% oftotalFees, then allocates 70% to user fees. This reverse-engineering of fees from rewards is non-obvious and should be documented:rewardClaimedLogs.forEach((rewardClaimedLog) => { const rewardClaimed = Number(rewardClaimedLog.ausd) / 1e6; + // Reward claimed represents 3% of total fees; back-calculate total fees const totalFees = rewardClaimed / 0.03; + // 70% of total fees are attributed to users const userFees = totalFees * 0.7;Also verify: is the 0.03 (3%) and 0.7 (70%) split documented in Hikari's fee structure?
|
The hikari.ts adapter exports: |
NOTE
Please enable "Allow edits by maintainers" while putting up the PR.
package.json/package-lock.jsonfile as part of your changesName (to be shown on DefiLlama):
Hikari Finance
Twitter Link:
https://x.com/hikari_finance
List of audit links if any:
https://hashlock.com/audits/hikari-finance
Website Link:
https://hikari.finance/
Logo (High resolution, will be shown with rounded borders):
KARI Logo.png.zip
Current TVL:
$ 1.185k
Treasury Addresses (if the protocol has treasury)
https://katanascan.com/address/0x2ac7673c3a0370de512a20464a800fa7c53235c3 (Liquidity Pool).
Chain:
Katana
Coingecko ID (so your TVL can appear on Coingecko, leave empty if not listed): (https://api.coingecko.com/api/v3/coins/list)
Coinmarketcap ID (so your TVL can appear on Coinmarketcap, leave empty if not listed): (https://api.coinmarketcap.com/data-api/v3/map/all?listing_status=active,inactive,untracked&start=1&limit=10000)
Short Description (to be shown on DefiLlama):
DeFi protocol that turns idle liquidity into yield while protecting token value with AUSD-backed floors.
Token address and ticker if any:
0xC2473b16fE99BE558Cd246cC3B610574534EfDB9 and KARI
Category (full list at https://defillama.com/categories) *Please choose only one:
Yield
Oracle Provider(s): Specify the oracle(s) used (e.g., Chainlink, Band, API3, TWAP, etc.):
Uniswap TWAP Oracle
Implementation Details: Briefly describe how the oracle is integrated into your project:
Price Feed for AUSD/KARI
Documentation/Proof: Provide links to documentation or any other resources that verify the oracle's usage:
Implementation on the contract to get the price feed.
forkedFrom (Does your project originate from another project):
Uniswap V3's Concentrated Liquidity
methodology (what is being counted as tvl, how is tvl being calculated):
TVL is calculated from the current marketcap of AUSD inside the liquidity pool.
https://katanascan.com/address/0x2ac7673c3a0370de512a20464a800fa7c53235c3
Github org/user (Optional, if your code is open source, we can track activity):
Does this project have a referral program?
No
Summary by CodeRabbit