1- import { BaseAdapter , FetchOptions , SimpleAdapter } from "../../adapters/types" ;
1+ import { FetchOptions , SimpleAdapter } from "../../adapters/types" ;
22import { CHAIN } from "../../helpers/chains" ;
33import { addOneToken } from "../../helpers/prices" ;
44
5- const config : any = {
5+ export const config : any = {
66 [ CHAIN . BSC ] : {
77 wom : "0xAD6742A35fB341A9Cc6ad674738Dd8da98b94Fb1" ,
88 veWom : "0x3DA62816dD31c56D9CdF22C6771ddb892cB5b0Cc" ,
@@ -35,6 +35,12 @@ const config: any = {
3535 zBNB : "0x9a39f4AB3f52026432835dEe6D3DB721D95f3D28" ,
3636 zUSD : "0xC26b7Cbe7e695a0d11a8cB96140D1Cd502945A2C" ,
3737 USDV : "0xC897a2Ae2E45f0D7ba8cbE397208C3e9f8914A9f" ,
38+ CUSD : "0x4dFa92842d05a790252A7f374323b9C86D7b7E12" ,
39+ LINA : "0x84a14A10E7258C68413168c98E905483f9183D7a" ,
40+ StandalonePool : "0x6569DDC1Cc2648c89BC8025046A7dd65EB8940F3" ,
41+ StandalonePool2 : "0xfcd11c01c14e4c12C3F9835CD5192fE774038d46" ,
42+ StandalonePool3 : "0xaded24B510a137b05a8eD958a029DACD6a59efDc" ,
43+ volatilePool : "0x5b573F2E034e37Cc883F2a614BDdC77b07081B6f" ,
3844 } ,
3945 } ,
4046 [ CHAIN . ARBITRUM ] : {
@@ -58,6 +64,10 @@ const config: any = {
5864 crossChainPool : "0xe78876C360716f2225F55A6726B32324FE1B1145" ,
5965 USDV : "0xa6eF6C45EbFDBc13f6D032fbDFeC9b389C1603E5" ,
6066 sFRAX : "0xaBF19eAdb08693278FdbAD35Cb4E3c1D6484c8Bb" ,
67+ fraxUSDV : "0x3cc8c886575968642Cab9F430261c81C5b044d4b" ,
68+ StandalonePool : "0xD64816Fbdf50a1C4AEa456A4006ad21A928305f3" ,
69+ ePendle : "0x3257EaA9C919fe01EF628fe9031BA2Cd8927A3b1" ,
70+ volatilePool : "0x39a2f59875bC636b7eFEcAc30b6E97066a850B1e" ,
6171 } ,
6272 } ,
6373 [ CHAIN . ETHEREUM ] : {
@@ -71,6 +81,9 @@ const config: any = {
7181 ETHx : "0x647CC8816C2d60A5fF4d1ffeF27a5b3637d5ac81" ,
7282 crossChainPool : "0xA45C0ABeef67C363364E0e73832df9986aBa3800" ,
7383 USDV : "0x05A33c0eaf81367Ce953d2dCd4ea1BE8758f4D32" ,
84+ volatilePool : "0x89B88A45E23978b38A14695b63F475d4e4CcaF95" ,
85+ mWOM : "0xcf2e56E086fcD21eaB3614A5A78c8Ae27c2F0536" ,
86+ wmxWOM : "0xe43c1695df76CcA4D6079061924D7150Fd553c21" ,
7487 } ,
7588 } ,
7689 // does not have wom yet
@@ -79,6 +92,7 @@ const config: any = {
7992 veWom : "" ,
8093 pools : {
8194 crossChainPool : "0x80f088ae72DB6d1AC337340cd6Aa0EB1F67337CE" ,
95+ volatilePool : "0x15dcC2da1a73194C9c5BB83ecdA86251F0b1a17F" ,
8296 } ,
8397 } ,
8498 [ CHAIN . AVAX ] : {
@@ -89,6 +103,10 @@ const config: any = {
89103 sAVAX : "0xE3Abc29B035874a9f6dCDB06f8F20d9975069D87" ,
90104 USDV : "0x108c990c93Fa8E3cD88DDb13594D39f09D9B3C02" ,
91105 ggAVAX : "0xBbA43749efC1bC29eA434d88ebaf8A97DC7aEB77" ,
106+ triPool : "0xc12c0Ced34b115655234E8a4dB87EBc8F6F362d0" ,
107+ AUSD : "0x911a98f54da5355EAba1c8D57933ae5493c4223b" ,
108+ Axon : "0x74163B79733AEA2d9C4cED777dc49D591Db739E9" ,
109+ volatilePool : "0x89B88A45E23978b38A14695b63F475d4e4CcaF95" ,
92110 } ,
93111 } ,
94112 [ CHAIN . BASE ] : {
@@ -108,31 +126,161 @@ const config: any = {
108126 frax : "0x6BB82A9b0b9b9716B885baeEfDBE47b685a0F919" ,
109127 dola : "0x489818F2eeAef737105887710F7C5b9323Ad3d01" ,
110128 frxETH : "0xB86BA65b75D34402bf377cF83b184554a18Fcafa" ,
129+ StandalonePool : "0x7B1f9C537efCa25501d15a77Bdc1d23287839623" ,
111130 } ,
112131 } ,
132+ [ CHAIN . POLYGON ] : {
133+ wom : "" ,
134+ veWom : "" ,
135+ pools : {
136+ crossChainPool : "0x4705b477d35112f7B7cA2Bc5059eD9b78bb46134" ,
137+ } ,
138+ } ,
139+ [ CHAIN . MONAD ] : {
140+ wom : "" ,
141+ veWom : "" ,
142+ pools : {
143+ mainPool : "0x25FAa3176efa09658E65853F077810bb2CCa82a4" ,
144+ } ,
145+ } ,
146+ [ CHAIN . HYPERLIQUID ] : {
147+ wom : "" ,
148+ veWom : "" ,
149+ pools : {
150+ mainPool : "0xeF420C965d80fb24A211155a6B489C0D62b7e07a" ,
151+ } ,
152+ } ,
153+ } ;
154+
155+ // Voter contract addresses for chains with governance (for bribes + token incentives)
156+ const voterConfig : Record < string , { voter : string ; } > = {
157+ [ CHAIN . BSC ] : {
158+ voter : "0x04D4e1C1F3D6539071b6D3849fDaED04d48D563d" ,
159+ } ,
160+ [ CHAIN . ARBITRUM ] : {
161+ voter : "0x3f90a5a47364c0467031fB00246192d40E3D2D9D" ,
162+ } ,
163+ [ CHAIN . ETHEREUM ] : {
164+ voter : "0x32A936CbA2629619b46684cDf923CB556f09442c" ,
165+ } ,
113166} ;
114167
168+ async function fetch ( options : FetchOptions ) {
169+ const { chain, getLogs, createBalances, api } = options ;
170+ const pools = Object . values ( config [ chain ] . pools ) as string [ ] ;
171+
172+ const swapAbi = "event Swap (address indexed sender, address fromToken, address toToken, uint256 fromAmount, uint256 toAmount, address indexed to)" ;
173+
174+ // 1. Read haircutRate and lpDividendRatio from each pool
175+ const [ haircutRates , lpDividendRatios ] = await Promise . all ( [
176+ api . multiCall ( { abi : "function haircutRate() view returns (uint256)" , calls : pools } ) . catch ( ( ) => pools . map ( ( ) => "400000000000000" ) ) , // default 4bps
177+ api . multiCall ( { abi : "function lpDividendRatio() view returns (uint256)" , calls : pools } ) . catch ( ( ) => pools . map ( ( ) => "1000000000000000000" ) ) , // default 100%
178+ ] ) ;
179+
180+ // 2. Compute per-pool volume, fees, and revenue split
181+ const dailyVolume = createBalances ( ) ;
182+ const dailyFees = createBalances ( ) ;
183+ const dailySupplySideRevenue = createBalances ( ) ;
184+ const dailyProtocolRevenue = createBalances ( ) ;
185+
186+ const perPoolLogs = await Promise . all (
187+ pools . map ( ( pool ) => getLogs ( { target : pool , eventAbi : swapAbi } ) . catch ( ( ) => [ ] ) )
188+ ) ;
189+
190+ for ( let i = 0 ; i < pools . length ; i ++ ) {
191+ const poolLogs = perPoolLogs [ i ] ;
192+ const hr = Number ( haircutRates [ i ] ) / 1e18 ;
193+ const lpRatio = Number ( lpDividendRatios [ i ] ) / 1e18 ;
194+
195+ const poolVolume = createBalances ( ) ;
196+ poolLogs . forEach ( ( log : any ) => {
197+ addOneToken ( { chain, balances : poolVolume , token0 : log . fromToken , amount0 : log . fromAmount , token1 : log . toToken , amount1 : log . toAmount } ) ;
198+ } ) ;
199+
200+ dailyVolume . addBalances ( poolVolume ) ;
201+ const poolFees = poolVolume . clone ( hr ) ;
202+ dailyFees . addBalances ( poolFees ) ;
203+ dailySupplySideRevenue . addBalances ( poolFees . clone ( lpRatio ) ) ;
204+ dailyProtocolRevenue . addBalances ( poolFees . clone ( 1 - lpRatio ) ) ;
205+ }
206+
207+ // 5. Bribes: OnReward events from BribeV2 contracts (via Voter)
208+ const dailyBribesRevenue = createBalances ( ) ;
209+ if ( voterConfig [ chain ] ) {
210+ const { voter } = voterConfig [ chain ] ;
211+
212+ // Get all asset (LP token) addresses from pools, then look up bribes from Voter
213+ const allUnderlyingTokens = await api . multiCall ( {
214+ abi : "address[]:getTokens" ,
215+ calls : pools ,
216+ } ) . catch ( ( ) => [ ] ) ;
217+
218+ const assetCalls : { target : string ; params : string } [ ] = [ ] ;
219+ allUnderlyingTokens . forEach ( ( tokens : string [ ] , poolIdx : number ) => {
220+ ( tokens || [ ] ) . forEach ( ( token : string ) => {
221+ assetCalls . push ( { target : pools [ poolIdx ] , params : token } ) ;
222+ } ) ;
223+ } ) ;
224+
225+ if ( assetCalls . length > 0 ) {
226+ const assetAddresses = await api . multiCall ( {
227+ abi : "function addressOfAsset(address) view returns (address)" ,
228+ calls : assetCalls ,
229+ } ) . catch ( ( ) => [ ] ) ;
230+
231+ // Look up bribe address for each asset from Voter
232+ const infoCalls = assetAddresses
233+ . filter ( ( a : string ) => a && a !== "0x0000000000000000000000000000000000000000" ) ;
234+
235+ if ( infoCalls . length > 0 ) {
236+ const infos = await api . multiCall ( {
237+ abi : "function infos(address) view returns (uint104 supplyBaseIndex, uint104 supplyVoteIndex, uint40 nextEpochStartTime, uint128 claimable, bool whitelist, address gaugeManager, address bribe)" ,
238+ calls : infoCalls . map ( ( a : string ) => ( { target : voter , params : a } ) ) ,
239+ } ) . catch ( ( ) => [ ] ) ;
240+
241+ const bribeAddresses = infos
242+ . map ( ( info : any ) => info ?. bribe )
243+ . filter ( ( b : string ) => b && b !== "0x0000000000000000000000000000000000000000" ) ;
244+
245+ if ( bribeAddresses . length > 0 ) {
246+ // Get OnReward events from all bribe contracts
247+ const bribeLogs = await getLogs ( {
248+ targets : bribeAddresses ,
249+ eventAbi : "event OnReward(address indexed rewardToken, address indexed user, uint256 amount)" ,
250+ } ) . catch ( ( ) => [ ] ) ;
251+
252+ bribeLogs . forEach ( ( log : any ) => {
253+ dailyBribesRevenue . add ( log . rewardToken , log . amount ) ;
254+ } ) ;
255+ }
256+ }
257+ }
258+ }
259+
260+ return {
261+ dailyVolume,
262+ dailyFees,
263+ dailyUserFees : dailyFees ,
264+ dailySupplySideRevenue,
265+ dailyProtocolRevenue,
266+ dailyRevenue : dailyProtocolRevenue ,
267+ dailyBribesRevenue,
268+ } ;
269+ }
270+
115271const adapter : SimpleAdapter = {
116272 version : 2 ,
117273 pullHourly : true ,
118- adapter : { } ,
274+ fetch,
275+ chains : Object . keys ( config ) ,
276+ methodology : {
277+ Fees : "Swap fees paid by users (haircutRate applied to each swap)." ,
278+ UserFees : "Same as Fees — all swap fees are paid by the user." ,
279+ SupplySideRevenue : "Share of fees distributed to LPs, determined by the pool's lpDividendRatio." ,
280+ ProtocolRevenue : "Share of fees retained by the protocol (tip bucket + feeTo), i.e. 1 - lpDividendRatio." ,
281+ HoldersRevenue : "Not applicable." ,
282+ Revenue : "Same as ProtocolRevenue." ,
283+ } ,
119284} ;
120285
121- Object . keys ( config ) . forEach ( ( chain ) => {
122- ( adapter . adapter as BaseAdapter ) [ chain ] = { fetch }
123- } )
124-
125286export default adapter ;
126-
127-
128- async function fetch ( { chain, getLogs, createBalances, } : FetchOptions ) {
129- const pools = Object . values ( config [ chain ] . pools )
130- const dailyVolume = createBalances ( )
131- const eventAbi = "event Swap (address indexed sender, address fromToken, address toToken, uint256 fromAmount, uint256 toAmount, address indexed to)"
132- const logs = await getLogs ( { targets : pools as any , eventAbi } )
133- logs . forEach ( ( log : any ) => {
134- const { fromToken, toToken, fromAmount, toAmount } = log
135- addOneToken ( { chain, balances : dailyVolume , token0 : fromToken , amount0 : fromAmount , token1 : toToken , amount1 : toAmount } )
136- } )
137- return { dailyVolume, dailyFees : dailyVolume . clone ( 0.0004 ) }
138- }
0 commit comments