diff --git a/great_ape_safe/ape_api/badger.py b/great_ape_safe/ape_api/badger.py index af0e50fd..20d24fd0 100644 --- a/great_ape_safe/ape_api/badger.py +++ b/great_ape_safe/ape_api/badger.py @@ -64,6 +64,9 @@ def __init__(self, safe): self.api_paladin_claim_url = ( f"https://api.paladin.vote/quest/v2/copilot/claims/" ) + self.api_paladin_clawback_incentives_url = ( + f"https://api.paladin.vote/quest/v2/copilot/user/" + ) def claim_all(self, json_file_path=None): """ @@ -224,7 +227,7 @@ def transform_claimable(amount_string, n_decimals): def get_paladin_data(self, address=None): """ - get hidden hand data for a particular address + get paladin data for a particular address for claiming its rewards (merkle tree data) """ address = address if address else self.safe.address url = self.api_paladin_claim_url + address @@ -233,12 +236,24 @@ def get_paladin_data(self, address=None): r.raise_for_status() return r.json()["claims"] + def get_paladin_quests_info(self, address=None): + """ + get paladin data for a particular address related to posted quests + which are closed currently and there may be withdrawable incentives unallocated + """ + address = address if address else self.safe.address + url = self.api_paladin_clawback_incentives_url + address + r = requests.get(url) + if not r.ok: + r.raise_for_status() + return r.json()["quests"] + def claim_bribes_from_paladin(self): """ grabs the available claimable tokens from Paladin endpoint, shape the endpoint information and claims tokens for the safe. """ - data = self.get_paladin_data() + data = [self.get_paladin_data()[-1]] claim_data = [] claim_data_legacy = [] @@ -273,6 +288,19 @@ def claim_bribes_from_paladin(self): if len(claim_data_legacy) > 0: self.paladin_merkle_tree_legacy.multiClaim(self.safe, claim_data_legacy) + def claw_back_incentives_from_paladin(self): + """ + Inspects the quests available in Paladin endpoint for the safe, + check if there are still pending questID, which needs to be claim back. + """ + data = self.get_paladin_quests_info() + + for entry in data: + if int(entry["general"]["withdrawable"]) > 0: + self.safe.contract(entry["general"]["board"]).withdrawUnusedRewards( + entry["general"]["questId"], self.safe + ) + def sweep_reward_token(self, token_addr): """ Sweeps reward token from the vestedCVX strategy into @@ -528,4 +556,4 @@ def pause_deposits(self, vault): assert vault.pausedDeposit() == False vault.pauseDeposits() assert vault.pausedDeposit() - C.print(f"[green]Deposits paused for {vault.name()}[/green]") + C.print(f"[green]Deposits paused for {vault.name()}[/green]") \ No newline at end of file diff --git a/scripts/badger/claw_back_incentives_paladin.py b/scripts/badger/claw_back_incentives_paladin.py new file mode 100644 index 00000000..1086bb48 --- /dev/null +++ b/scripts/badger/claw_back_incentives_paladin.py @@ -0,0 +1,19 @@ +from great_ape_safe import GreatApeSafe +from helpers.addresses import r + + +def main(): + safe = GreatApeSafe(r.badger_wallets.treasury_ops_multisig) + safe.init_badger() + + # tokens + liq = safe.contract(r.treasury_tokens.LIQ) + badger = safe.contract(r.treasury_tokens.BADGER) + + # snap + safe.take_snapshot(tokens=[badger, liq]) + + # check if there are claimable withdrawable incentives in paladin + safe.badger.claw_back_incentives_from_paladin() + + safe.post_safe_tx()