Automated yield optimization between Aave V3 and Compound V3 on Arbitrum using TriggerX
Automatically rebalances your USDC between Aave and Compound to maximize yield with zero manual intervention. All transactions execute through a Gnosis Safe wallet for enhanced security.
- Fully Automated - Set it and forget it
- Non-Custodial - You control your funds via Safe wallet
- Gas Efficient - Only rebalances when profitable
- Condition-Based - Triggers only when yield difference exceeds threshold (default: 0.20%)
- Safe Execution - All transactions routed through Gnosis Safe wallet
- Mainnet Ready - Optimized for Arbitrum mainnet deployment
- Monitor: TriggerX continuously checks yield differences via your deployed API
- Analyze: When difference exceeds threshold (default: 0.20%), job triggers
- Execute: Automatically withdraws from lower APY protocol and deposits to higher APY protocol
- Safe Execution: All transactions execute atomically through your Safe wallet
Note: The job is non-recurring - it runs once when the condition is met. Create a new job after execution if you want continuous monitoring.
git clone https://github.com/yourusername/yield-optimizer
cd yield-optimizer
npm installCreate .env file from env.example:
cp env.example .envRequired configuration:
# Arbitrum Mainnet
RPC_URL=https://arb1.arbitrum.io/rpc
CHAIN_ID=42161
# Your wallet (must be Safe owner)
PRIVATE_KEY=your_private_key_here
SAFE_WALLET_ADDRESS=your_safe_address_here
# USDC on Arbitrum
TOKEN_ADDRESS=0xaf88d065e77c8cC2239327C5EDb3A432268e5831
# Yield Optimizer Settings
MIN_YIELD_DIFFERENCE=20 # 20 basis points (0.20%)
CHECK_INTERVAL=60 # Check every 60 seconds
JOB_DURATION=300 # Job duration in seconds
# TriggerX
TRIGGERX_API_KEY=your_api_key_here
MONITOR_URL=https://your-api.com/api/monitor # Must be publicly accessibleIf you don't have a Safe wallet yet:
npm run create-safeThis deploys a Gnosis Safe wallet on Arbitrum mainnet. Save the address to your .env file.
Important: You need ETH in your EOA wallet to deploy the Safe (gas fees).
Fund your Safe wallet with:
- ETH: At least 0.1 ETH for gas fees
- USDC: Your desired deposit amount
Your yield monitoring API must be publicly accessible. The API should return:
{
"aaveApy": 3.45,
"compoundApy": 3.65,
"difference": 20,
"shouldMove": true,
"currentProtocol": "aave",
"betterProtocol": "compound"
}The difference field should be in basis points (e.g., 20 = 0.20%).
Options for deploying:
- Deploy to cloud service (AWS, Heroku, Railway, Vercel, etc.)
- Use ngrok for temporary testing:
./scripts/start-ngrok.sh
./scripts/create-yield-optimizer-job.shOr:
npm startDone! Your yield optimizer job is created and will trigger when the condition is met.
For detailed setup instructions, see MAINNET_WORKFLOW.md
yield-optimizer/
├── src/
│ ├── contracts/
│ │ ├── aave.ts # Aave V3 integration
│ │ ├── compound.ts # Compound V3 integration
│ │ └── arbitrum-config.ts # Arbitrum addresses
│ ├── triggerx-yield-optimizer.ts # Main TriggerX integration
│ ├── yieldMonitor.ts # Yield comparison logic
│ ├── checkBalance.ts # Balance checker
│ ├── createSafeWallet.ts # Safe wallet creation
│ └── verify-safe-wallet.ts # Safe wallet verification
├── scripts/
│ ├── create-yield-optimizer-job.sh # Main job creation script
│ ├── deposit-to-protocol.sh # Deposit utility (for reference)
│ ├── verify-safe-wallet.sh # Verify Safe wallet
│ ├── verify-yield-optimizer.sh # Verify optimizer setup
│ ├── start-ngrok.sh # Temporary public API access
│ └── test-transaction-generation.ts # Test transaction logic
├── foundry/ # Foundry contracts (if needed)
├── .env # Configuration (create from env.example)
├── MAINNET_WORKFLOW.md # Detailed mainnet setup guide
├── package.json
└── README.md # This file
npm run check-yieldsThis compares current APYs from Aave and Compound and shows if rebalancing is needed.
npm run check-balanceShows your USDC balance across:
- Safe wallet
- Aave V3
- Compound V3
npm run verify-safe-walletVerifies that your Safe wallet exists and is properly configured.
ts-node scripts/test-transaction-generation.tsTests the transaction generation logic without creating a TriggerX job.
Scenario: Compound yields 2.8%, Aave yields 2.3%
- Extra yield: 0.5% × $10,000 = $50/year
- Rebalancing: ~4 times/year
- Gas cost: ~$0.14/year (Arbitrum is cheap!)
- Net benefit: ~$49.86/year
The larger your position, the more you save!
Minimum APY difference to trigger rebalancing (in basis points).
20(0.20%): Default - Recommended for most users50(0.50%): Conservative - fewer rebalances, higher gas efficiency10(0.10%): Aggressive - more frequent rebalancing
Note: Consider gas costs when setting this value. On Arbitrum, gas is cheap, so lower thresholds can be profitable.
How often TriggerX checks your API (in seconds). This is informational - TriggerX will poll at its own rate.
60(1 minute): Default300(5 minutes): Less frequent API calls3600(1 hour): Minimal API usage
How long the job remains active (in seconds).
300(5 minutes): Short-term testing2592000(30 days): Standard duration7776000(90 days): Long-term monitoring
- MAINNET_WORKFLOW.md - Complete mainnet setup and deployment guide
- Detailed setup instructions
- Configuration guide
- Troubleshooting
- Security considerations
- TriggerX - Automation platform for condition-based job execution
- Gnosis Safe - Multi-sig wallet for secure transaction execution
- Ethers.js - Ethereum interactions and contract calls
- TypeScript - Type-safe development
- Foundry - Smart contract development (optional)
- Aave V3 - Lending protocol
- Compound V3 - Lending protocol
- Arbitrum - L2 for low gas costs
- Non-custodial - Your keys, your coins
- Safe wallet - Multi-sig security
- Battle-tested protocols - Aave & Compound are audited
- Atomic transactions - All or nothing execution
- Tested thoroughly - Comprehensive test suite
View your job at: https://app.triggerx.network/jobs/YOUR_JOB_ID
Track:
- Execution history
- Gas costs
- Total value optimized
- Success rate
Error: Safe wallet does not exist
- Ensure Safe wallet is deployed on Arbitrum mainnet
- Run
npm run create-safeto create one - Verify
SAFE_WALLET_ADDRESSin.envis correct
Error: Monitor API URL cannot be localhost
- Your API must be publicly accessible
- Deploy to a cloud service or use ngrok temporarily
- Update
MONITOR_URLin.envwith public URL
Error: Insufficient ETH balance
- Need at least 0.01 ETH in your EOA wallet
- Fund your wallet on Arbitrum mainnet
-
Check API Response:
curl https://your-api.com/api/monitor
Should return JSON with
differencefield in basis points. -
Verify Condition: Ensure
difference > MIN_YIELD_DIFFERENCE -
Check Job Status: View job in TriggerX dashboard at https://app.triggerx.network
-
Verify Safe Balance: Ensure Safe has ETH for gas fees
-
Check Job Duration: Non-recurring jobs expire after
JOB_DURATIONseconds
- Insufficient Gas: Fund Safe wallet with ETH
- Insufficient Balance: Check USDC balance in Safe wallet
- Approval Issues: May need to reset token approvals
See MAINNET_WORKFLOW.md for detailed troubleshooting and setup instructions.
| Command | Description |
|---|---|
./scripts/create-yield-optimizer-job.sh |
Create TriggerX yield optimizer job |
npm start |
Alias for job creation (runs triggerx-yield-optimizer.ts) |
npm run check-yields |
Check current APYs from Aave and Compound |
npm run check-balance |
Check USDC balances across protocols |
npm run create-safe |
Create new Safe wallet on Arbitrum mainnet |
npm run verify-safe-wallet |
Verify Safe wallet exists and is valid |
./scripts/verify-yield-optimizer.sh |
Comprehensive setup verification |
./scripts/start-ngrok.sh |
Start ngrok tunnel for temporary public API access |
- Support for more tokens (DAI, USDT, ETH)
- Multi-chain support (Polygon, Optimism)
- More protocols (Curve, Yearn)
- Web dashboard
- Email/Discord notifications
- Advanced strategies (leveraged yield)
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see LICENSE file for details
- TriggerX - Automation platform
- Aave - Lending protocol
- Compound - Lending protocol
- Safe - Smart wallet
Built for DeFi yield optimization
Ready to optimize your yields? Get started now!