Delegate independent tasks to specialized agents working concurrently with isolated context.
Claim Voting Rewards Safe Batch Generator
claim-rewards
Generate Safe UI compatible multisig batch JSON to claim voting rewards (internal LP fees and external bribes). Use when the user wants to claim bribes, collect voting rewards, or prepare claim transactions for a multisig wallet.
SKILL.md
Full skill instructions
Claim Voting Rewards Safe Batch Generator
Generate Safe Transaction Builder compatible JSON for claiming all voting rewards (internal LP fees and external bribes) on the Lithos protocol.
Prerequisites
- The
.envfile must containRPC_URLfor Plasma mainnet - The owner address must be a multisig that owns veNFTs or has claimable rewards
Contract Addresses (Plasma Mainnet)
- Voter:
0x2AF460a511849A7aA37Ac964074475b0E6249c69 - VotingEscrow:
0x2Eff716Caa7F9EB441861340998B0952AF056686 - Chain ID:
9745
Key Concepts
Internal vs External Bribes
- Internal bribes (LP fees): Trading fees from liquidity provision, claimed via
claimFees() - External bribes: Third-party incentives for voting, claimed via
claimBribes()
Reward Ownership
Rewards accrue to the owner address, not individual veNFT tokenIds. The owner can claim all rewards in a single batch transaction.
Instructions
Step 1: Get all pools and gauges
# Get number of pools
source .env && cast call 0x2AF460a511849A7aA37Ac964074475b0E6249c69 "length()(uint256)" --rpc-url $RPC_URL
# Get pool at index
source .env && cast call 0x2AF460a511849A7aA37Ac964074475b0E6249c69 "pools(uint256)(address)" <INDEX> --rpc-url $RPC_URL
# Get gauge for pool
source .env && cast call 0x2AF460a511849A7aA37Ac964074475b0E6249c69 "gauges(address)(address)" <POOL_ADDRESS> --rpc-url $RPC_URL
Step 2: Get bribe contracts for each gauge
# Get internal bribe (LP fees)
source .env && cast call 0x2AF460a511849A7aA37Ac964074475b0E6249c69 "internal_bribes(address)(address)" <GAUGE_ADDRESS> --rpc-url $RPC_URL
# Get external bribe
source .env && cast call 0x2AF460a511849A7aA37Ac964074475b0E6249c69 "external_bribes(address)(address)" <GAUGE_ADDRESS> --rpc-url $RPC_URL
Step 3: Get reward tokens for each bribe
# Get number of reward tokens
source .env && cast call <BRIBE_ADDRESS> "rewardsListLength()(uint256)" --rpc-url $RPC_URL
# Get reward token at index
source .env && cast call <BRIBE_ADDRESS> "rewardTokens(uint256)(address)" <INDEX> --rpc-url $RPC_URL
Step 4: Check claimable amounts
# Check earned amount for owner
source .env && cast call <BRIBE_ADDRESS> "earned(address,address)(uint256)" <OWNER_ADDRESS> <TOKEN_ADDRESS> --rpc-url $RPC_URL
# IMPORTANT: Check bribe contract has sufficient balance
source .env && cast call <TOKEN_ADDRESS> "balanceOf(address)(uint256)" <BRIBE_ADDRESS> --rpc-url $RPC_URL
CRITICAL: Only include rewards where bribe_balance >= earned_amount. Underfunded bribes will cause the transaction to revert with "ERC20: transfer amount exceeds balance".
Step 5: Generate claim calldata
For internal bribes (LP fees):
cast calldata "claimFees(address[],address[][])" "[<BRIBE1>,<BRIBE2>,...]" "[[<TOKEN1A>,<TOKEN1B>],[<TOKEN2A>],...]"
For external bribes:
cast calldata "claimBribes(address[],address[][])" "[<BRIBE1>,<BRIBE2>,...]" "[[<TOKEN1A>,<TOKEN1B>],[<TOKEN2A>],...]"
Step 6: Create Safe batch JSON
Generate a JSON file with this structure:
{
"version": "1.0",
"chainId": "9745",
"createdAt": <UNIX_TIMESTAMP>,
"meta": {
"name": "Claim All Voting Rewards for <SHORT_ADDRESS>...",
"description": "Claim all internal (LP fees) and external bribes across <NUM_BRIBES> bribe contracts for address <FULL_ADDRESS>",
"txBuilderVersion": "1.16.5"
},
"transactions": [
{
"to": "0x2AF460a511849A7aA37Ac964074475b0E6249c69",
"value": "0",
"data": "<CLAIM_FEES_CALLDATA>",
"contractMethod": {
"inputs": [
{ "internalType": "address[]", "name": "_fees", "type": "address[]" },
{ "internalType": "address[][]", "name": "_tokens", "type": "address[][]" }
],
"name": "claimFees",
"payable": false
},
"contractInputsValues": {
"_fees": "[<BRIBE_ADDRESSES>]",
"_tokens": "[[<TOKEN_ARRAYS>]]"
}
},
{
"to": "0x2AF460a511849A7aA37Ac964074475b0E6249c69",
"value": "0",
"data": "<CLAIM_BRIBES_CALLDATA>",
"contractMethod": {
"inputs": [
{ "internalType": "address[]", "name": "_bribes", "type": "address[]" },
{ "internalType": "address[][]", "name": "_tokens", "type": "address[][]" }
],
"name": "claimBribes",
"payable": false
},
"contractInputsValues": {
"_bribes": "[<BRIBE_ADDRESSES>]",
"_tokens": "[[<TOKEN_ARRAYS>]]"
}
}
]
}
Step 7: Write to file
Save the JSON to safe-txs/safe.claim-bribes-<OWNER_SHORT>.json.
Using the Script
There is an existing script that automates this process:
npx tsx scripts/claimAllBribesForAddress.ts <OWNER_ADDRESS>
This script:
- Enumerates all 25+ gauges
- Gets internal and external bribes for each
- Checks all reward tokens and claimable amounts
- Verifies bribe contracts have sufficient balance (skips underfunded)
- Generates Safe batch JSON with
claimFeesandclaimBribestransactions - Outputs a summary of claimable and skipped rewards
Verification
Simulate the transactions before executing:
# Simulate claimFees
source .env && cast call 0x2AF460a511849A7aA37Ac964074475b0E6249c69 "<CLAIM_FEES_CALLDATA>" --from <OWNER_ADDRESS> --rpc-url $RPC_URL
# Simulate claimBribes
source .env && cast call 0x2AF460a511849A7aA37Ac964074475b0E6249c69 "<CLAIM_BRIBES_CALLDATA>" --from <OWNER_ADDRESS> --rpc-url $RPC_URL
Example Usage
User: "Claim all voting rewards for 0x495a98fd059551385Fc9bAbBcFD88878Da3A1b78"
- Run the script or manually enumerate all gauges
- Find claimable rewards:
- vAMM-WXPL/USDT0 (internal): 15,625 WXPL, 3,196 USDT0
- sAMM-msUSD/USDT0 (external): 3,330 USDT0
- vAMM-WXPL/LITH (internal): 91 WXPL, 3,719 LITH
- etc.
- Skip underfunded bribes (e.g., ELITE bribe with insufficient balance)
- Generate
safe-txs/safe.claim-bribes-0x495a98.json - Simulate both transactions
- Report success with rewards breakdown
Common Token Addresses
| Token | Address | Decimals |
|---|---|---|
| WXPL | 0x6100E367285b01F48D07953803A2d8dCA5D19873 | 18 |
| USDT0 | 0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb | 6 |
| LITH | 0xAbB48792A3161E81B47cA084c0b7A22a50324A44 | 18 |
| USDe | 0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34 | 18 |
| msUSD | 0x29AD7fE4516909b9e498B5a65339e54791293234 | 18 |
| WETH | 0x9895D81bB462A195b4922ED7De0e3ACD007c32CB | 18 |
| ebUSD | 0xEf7B1A03E0897C33b63159e38d779e3970C0E2fc | 18 |
| ELITE | 0x30C8Cf6B46AA4DF3F9fbC2857aca92F10a6cAd7f | 18 |
Common Mistakes to Avoid
-
Including underfunded bribes - Always check
balanceOf(bribe)>=earned(owner, token). Underfunded bribes will revert the entire batch. -
Including tokens with 0 claimable - Only include tokens where
earned() > 0. -
Using wrong address - Verify the owner address actually owns veNFTs or has earned rewards.
-
Missing reward tokens - Check ALL reward tokens in each bribe contract, not just the first one.
Notes
- Rewards accrue to the owner address, not individual tokenIds
- Internal bribes are LP trading fees (claimFees)
- External bribes are third-party incentives (claimBribes)
- Both can be batched into a single Safe transaction
- Always simulate before executing to catch revert conditions
- Underfunded bribes are a known issue - skip them and report to protocol team
More Other skills
brand-guidelines
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
theme-factory
Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.
internal-comms
A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.).
Fundamental design principles for writing maintainable, testable Python code.
responsive-design
Modern responsive layouts using container queries, fluid typography, CSS Grid, and mobile-first strategies.
Generate Playwright tests from scenarios using interactive browser exploration and validation.
Automated website exploration and test case generation using Playwright.
Modern React state management with Redux Toolkit, Zustand, Jotai, and React Query for every state category.
gdpr-data-handling
GDPR-compliant data handling with consent management, data subject rights, and privacy controls.
Python error handling patterns including input validation, exception hierarchies, and partial failure handling. Use when implementing validation logic, designing exception strategies, handling batch processing failures, or building robust APIs.
refactor-plan
Detailed multi-file refactor planning with safety checks and rollback guidance.
