Skip to main content

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! πŸš€