11from typing import Dict , Optional , Tuple , Any , List
22import pandas as pd
3+ from web3 import Web3
34from .base import BribePlatform
45from bal_tools .safe_tx_builder import SafeContract
56import json
67from pathlib import Path
8+ from fee_allocator .logger import logger
79
810
911class PaladinPlatform (BribePlatform ):
@@ -80,17 +82,69 @@ def process_bribes(self, bribes_df: pd.DataFrame, builder: Any, usdc: Any) -> No
8082
8183
8284 def validate_gauge_requirements (self , gauge_address : str ) -> Tuple [bool , Optional [str ]]:
83- """No validation needed for ROLLOVER close type"""
85+ base_dir = Path (__file__ ).parent .parent
86+ with open (f"{ base_dir } /abi/gauge.json" , "r" ) as f :
87+ gauge_abi = json .load (f )
88+
89+ w3 = self .run_config .mainnet .web3
90+ usdc = Web3 .to_checksum_address (self .usdc_address )
91+ gauge = Web3 .to_checksum_address (gauge_address )
92+ contract = w3 .eth .contract (address = gauge , abi = gauge_abi )
93+
94+ reward_tokens = [contract .functions .reward_tokens (i ).call () for i in range (8 )]
95+ if usdc not in reward_tokens :
96+ return False , f"USDC ({ usdc } ) not found in gauge reward tokens"
97+
98+ distributor = contract .functions .reward_data (usdc ).call ()[1 ]
99+ if distributor .lower () not in [self .bal_quest_board .lower (), self .aura_quest_board .lower ()]:
100+ return False , f"Incorrect distributor { distributor } . Expected: { self .bal_quest_board } or { self .aura_quest_board } "
101+
84102 return True , None
85103
86104 @property
87105 def platform_name (self ) -> str :
88- """Platform identifier for reporting"""
89106 return "paladin"
90107
91108 @property
92109 def supported_markets (self ) -> List [str ]:
93110 return ["aura" , "balancer" ]
94111
95112 def get_platform_for_market (self , market : str , voting_pool_override : Optional [str ]) -> str :
96- return "paladin"
113+ return "paladin"
114+
115+ def check_all_gauge_requirements (self , pools : List [Any ]) -> List [Dict ]:
116+ """Check all Paladin gauges for requirements and return issues"""
117+
118+ gauges_with_issues = []
119+
120+ for pool in pools :
121+ if pool .market_override != "paladin" :
122+ continue
123+
124+ valid , error_msg = self .validate_gauge_requirements (pool .gauge_address )
125+ if not valid :
126+ action_needed = []
127+
128+ if pool .to_bal_incentives_usd > 0 :
129+ action_needed .append (f"Balancer distributor ({ self .bal_quest_board } )" )
130+ if pool .to_aura_incentives_usd > 0 :
131+ action_needed .append (f"Aura distributor ({ self .aura_quest_board } )" )
132+
133+ if action_needed :
134+ if "not found in gauge reward tokens" in error_msg :
135+ action_msg = f"Add USDC ({ self .usdc_address } ) as reward token and set { ' and ' .join (action_needed )} "
136+ elif "Incorrect distributor" in error_msg :
137+ action_msg = f"Set { ' and ' .join (action_needed )} "
138+ else :
139+ action_msg = error_msg
140+
141+ logger .warning (f"Paladin gauge { pool .gauge_address } missing requirements: { action_msg } " )
142+ gauges_with_issues .append ({
143+ "gauge" : pool .gauge_address ,
144+ "pool_id" : pool .pool_id ,
145+ "chain" : pool .chain .name ,
146+ "action" : action_msg ,
147+ "amount" : float (pool .total_to_incentives_usd )
148+ })
149+
150+ return gauges_with_issues
0 commit comments