Skip to content

Commit 5f2a553

Browse files
authored
Merge pull request #100 from factorial-finance/main
feat: add Affluent integration
2 parents 7c22536 + 5c86880 commit 5f2a553

5 files changed

Lines changed: 136 additions & 0 deletions

File tree

campaign/campaign.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from web3 import Web3
1818
from constants.evaa import EVAA_USDE_START_BLOCK, EVAA_SUSDE_START_BLOCK
1919
from integrations.stonfi_integration import StonFiIntegration
20+
from integrations.affluent_integration import AffluentIntegration
2021
from integrations.integration import Integration
2122
from integrations.integration_ids import IntegrationID
2223
from integrations.pendle_lpt_integration import PendleLPTIntegration
@@ -48,6 +49,20 @@
4849
chain=Chain.TON,
4950
reward_multiplier=30,
5051
),
52+
AffluentIntegration(
53+
integration_id=IntegrationID.AFFLUENT_USDE,
54+
start_block=AFFLUENT_USDE_START_BLOCK,
55+
summary_cols=[SummaryColumn.AFFLUENT_USDE_PTS],
56+
chain=Chain.TON,
57+
reward_multiplier=20,
58+
),
59+
AffluentIntegration(
60+
integration_id=IntegrationID.AFFLUENT_SUSDE,
61+
start_block=AFFLUENT_SUSDE_START_BLOCK,
62+
summary_cols=[SummaryColumn.AFFLUENT_SUSDE_PTS],
63+
chain=Chain.TON,
64+
reward_multiplier=5,
65+
),
5166
# Template integration
5267
ProtocolNameIntegration(
5368
integration_id=IntegrationID.EXAMPLE,

constants/affluent.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from constants.integration_token import Token
2+
3+
AFFLUENT_USDE_START_BLOCK = 22881841
4+
AFFLUENT_SUSDE_START_BLOCK = 22881841
5+
6+
AFFLUENT_ENDPOINT = "https://api.affluent.org/v2/api"
7+
8+
TOKEN_ADDRESS_MAP = {
9+
Token.USDE: "EQAIb6KmdfdDR7CN1GBqVJuP25iCnLKCvBlJ07Evuu2dzP5f",
10+
Token.SUSDE: "EQDQ5UUyPHrLcQJlPAczd_fjxn8SLrlNQwolBznxCdSlfQwr",
11+
}

constants/summary_columns.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ class SummaryColumn(Enum):
5959

6060
STONFI_USDE_PTS = ("stonfi_usde_pts", SummaryColumnType.ETHENA_PTS)
6161

62+
AFFLUENT_USDE_PTS = ("affluent_usde_pts", SummaryColumnType.ETHENA_PTS)
63+
AFFLUENT_SUSDE_PTS = ("affluent_susde_pts", SummaryColumnType.ETHENA_PTS)
64+
6265
VENUS_SUSDE_PTS = ("venus_susde_pts", SummaryColumnType.ETHENA_PTS)
6366

6467
# EVAA Protocol
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import json
2+
from typing import Dict, List, Optional, Tuple
3+
4+
from constants.affluent import AFFLUENT_ENDPOINT, AFFLUENT_USDE_START_BLOCK, AFFLUENT_SUSDE_START_BLOCK, TOKEN_ADDRESS_MAP
5+
6+
from integrations.l2_delegation_integration import L2DelegationIntegration
7+
from integrations.integration_ids import IntegrationID
8+
from utils.web3_utils import get_block_date
9+
from utils.request_utils import requests_retry_session
10+
from utils.slack import slack_message
11+
from constants.summary_columns import SummaryColumn
12+
from constants.chains import Chain
13+
14+
class AffluentIntegration(L2DelegationIntegration):
15+
def __init__(
16+
self,
17+
integration_id: IntegrationID,
18+
start_block: int,
19+
summary_cols: Optional[List[SummaryColumn]] = None,
20+
chain: Chain = Chain.TON,
21+
reward_multiplier: int = 1,
22+
end_block: Optional[int] = None,
23+
):
24+
super().__init__(
25+
integration_id=integration_id,
26+
start_block=start_block,
27+
chain=chain,
28+
summary_cols=summary_cols if summary_cols else [SummaryColumn.AFFLUENT_USDE_PTS],
29+
reward_multiplier=reward_multiplier,
30+
end_block=end_block,
31+
)
32+
33+
def get_l2_block_balances(
34+
self,
35+
cached_data: Dict[int, Dict[str, float]],
36+
blocks: List[int]
37+
) -> Dict[int, Dict[str, float]]:
38+
try:
39+
block_balances: Dict[int, Dict[str, float]] = {}
40+
41+
for target_block in blocks:
42+
block_balances[target_block] = self.get_participants_data(target_block)
43+
44+
return block_balances
45+
except Exception as e:
46+
err_msg = f"Error fetching Affluent balances at block {target_block}: {e}"
47+
print(err_msg)
48+
slack_message(err_msg)
49+
50+
def get_token_symbol(self):
51+
return self.integration_id.get_token()
52+
53+
def get_participants_data(self, block: int) -> Dict[str, float]:
54+
token = self.get_token_symbol()
55+
token_address = TOKEN_ADDRESS_MAP[token]
56+
block_data: Dict[str, float] = {}
57+
target_date = get_block_date(block, self.chain, adjustment=3600, fmt="%Y-%m-%dT%H:%M:%S")
58+
59+
try:
60+
res = requests_retry_session().get(
61+
AFFLUENT_ENDPOINT + "/holdings",
62+
params={
63+
"assets": token_address,
64+
"timestamp": target_date,
65+
},
66+
timeout=60,
67+
)
68+
payload = res.json()
69+
70+
if payload is None:
71+
raise Exception(f"Error getting participants data for Affluent Protocol token {token} at block {block}: {e}")
72+
73+
for user_data in payload["result"]:
74+
block_data[user_data["user_address"]] = user_data["balance"]
75+
76+
except Exception as e:
77+
err_msg = f"Error getting participants data for Affluent Protocol at block {block}: {e}"
78+
slack_message(err_msg)
79+
80+
return block_data
81+
82+
83+
if __name__ == "__main__":
84+
affluent_integration_usde = AffluentIntegration(
85+
integration_id=IntegrationID.AFFLUENT_USDE,
86+
start_block=AFFLUENT_USDE_START_BLOCK,
87+
summary_cols=[SummaryColumn.AFFLUENT_USDE_PTS],
88+
chain=Chain.TON,
89+
reward_multiplier=20
90+
)
91+
affluent_integration_susde = AffluentIntegration(
92+
integration_id=IntegrationID.AFFLUENT_SUSDE,
93+
start_block=AFFLUENT_SUSDE_START_BLOCK,
94+
summary_cols=[SummaryColumn.AFFLUENT_SUSDE_PTS],
95+
chain=Chain.TON,
96+
reward_multiplier=5
97+
)
98+
99+
print("Affluent USDe :", json.dumps(affluent_integration_usde.get_l2_block_balances(cached_data={}, blocks=[22895215, 22895215 - 600]), indent=2))
100+
print("Affluent sUSDe :", json.dumps(affluent_integration_susde.get_l2_block_balances(cached_data={}, blocks=[22895215]), indent=2))
101+

integrations/integration_ids.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,11 @@ class IntegrationID(Enum):
505505
Token.SUSDE,
506506
)
507507

508+
509+
# Affluent
510+
AFFLUENT_USDE = ("affluent_usde", "Affluent TON USDe", Token.USDE)
511+
AFFLUENT_SUSDE = ("affluent_susde", "Affluent TON sUSDe", Token.SUSDE)
512+
508513
# Silo Finance LP-sUSDe (25 Sep 2025)
509514
SILO_FINANCE_LP_SUSDE_SEP_25_EXPIRY = (
510515
"silo_finance_lp_susde_sep_25_expiry",
@@ -526,6 +531,7 @@ class IntegrationID(Enum):
526531
Token.USDE,
527532
)
528533

534+
529535
def __init__(self, column_name: str, description: str, token: Token = Token.USDE):
530536
self.column_name = column_name
531537
self.description = description

0 commit comments

Comments
 (0)