Skip to content
This repository was archived by the owner on Apr 14, 2026. It is now read-only.

Commit a18187d

Browse files
committed
calc v3 pool fees
1 parent db7445f commit a18187d

3 files changed

Lines changed: 62 additions & 44 deletions

File tree

fee_allocator/accounting/chains.py

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -244,17 +244,24 @@ def _fetch_and_process_pool_fee_data(self) -> list[PoolFeeData]:
244244

245245
pools_data = []
246246

247-
core_pools_to_process = (
247+
core_pools_list = (
248248
[(pool_id, label) for pool_id, label in self.core_pools_list.items()]
249249
if self.core_pools_list is not None
250250
else self.bal_pools_gauges.core_pools
251251
)
252252

253-
for pool_id, label in core_pools_to_process:
253+
v3_pools = [(p, l) for p, l in core_pools_list if len(p) == 42]
254+
v2_pools = [x for x in core_pools_list if x not in v3_pools]
255+
256+
for pool_id, label in v3_pools:
257+
pool_fee_data = self._fetch_twap_prices_and_init_pool_fee_data_v3(pool_id, label, pool_to_gauge)
258+
pools_data.append(pool_fee_data)
259+
260+
for pool_id, label in v2_pools:
254261
start_snap = self._get_latest_snapshot(start_snaps, pool_id)
255262
end_snap = self._get_latest_snapshot(end_snaps, pool_id)
256-
if self._should_add_pool(pool_id, start_snap, end_snap):
257-
pool_fee_data = self._fetch_twap_prices_and_init_pool_fee_data(pool_id, label, pool_to_gauge, start_snap, end_snap)
263+
if self._should_add_pool(pool_id, start_snap, end_snap, pool_to_gauge):
264+
pool_fee_data = self._fetch_twap_prices_and_init_pool_fee_data_v2(pool_id, label, pool_to_gauge, start_snap, end_snap)
258265
pools_data.append(pool_fee_data)
259266

260267
return pools_data
@@ -274,14 +281,15 @@ def _create_pool_to_gauge_mapping(self, pools: list[Pool]) -> Dict[str, str]:
274281
return pool_to_gauge
275282

276283
def _should_add_pool(
277-
self, pool_id: str, start_snap: PoolSnapshot, end_snap: PoolSnapshot
284+
self, pool_id: str, start_snap: PoolSnapshot, end_snap: PoolSnapshot, pool_to_gauge: Dict[str, str]
278285
) -> bool:
279286
return (
280287
start_snap and end_snap
281288
and self.bal_pools_gauges.has_alive_preferential_gauge(pool_id)
289+
and pool_to_gauge.get(pool_id)
282290
)
283291

284-
def _fetch_twap_prices_and_init_pool_fee_data(
292+
def _fetch_twap_prices_and_init_pool_fee_data_v2(
285293
self,
286294
pool_id: str,
287295
label: str,
@@ -312,6 +320,31 @@ def _fetch_twap_prices_and_init_pool_fee_data(
312320
end_pool_snapshot=end_snap,
313321
last_join_exit_ts=last_join_exit_ts,
314322
)
323+
324+
def _fetch_twap_prices_and_init_pool_fee_data_v3(
325+
self,
326+
pool_id: str,
327+
label: str,
328+
pool_to_gauge: Dict[str, str],
329+
) -> PoolFeeData:
330+
logger.info(f"fetching twap prices for {label} on {self.name}")
331+
332+
try:
333+
last_join_exit_ts = self.bal_pools_gauges.get_last_join_exit(pool_id)
334+
except NoResultError:
335+
last_join_exit_ts = 0
336+
337+
return PoolFeeData(
338+
pool_id=pool_id,
339+
address=pool_id,
340+
symbol=label,
341+
tokens_price=None,
342+
gauge_address=pool_to_gauge[pool_id],
343+
start_pool_snapshot=None,
344+
end_pool_snapshot=None,
345+
last_join_exit_ts=last_join_exit_ts,
346+
total_earned_fees_usd_twap=self.subgraph.get_v3_protocol_fees(pool_id, self.name, self.chains.date_range),
347+
)
315348

316349
@staticmethod
317350
def _get_latest_snapshot(

fee_allocator/accounting/core_pools.py

Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
from __future__ import annotations
22
from dataclasses import dataclass, field
3-
from web3 import Web3
43
from typing import List, Dict, TYPE_CHECKING
54
from decimal import Decimal
6-
from datetime import datetime
75

86
from bal_tools.models import PoolSnapshot, TWAPResult
97
from fee_allocator.accounting.interfaces import AbstractPoolFee
@@ -32,55 +30,41 @@ class PoolFeeData:
3230
pool_id: str
3331
address: str
3432
symbol: str
35-
bpt_price: Decimal
3633
tokens_price: List[TWAPResult]
3734
gauge_address: str
3835
start_pool_snapshot: PoolSnapshot
3936
end_pool_snapshot: PoolSnapshot
4037
last_join_exit_ts: int
41-
42-
earned_bpt_fee: Decimal = field(init=False)
43-
earned_bpt_fee_usd_twap: Decimal = field(init=False)
44-
earned_tokens_fee: Dict[str, Decimal] = field(init=False)
45-
earned_tokens_fee_usd_twap: Decimal = field(init=False)
46-
total_earned_fees_usd_twap: Decimal = field(init=False)
38+
bpt_price: Decimal = field(default=Decimal(0))
39+
total_earned_fees_usd_twap: Decimal = None
4740

4841
def __post_init__(self):
49-
self.earned_bpt_fee = self._set_earned_bpt_fee()
50-
self.earned_bpt_fee_usd_twap = self._set_earned_bpt_fee_usd_twap()
51-
self.earned_tokens_fee = self._set_earned_tokens_fee()
52-
self.earned_tokens_fee_usd_twap = self._set_earned_tokens_fee_usd_twap()
53-
self.total_earned_fees_usd_twap = self._set_total_earned_fees_usd_twap()
54-
55-
def _set_earned_bpt_fee(self) -> Decimal:
56-
return (
42+
if len(self.pool_id) == 42:
43+
# v3 pool; earned fees already calculated
44+
if self.total_earned_fees_usd_twap is None:
45+
raise ValueError(f"v3 pool {self.pool_id} must have total_earned_fees_usd_twap set. got {self.total_earned_fees_usd_twap}")
46+
else:
47+
# v2 pool
48+
self.total_earned_fees_usd_twap = self._set_total_earned_fees_usd_twap_v2()
49+
50+
def _set_total_earned_fees_usd_twap_v2(self) -> Decimal:
51+
bpt_fee = (
5752
self.end_pool_snapshot.totalProtocolFeePaidInBPT
5853
- self.start_pool_snapshot.totalProtocolFeePaidInBPT
5954
)
55+
if bpt_fee > 0:
56+
return self.bpt_price * bpt_fee
6057

61-
def _set_earned_bpt_fee_usd_twap(self) -> Decimal:
62-
return self.bpt_price * self.earned_bpt_fee
63-
64-
def _set_earned_tokens_fee(self) -> Dict[str, Decimal]:
65-
return {
66-
end_token.address: Decimal(
67-
end_token.paidProtocolFees - start_token.paidProtocolFees
68-
)
69-
for start_token, end_token in zip(
70-
self.start_pool_snapshot.tokens, self.end_pool_snapshot.tokens
71-
)
72-
}
73-
74-
def _set_earned_tokens_fee_usd_twap(self) -> Decimal:
7558
return sum(
76-
token.twap_price * fee
77-
for fee, token in zip(self.earned_tokens_fee.values(), self.tokens_price)
78-
if fee > 0
59+
token.twap_price * Decimal(end_token.paidProtocolFees - start_token.paidProtocolFees)
60+
for end_token, start_token, token in zip(
61+
self.end_pool_snapshot.tokens,
62+
self.start_pool_snapshot.tokens,
63+
self.tokens_price
64+
)
65+
if end_token.paidProtocolFees > start_token.paidProtocolFees
7966
)
8067

81-
def _set_total_earned_fees_usd_twap(self) -> Decimal:
82-
return self.earned_bpt_fee_usd_twap + self.earned_tokens_fee_usd_twap
83-
8468

8569
class PoolFee(AbstractPoolFee, PoolFeeData):
8670
"""

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ gql[requests]
77
pandas==2.0.3
88
numpy==1.26.4
99
json-fix
10-
git+https://github.com/BalancerMaxis/bal_addresses@main
10+
# git+https://github.com/BalancerMaxis/bal_addresses@main
11+
git+https://github.com/BalancerMaxis/bal_tools@v3-pool-fees

0 commit comments

Comments
 (0)