Skip to content
Open
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
97 changes: 97 additions & 0 deletions fees/hikari.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { FetchOptions, SimpleAdapter } from "../adapters/types";
import { CHAIN } from "../helpers/chains";

const KATANA_TOKEN = "0x7F1f4b4b29f5058fA32CC7a97141b8D7e5ABDC2d";
const hikariPool = "0x2ac7673C3a0370dE512A20464a800fa7C53235C3";
const hikariStaking = "0xeCA16687491B0D748C6246645f56AAE787474f3b";
const AUSD_TOKEN = "0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a";

const FEE_EVENT =
"event Collect(address indexed owner, address recipient, int24 indexed tickLower, int24 indexed tickUpper, uint128 amount0, uint128 amount1)";

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 =
"event RewardClaimed(address user, uint256 ausd, address pool, uint256 time, address ausd_)"; // ausd_ is the reward token for the user

const KATANA_CLAIMED_EVENT =
"event KatanaClaimed(address sender, address vault, uint256 tokens, uint256 acc)";

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

const stakedLogs = await options.getLogs({
target: hikariStaking,
eventAbi: STAKED_EVENT,
});

const katanaLogs = await options.getLogs({
target: hikariStaking,
eventAbi: KATANA_CLAIMED_EVENT,
});

const feesLogs = await options.getLogs({
target: hikariPool,
eventAbi: FEE_EVENT,
});

const rewardClaimedLogs = await options.getLogs({
target: hikariStaking,
eventAbi: REWARD_CLAIMED_EVENT,
});

feesLogs.forEach((feeLog) => {
dailyRevenue.addUSDValue(feeLog.amount0);
});
Comment on lines +53 to +55
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

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.


rewardClaimedLogs.forEach((rewardClaimedLog) => {
const rewardClaimed = Number(rewardClaimedLog.ausd) / 1e6;
const totalFees = rewardClaimed / 0.03;
const userFees = totalFees * 0.7;
dailyUserFees.addUSDValue(userFees);
dailyRevenue.addUSDValue(userFees);
dailySupplySideRevenue.add(AUSD_TOKEN, rewardClaimedLog.ausd);
});

katanaLogs.forEach((katanaLog) => {
const katana = Number(katanaLog.tokens);
dailySupplySideRevenue.add(KATANA_TOKEN, katana);
});

return {
dailyUserFees,
dailyFees,
dailyProtocolRevenue: dailyUserFees,
dailyRevenue,
dailySupplySideRevenue,
};
Comment on lines +71 to +77
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

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.

};

const adapter: SimpleAdapter = {
methodology: {
Fees: "Fees collected from the Hikari pool's Concentrated Liquidity.",
Revenue: "Revenue collected from fees and yield from the staking contract.",
UserFees: "User fees collected from the staking contract.",
SupplySideRevenue:
"Supply side revenue collected from the staking contract in Katana tokens and AUSD tokens.",
},
version: 2,
adapter: {
[CHAIN.KATANA]: {
fetch: fetch as any,
start: "2025-07-08",
},
},
};

export default adapter;
29 changes: 24 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading