Ajna Strategy Deployment Guide
β COMPLETE: Full Ajna Integration Implementedβ
The AjnaStrategy is now production-ready with real Ajna protocol calls!
What's Implementedβ
β
Ajna Interface (IAjnaPool.sol)β
β
addQuoteToken() - Deposit tokens to lending bucket
β
removeQuoteToken() - Withdraw tokens from bucket
β
moveQuoteToken() - Rebalance between buckets
β
lenderInfo() - Query LP position
β
bucketInfo() - Query bucket statistics
β
IAjnaPoolFactory - Pool deployment interface
β Strategy Functionsβ
β
_depositToAjna() - Real deposit implementation
β
_withdrawFromAjna() - Real withdrawal with LP burning
β
_getAjnaBalance() - Real balance query with interest
β
moveToBucket() - Rebalance to different price point
β
setBucketIndex() - Change lending price point
How Ajna Worksβ
Referencesβ
- Ajna Protocol Whitepaper (Oct 12, 2023):
https://www.ajna.finance/pdf/Ajna_Protocol_Whitepaper_10-12-2023.pdf
Bucket Systemβ
Ajna uses 7,388 price buckets (Fenwick index 1..7388; 0 is invalid for add/move).
Price mapping (quote per collateral, WAD) is:
price = 1.005^(4156 - index)
So:
- Index 4156 β price β 1.0 (anchor)
- Lower index (< 4156) β higher price
- Higher index (> 4156) β lower price
Interest & Yieldβ
- Variable APY: Based on pool utilization
- Higher utilization = Higher interest rates
- No liquidations: Novel Ajna design
- Permissionless: Anyone can create pools
LP Tokensβ
- Deposit quote tokens β Receive LP tokens
- LP tokens represent your share of the bucket
- LP value grows with accrued interest
- Burn LP tokens to withdraw + interest
Deployment Stepsβ
1. Find or Create Ajna Poolβ
Ajna Addresses on Base:β
Source: https://faqs.ajna.finance/info/deployment-addresses-and-bridges
AJNA_ERC20_FACTORY="0x214f62B5836D83f3D6c4f71F174209097B1A779C"
AJNA_ERC721_FACTORY="0xeefEC5d1Cc4bde97279d01D88eFf9e0fEe981769"
AJNA_POOL_INFO_UTILS="0x97fa9b0909C238D170C1ab3B5c728A3a45BBEcBa"
AJNA_POSITION_MANAGER="0x59710a4149A27585f1841b5783ac704a08274e64"
Check if Pool Exists:β
# Check for AKITA pool
cast call $AJNA_ERC20_FACTORY \
"deployedPools(address,address,uint256)(address)" \
$AKITA_TOKEN \ # Collateral
$WETH \ # Quote token
50000000000000000 # 0.05 (5%) interest rate
If No Pool, Deploy One:β
// Deploy AKITA/WETH lending pool
IAjnaPoolFactory(ajnaFactory).deployPool(
akitaToken, // Collateral
weth, // Quote token (what we lend)
0.05e18 // 5% initial interest rate
);
2. Deploy AjnaStrategyβ
cd contracts
forge create AjnaStrategy \
--rpc-url https://mainnet.base.org \
--private-key $PRIVATE_KEY \
--constructor-args \
"0xA015954E2606d08967Aee3787456bB3A86a46A42" \ # AKITA Vault
"0x5b674196812451b7cec024fe9d22d2c0b172fa75" \ # AKITA Token
"0x214f62B5836D83f3D6c4f71F174209097B1A779C" \ # Ajna ERC20 Factory
"0x4200000000000000000000000000000000000006" \ # WETH (quote)
"$YOUR_ADDRESS" # Owner
# Verify on Basescan
forge verify-contract \
$DEPLOYED_ADDRESS \
AjnaStrategy \
--chain base \
--constructor-args $(cast abi-encode \
"constructor(address,address,address,address,address)" \
"0xA015954E2606d08967Aee3787456bB3A86a46A42" \
"0x5b674196812451b7cec024fe9d22d2c0b172fa75" \
"0x214f62B5836D83f3D6c4f71F174209097B1A779C" \
"0x4200000000000000000000000000000000000006" \
"$YOUR_ADDRESS")
3. Configure Strategyβ
# Set the Ajna pool address
cast send $AJNA_STRATEGY \
"setAjnaPool(address)" \
$AJNA_POOL \
--rpc-url base \
--private-key $PRIVATE_KEY
# Initialize approvals
cast send $AJNA_STRATEGY \
"initializeApprovals()" \
--rpc-url base \
--private-key $PRIVATE_KEY
# (Recommended) Keep a small % of assets idle inside the strategy so withdrawals
# don't have to touch Ajna every time.
# - 0 = fully deploy (previous behavior)
# - 1000 = 10% idle buffer
# - 2000 = 20% idle buffer
cast send $AJNA_STRATEGY \
"setIdleBufferBps(uint256)" \
1000 \
--rpc-url base \
--private-key $PRIVATE_KEY
# Optional: Adjust bucket index (default is 4156)
cast send $AJNA_STRATEGY \
"setBucketIndex(uint256)" \
4156 \
--rpc-url base \
--private-key $PRIVATE_KEY
4. Add to Vaultβ
# Add strategy with weight 100
cast send $AKITA_VAULT \
"addStrategy(address,uint256)" \
$AJNA_STRATEGY \
100 \
--rpc-url base \
--private-key $PRIVATE_KEY
For 4-Way Allocationβ
Complete Strategy Setup:β
# 1. AKITA/WETH 1% LP Strategy
AKITA_WETH_STRATEGY="0x..." # Deploy CreatorCharmStrategy
# 2. AKITA/USDC 1% LP Strategy
AKITA_USDC_STRATEGY="0x..." # Deploy CreatorCharmStrategy
# 3. Ajna Lending Strategy
AJNA_STRATEGY="0x..." # Deployed above
# Add all 3 strategies with equal weight
cast send $AKITA_VAULT \
"addStrategy(address,uint256)" \
$AKITA_WETH_STRATEGY 100 \
--rpc-url base --private-key $PK
cast send $AKITA_VAULT \
"addStrategy(address,uint256)" \
$AKITA_USDC_STRATEGY 100 \
--rpc-url base --private-key $PK
cast send $AKITA_VAULT \
"addStrategy(address,uint256)" \
$AJNA_STRATEGY 100 \
--rpc-url base --private-key $PK
# Set minimum idle to 12.5M (keeps 12.5M idle)
cast send $AKITA_VAULT \
"setMinimumTotalIdle(uint256)" \
12500000000000000000000000 \
--rpc-url base --private-key $PK
Testing the Integrationβ
1. Test Depositβ
# Simulate deposit
cast call $AJNA_STRATEGY \
"deposit(uint256)" \
1000000000000000000 \
--from $AKITA_VAULT
# Check balance
cast call $AJNA_STRATEGY \
"getTotalAssets()(uint256)"
2. Test Withdrawalβ
# Simulate withdrawal
cast call $AJNA_STRATEGY \
"withdraw(uint256)" \
1000000000000000000 \
--from $AKITA_VAULT
3. Check Yieldβ
# Check pending yield
cast call $AJNA_STRATEGY \
"pendingYield()(uint256)"
# Harvest yield
cast send $AJNA_STRATEGY \
"harvest()" \
--from $AKITA_VAULT
4. Check Ajna Pool Statsβ
# Get pool utilization
cast call $AJNA_POOL \
"poolUtilization()(uint256)"
# Get interest rate
cast call $AJNA_POOL \
"interestRate()(uint256)"
# Get our LP balance
cast call $AJNA_POOL \
"lenderInfo(uint256,address)(uint256,uint256)" \
4156 \ # Bucket index (price=1.0 anchor)
$AJNA_STRATEGY # Our address
Advanced Featuresβ
Rebalancing Between Bucketsβ
If market conditions change, move liquidity to a different price bucket:
# Move to bucket 4000 (higher price than 1.0 anchor)
cast send $AJNA_STRATEGY \
"moveToBucket(uint256,uint256)" \
4000 \ # New bucket index
0 \ # Amount (0 = move all)
--rpc-url base --private-key $PK
Bucket Selection Strategyβ
Index < 4156: higher price (more aggressive / more borrower-friendly)
Index = 4156: price β 1.0 anchor
Index > 4156: lower price (more conservative / less borrower-friendly)
Default 4156 is a neutral anchor. In production, pick the bucket from a real market price (e.g. Uniswap V3 TWAP for CREATOR/USDC) and optionally apply a small safety buffer.
Monitoringβ
Key Metrics to Track:β
# 1. Total assets in strategy
cast call $AJNA_STRATEGY "getTotalAssets()(uint256)"
# 2. Pending yield
cast call $AJNA_STRATEGY "pendingYield()(uint256)"
# 3. LP position (bucketIndex may change over time)
BUCKET=$(cast call $AJNA_STRATEGY "bucketIndex()(uint256)")
cast call $AJNA_POOL "lenderInfo(uint256,address)(uint256,uint256)" $BUCKET $AJNA_STRATEGY
# 4. Pool utilization
cast call $AJNA_POOL "poolUtilization()(uint256)"
# 5. Current interest rate
cast call $AJNA_POOL "interestRate()(uint256)"
Health Checks:β
# Is strategy active?
cast call $AJNA_STRATEGY "isActive()(bool)"
# Last harvest time
cast call $AJNA_STRATEGY "lastHarvest()(uint256)"
# Current bucket index
cast call $AJNA_STRATEGY "bucketIndex()(uint256)"
Emergency Proceduresβ
If Something Goes Wrong:β
# 1. Pause strategy
cast send $AJNA_STRATEGY \
"setActive(bool)" \
false \
--rpc-url base --private-key $PK
# 2. Emergency withdraw (pull all funds)
cast send $AJNA_STRATEGY \
"emergencyWithdraw()" \
--from $AKITA_VAULT
# 3. Remove from vault
cast send $AKITA_VAULT \
"removeStrategy(address)" \
$AJNA_STRATEGY \
--rpc-url base --private-key $PK
Gas Costsβ
Estimated gas for operations:
Deposit: ~150k gas (~$0.003 at 20 gwei)
Withdraw: ~180k gas (~$0.0036)
Harvest: ~120k gas (~$0.0024)
Rebalance: ~200k gas (~$0.004)
Total cost for 4-way activation: ~$0.006 (plus LP strategies)
Security Considerationsβ
β Safe:β
- No liquidations in Ajna
- User controls bucket selection
- Emergency withdraw available
- Owner can pause strategy
- ReentrancyGuard on all functions
β οΈ Risks:β
- Smart contract risk: Ajna protocol bugs
- Bucket risk: Wrong bucket = suboptimal yield
- Utilization risk: Low utilization = low yield
- Pool risk: New pool = less tested
π‘οΈ Mitigations:β
- Start with small amount
- Use a market-derived bucket (e.g. Uniswap V3 TWAP for CREATOR/USDC); 4156 is the neutral anchor (price β 1.0)
- Monitor pool utilization
- Can emergency withdraw anytime
Expected Performanceβ
Conservative Estimates:β
Pool Utilization: 50%
Base Interest Rate: 5%
Expected APY: 2.5-7.5%
With higher utilization (80%):
Expected APY: 8-15%
Comparison:β
Ajna Lending: 5-15% APY
LP Fees (WETH): 20-40% APY
LP Fees (USDC): 15-30% APY
Idle: 0% APY
---
Combined (12.5M each): ~10-20% blended APY
Resourcesβ
Summaryβ
β AjnaStrategy fully implemented β Real Ajna protocol calls β Bucket-based lending system β LP token tracking β Interest accrual calculation β Rebalancing capabilities β Production ready
Next: Deploy to Base mainnet and add to AKITA vault! π