AgentLoan

SMART CONTRACTS

Technical reference for AgentLoan smart contracts deployed on Arc Testnet.

Network
All contracts are deployed on Arc Testnet (Chain ID: 5042002). Block explorer: testnet.arcscan.app

CONTRACT ADDRESSES

ContractAddress
LendingPool v30xA5F8E24a5a97e9cA763D0FB4777786B684Aceb9B
PriceOraclePyth v30x440B0f69AADd464d88ED205191ed1a45374bCCF6
AgentExecutor0x81E1d5F98e2804be55190610Dcb6DbB71E9CABdA
InterestRateStrategy0x22B2A153F7694e49096ef91D627a80c5b6602Ffd
xUSDC (testnet)0xFa090bd1A524D861542888B6c5e7965dde1F4f35
xEURC (testnet)0x11aC6A7f4c3235e4edda971838640bE9e55aC222
xclrBTC (testnet)0x938ae31cc6418acc6730cF1AFFE53E91c143B078
Liquidation Bot (ERC-8004 #30907)0x9E47c5EE0b1174a5F4450553CE45Fdcf6bCd036a

PRICE ORACLE — PYTH NETWORK

AgentLoan uses Pyth Network for real-time on-chain prices. Pyth is a pull oracle — prices are fetched from Hermes API and pushed on-chain every ~15 seconds by the Liquidation Bot. The same oracle infrastructure is used by major DeFi protocols on mainnet.
TokenPyth Price ID
xclrBTC / BTC0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43
xEURC / EUR0xa995d00bb36a63cef7fd2c287dc105fc8f3d93779f062f09551b0af3e81ec30b
xUSDC / USDC0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a
Pyth on Arc Testnet: 0x2880aB155794e7179c9eE2e38200202908C17B43
Hermes API: https://hermes.pyth.network
Staleness threshold: 3600s (BTC/USDC) · 2,592,000s / 30 days (EUR — Pyth testnet updates slowly)

ARC ERC-8004 AGENT REGISTRY

The AgentLoan Liquidation Bot is registered as an on-chain AI agent via Arc's ERC-8004 standard. This gives the bot a verifiable on-chain identity and reputation system.
ContractAddress
IdentityRegistry0x8004A818BFB912233c491871b3d84c89A494BD9e
ReputationRegistry0x8004B663056A597Dffe9eCcC1965A193B7388713
ValidationRegistry0x8004Cb1BF31DAf7788923b405b754f57acEB4272
Bot wallet: 0x9E47c5EE0b1174a5F4450553CE45Fdcf6bCd036a
Agent ID: #30907
Registered via: IdentityRegistry.register(metadataURI)

ARCHITECTURE

LendingPool.sol
├── PriceOraclePyth.sol → Pyth Network (real-time, 15s updates)
├── InterestRateStrategy.sol (2-slope variable rate)
│ base 5% → kink 80% → slope2 145% → cap 1000%
├── libraries/ReserveLogic.sol (scaled balance indexes, overflow guard)
├── libraries/ValidationLogic.sol (health factor math)
└── mocks/MockERC20.sol × 3 (24h on-chain faucet cooldown)
AgentExecutor.sol
├── deployToYield(user, amount) → pull xUSDC from user → supply to pool
└── emergencyProtect(user, amount) → withdrawFor + repayFor atomic (1 tx)
Liquidation Bot (agents/)
├── pool-reader.ts → getAllBorrowers (incremental scan) + Multicall3 HF reads
├── oracle-updater.ts → Pyth Hermes API → updatePrices() every 15s
├── liquidator.ts → estimatePlan + execute + profit check
├── auto-refill.ts → deployer → bot wallet when gas < 10 USDC
└── arc-registry.ts → ERC-8004 identity registration

KEY FUNCTIONS

FunctionDescriptionTransactions
deposit(token, amount)Supply assets to the poolapprove + deposit
withdraw(token, amount)Withdraw supplied assets + interest1 tx
borrow(token, amount)Borrow against collateral1 tx
repay(token, amount)Repay debtapprove + repay
liquidate(borrower, debtToken, collToken, amount)Liquidate undercollateralized positionapprove + liquidate
getUserAccountData(user)Get HF, collateral, debt, available borrowsread
getUserSupplyBalance(token, user)Real balance including accrued interestread
getUserBorrowBalance(token, user)Real debt including accrued interestread
authorizeAgent(agent, bool)Allow an agent to act on your behalf1 tx
depositFor(user, token, amount)Agent supplies on behalf of userapprove + depositFor
withdrawFor(user, token, amount, recipient)Agent withdraws from user's supply1 tx (requires auth)
repayFor(borrower, token, amount)Anyone repays debt for a borrowerapprove + repayFor

MATH CONSTANTS

ConstantValueUsed for
RAY1e27Interest rate indexes and scaled balance math
WAD1e18Health factor and USD price calculations
SECONDS_PER_YEAR31,536,000Annual rate → per-second accrual
MAX_STALENESS3600sPyth price freshness check (hard limit)
ORACLE_BOT_INTERVAL15sBot pushes fresh prices this often

SECURITY FIXES APPLIED

IDSeverityFix
H-1Critical_updateAllIndexes() before HF check in liquidate()
H-2HighSame fix in withdraw() and borrow()
C-1CriticalSupply cap validated after index update
C-2HighLiquidation collateral accounting corrected
C-3MediumMockAggregator.setAnswer() protected with onlyOwner
ReserveLogicHighuint128 overflow guard on borrowIndex/liquidityIndex
PriceOracleMedium.call() instead of .transfer() for fee withdrawal
BotHighCollateral token can never equal debt token