Skip to content

Commit 8748a4c

Browse files
NebulaNomadPixelclaudebheluga
authored
feat: add LunarBase PMM volume adapter (#6286)
* feat: add LunarBase PMM volume adapter Track daily swap volume and fees for LunarBase CurvePMM pool on Base (ETH/USDC). Reads SwapExecuted events from the pool contract. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add fee/revenue breakdown to LunarBase adapter Track dailySupplySideRevenue and dailyProtocolRevenue. Reads treasuryShareBps dynamically from the CurvePMM contract. Currently 100% of fees go to LPs (treasuryShareBps = 0). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * add breakdowns and pullhourly --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: bheluga <bheluga@defillama.com>
1 parent 955a0fe commit 8748a4c

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

dexs/lunarbase/index.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { FetchOptions, SimpleAdapter } from "../../adapters/types";
2+
import { CHAIN } from "../../helpers/chains";
3+
import { addOneToken } from "../../helpers/prices";
4+
import { METRIC } from "../../helpers/metrics";
5+
6+
const CURVE_PMM = "0x6Ccc8223532fff07f47EF4311BEB3647326894Ab";
7+
8+
const swapEvent =
9+
"event SwapExecuted(address recipient, bool xToY, uint256 dx, uint256 dy, uint256 fee)";
10+
11+
const fetch = async (options: FetchOptions) => {
12+
const dailyVolume = options.createBalances();
13+
const dailyFees = options.createBalances();
14+
const dailySupplySideRevenue = options.createBalances();
15+
const dailyProtocolRevenue = options.createBalances();
16+
17+
const [tokenX, tokenY, treasuryShareBps, BPS] = await Promise.all([
18+
options.api.call({ target: CURVE_PMM, abi: "address:X" }),
19+
options.api.call({ target: CURVE_PMM, abi: "address:Y" }),
20+
options.api.call({ target: CURVE_PMM, abi: "uint24:treasuryShareBps" }),
21+
options.api.call({ target: CURVE_PMM, abi: "uint256:BPS" }),
22+
]);
23+
24+
const logs = await options.getLogs({
25+
target: CURVE_PMM,
26+
eventAbi: swapEvent,
27+
});
28+
29+
const tBps = Number(treasuryShareBps);
30+
const totalBps = Number(BPS);
31+
32+
for (const log of logs) {
33+
const { xToY, dx, dy, fee } = log;
34+
addOneToken({ chain: options.chain, balances: dailyVolume, token0: tokenX, token1: tokenY, amount0: dx, amount1: dy });
35+
36+
// Fee is taken from the output side: xToY → fee in Y, yToX → fee in X
37+
const feeToken = xToY ? tokenY : tokenX;
38+
const feeBig = BigInt(fee);
39+
dailyFees.add(feeToken, feeBig, METRIC.SWAP_FEES);
40+
41+
// Split: treasury gets treasuryShareBps/BPS, LPs get the rest
42+
const protocolFee = totalBps > 0 ? (feeBig * BigInt(tBps)) / BigInt(totalBps) : 0n;
43+
const supplySideFee = feeBig - protocolFee;
44+
dailyProtocolRevenue.add(feeToken, protocolFee, METRIC.SWAP_FEES);
45+
dailySupplySideRevenue.add(feeToken, supplySideFee, METRIC.SWAP_FEES);
46+
}
47+
48+
return {
49+
dailyVolume,
50+
dailyFees,
51+
dailyUserFees: dailyFees,
52+
dailySupplySideRevenue,
53+
dailyProtocolRevenue,
54+
dailyRevenue: dailyProtocolRevenue,
55+
};
56+
};
57+
58+
const methodology = {
59+
Volume: "The amount of tokens that are swapped through the protocol.",
60+
Fees: "Fees that are collected for each swap transaction.",
61+
UserFees: "Fees that are paid by the users",
62+
SupplySideRevenue: "The portion of fees that goes to the liquidity providers.",
63+
Revenue: "The portion of fees that going to the protocol.",
64+
ProtocolRevenue: "All the revenue goes to the protocol.",
65+
};
66+
67+
const breakdownMethodology = {
68+
Fees: {
69+
[METRIC.SWAP_FEES]: "Fees that are collected for each swap transaction.",
70+
},
71+
UserFees: {
72+
[METRIC.SWAP_FEES]: "Swap fees that are paid by the users.",
73+
},
74+
SupplySideRevenue: {
75+
[METRIC.SWAP_FEES]: "Swap fees that goes to the liquidity providers.",
76+
},
77+
ProtocolRevenue: {
78+
[METRIC.SWAP_FEES]: "Swap fees that goes to the protocol.",
79+
},
80+
Revenue: {
81+
[METRIC.SWAP_FEES]: "Swap fees that going to the protocol.",
82+
},
83+
};
84+
const adapter: SimpleAdapter = {
85+
version: 2,
86+
pullHourly: true,
87+
fetch,
88+
chains: [CHAIN.BASE],
89+
start: "2026-03-19",
90+
methodology,
91+
breakdownMethodology,
92+
};
93+
94+
export default adapter;

0 commit comments

Comments
 (0)