An AI keeper that steps in before you get liquidated — and won't move until it has verified your payment on-chain.
A money market on HashKey Chain mainnet (177). Supply and borrow. Borrow across chains over Chainlink CCIP. Pay through HSP to switch on a non-custodial AI keeper that rotates collateral or repays debt to keep your position alive.
In an on-chain money market you are liquidated the instant your Health Factor crosses the threshold — usually during a fast price drop, when nobody reacts in time. The penalty goes to the liquidator, not to you.
Positions are lost not because the borrower is insolvent, but because they were away from the keyboard.
Paboxo is an isolated-pair lending protocol. createLendingPool is a public function: anyone can
open a market for any collateral / borrow pair with its own risk curve — no governance vote, no
allowlist. The only requirement is that both tokens have a registered price feed. Suppliers deposit
the borrow token and earn interest. Borrowers post collateral into a Position contract that
belongs to them alone.
On top of that sits the part that makes Paboxo different: an opt-in, non-custodial AI keeper that watches your Health Factor and acts inside your own position before the liquidator can.
In Paboxo the payment, the AI, and the DeFi mechanic are one verifiable flow:
| 💳 HSP settlement | The protection fee is a real on-chain USDC.e payment on mainnet 177, producing a verifiable ACCEPT receipt. |
| 🔐 Payment-gated keeper | Before touching a position, the keeper re-runs HSPVerifier against the signed mandate — payer, recipient, token, chainId. Payment is a cryptographic precondition for action, not an off-chain flag. |
| 🛡️ Non-custodial, simulate-first | The keeper acts inside your position, never takes custody, simulates every action, and runs dry-run by default. |
| 🔗 Integrated rails | Cross-chain over Chainlink CCIP. Real DODO V2 liquidity for the swap lever. |
Every core contract is source-verified on Blockscout. Every claim below has a link.
| Contract | Address |
|---|---|
| LendingPoolFactory | 0xF0D1c69c…6fa20B47 |
| TokenDataStream — oracle | 0x007F735F…190eC20F |
| IsHealthy — health & liquidation | 0xb3B45829…2629a27B |
| InterestRateModel | 0x175867CA…f2382E22 |
| CCIP Receiver | 0x8ab3650f…536366Ae |
| Market | Lending pool |
|---|---|
| pxWHSK | 0xB45693e9…08196406 |
| pxWBTC | 0xC6FA92Df…b5D17270 |
| pxWETH | 0xF1a061Db…b934942D |
| Claim | Proof |
|---|---|
| 🌉 Cross-chain works | CCIP message, Base → HashKey 177 — ExecutionStateChanged = SUCCESS, destination tx |
| 🔄 The swap lever fires on-chain | repayWithSelectedToken on the pxWETH market — 0.028 pxWETH swapped to 50.35 pxUSDT through a real DODO V2 DPP pool |
| 🤖 The keeper is running | GET /api/cycles — its live decision log, straight from the keeper |
| ✅ The contracts pass | CI green — 170 tests |
| 📊 The indexer is serving | GET /pools — 75 indexed entities over GraphQL + REST |
A price moves. The protocol notices. The AI acts before the liquidator can.
flowchart LR
A["📉 <b>Price drops</b><br/>oracle-cron pushes<br/>the new price on-chain"]
B["🔄 <b>Pool re-pegs</b><br/>market-maker resets the<br/>DODO guide price to match"]
C["🤖 <b>Agent reacts</b><br/>health factor crosses 1.15<br/>agent sizes the fix"]
D["🛡️ <b>Collateral rotates</b><br/>inside your own Position<br/>HF restored above 1.30"]
E["✅ <b>No liquidation</b><br/>you keep your position<br/>and your exposure"]
A --> B --> C --> D --> E
style A fill:#3d1f1f,stroke:#f85149,color:#f0f6fc
style B fill:#1c2128,stroke:#6e7681,color:#f0f6fc
style C fill:#0d2b4e,stroke:#1f6feb,color:#f0f6fc
style D fill:#0f2d1c,stroke:#2ea043,color:#f0f6fc
style E fill:#0f2d1c,stroke:#2ea043,color:#f0f6fc
The same story, call by call — including the HSP gate the keeper cannot skip:
sequenceDiagram
autonumber
actor U as 👤 User
participant FE as paboxo-fe
participant HSP as 💳 HSP
participant LP as LendingPool<br/>+ Router
participant POS as Position<br/>(user-owned)
participant DEX as DODO V2<br/>DPP
participant K as ⚙️ Keepers
participant AI as 🤖 Rebalance Agent
rect rgba(128, 142, 158, 0.12)
Note over U,POS: Open a position
U->>FE: supply collateral, borrow pxUSDT
FE->>LP: supplyCollateral() · borrowDebt()
LP->>POS: deploy & custody collateral
LP-->>FE: HF = 1.42 ✅
end
rect rgba(219, 171, 10, 0.14)
Note over U,LP: Pay to protect
U->>HSP: pay fee in USDC.e — from your own wallet
HSP-->>U: ACCEPT receipt + decision trace
U->>LP: approveRebalanceDelegation(keeper)
end
rect rgba(248, 81, 73, 0.13)
Note over K,DEX: The market moves against you
K->>LP: setPrice() — collateral drops
K->>DEX: resetDODOPrivatePool() — re-peg to oracle
end
rect rgba(31, 111, 235, 0.14)
Note over AI,POS: The agent acts before the liquidator
AI->>LP: read health factor
LP-->>AI: HF = 1.09 ⚠️ (below 1.15)
AI->>HSP: HSPVerifier — re-check the signed mandate
HSP-->>AI: ✅ ACCEPT — payer, recipient, token, chainId
AI->>AI: size the fix — deterministic math
AI->>LP: rebalancePosition() — simulated first
LP->>POS: rotate collateral
POS->>DEX: swap at the re-pegged price
DEX-->>POS: proceeds stay in the Position
LP-->>AI: HF = 1.31 ✅ restored
end
rect rgba(46, 160, 67, 0.14)
Note over AI,U: You never got liquidated
AI->>FE: DGRID explanation — "why I did this"
FE-->>U: position safe · funds never left
end
Every number that moves money — health factor, swap size, which lever to pull — is deterministic scaled-integer math, enforced on-chain. The language model receives that finished decision and is instructed, in its system prompt, that it must not change it. Its only job is to tell you why, in a sentence you can read.
An LLM that can hallucinate prose is useful. An LLM that can hallucinate a swap size is a liability. Paboxo gives it the first job and structurally denies it the second.
Three levers, all constrained on-chain:
| Lever | What it does | Requires |
|---|---|---|
| Rotate | Swaps volatile collateral → stablecoin, via DODO V2 DPP pools | Your on-chain delegation |
| Deleverage | Repays part of the debt out of your collateral | Protocol operator |
| Signal-only | Warns you, touches nothing — the default until you delegate | Nothing |
How it decides. Every 60 seconds the agent reads live health factors from IsHealthy. A position
is at risk when 1.0 ≤ HF < 1.15. It sizes an action to restore HF ≥ 1.30. Below 1.0 it does
nothing — that position belongs to liquidation, and the agent knows the difference.
How it stays safe. Every write, from every keeper, passes through one mandatory safety guard: a dry-run gate, a gas ceiling, a per-cycle action cap, and absolute price bounds. There is no send path that bypasses it. Every action is simulated before execution, and the keeper runs dry-run by default — production execution is a deliberate switch, and for judging safety the demo runs in verify-and-simulate mode.
Your funds never leave your Position. Delegation is one on-chain call
(approveRebalanceDelegation); revoking it is another. The keeper cannot move your collateral out,
cannot borrow against it, and cannot touch a position that has not opted in.
Watch it think:
curl https://paboxo-api.staifdev.codes/api/cycles # every cycle it has run
curl https://paboxo-api.staifdev.codes/api/actions # every decision, with its plain-language reasonBuilt as a Mastra Workflow — buildWatchlist → readHealth → filterAtRisk → decide → explain → execute → report — reasoning through DGRID AI. If the
model is unreachable the agent falls back to a deterministic template and keeps running. The loop
never stops because the AI had a bad day.
HSP sits on the protocol's authorization path, not as a bolt-on.
- You click Enable protection and pay a fee in USDC.e through HSP — a real on-chain settlement from your own wallet, zero custody, on mainnet 177.
- HSP returns a verified
ACCEPTreceipt with a decision trace. - You grant rebalance-delegation to the keeper on-chain.
- The keeper independently re-verifies that receipt (
HSPVerifier, bound to the signed mandate) before it acts.
The keeper refuses to protect a position without cryptographic proof of payment. No subscription database, no off-chain flag to spoof.
| Coordinator | hsp-hackathon.hashkeymerchant.com |
| Fee token | USDC.e 0x054ed458…c9D88D0a |
| Adapter | 0x467AaF35…c1e25012 |
HSP is a hackathon sandbox (pre-1.0). The integration is real on mainnet 177; the adapter and coordinator are the organizer's sandbox deployment.
Supply into a HashKey pool from Base. Borrow pxUSDT that bridges to another chain. Burn & mint pools on both lanes.
Not a bridge we wrote. Not a mock. Here is the message on the CCIP
explorer
— ExecutionStateChanged = SUCCESS.
| Chain | Selector | |
|---|---|---|
| Home | HashKey Chain | 7613811247471741961 |
| Counterparty | Base | 15971525489660198786 |
You do not have to take any of this on faith. The whole loop is live, and you can walk it end to end.
| 1 | Open the app | paboxo.xyz — connect a wallet on HashKey Chain mainnet 177. |
| 2 | Take a position | Supply collateral, borrow pxUSDT. Your collateral lands in a Position contract that only you own. |
| 3 | Turn on protection | One click. Pay the fee in USDC.e through HSP, straight from your wallet — nothing is ever held for you. |
| 4 | Get your receipt | HSP returns a signed ACCEPT, with the full decision trace. This is the proof the keeper will demand later. |
| 5 | Hand over the keys — just one | Grant rebalance-delegation on-chain. It permits exactly one thing: rotating collateral inside your position. Revoke it whenever you like. |
| 6 | Watch it think | The keeper re-verifies your receipt against the signed mandate, reads your health factor, sizes the fix, and tells you — in plain language — what it would do and why. |
Step 6 is the one worth staying for. Most protocols show you a liquidation after it has happened. This one shows you the reasoning before it would have.
| Repo | What's inside | Verify it |
|---|---|---|
| paboxo-sc | The protocol. Factory, pools, routers, per-user Positions, health & liquidation, oracles, DODO adapter, CCIP, HSP verifier usage. | forge test — 170 passing, CI green |
| paboxo-keeper | The off-chain brain. ai-workflow (Rebalance Agent + DGRID + HSP verify gate), market-maker (pegs DODO DPP to the oracle), oracle-cron, liquidation-bot. |
pnpm -r test |
| paboxo-fe | The app. Earn, borrow, swap, portfolio, cross-chain, HSP payment flow + protection panel. | bun run test — 428 passing |
| paboxo-indexer | Every protocol event, queryable. 75 entities over GraphQL + REST. | Live GraphQL |
| paboxo-landingpage | The 3D landing experience. | paboxo.xyz |
These are the live values on every market. Don't take our word for it — read them off the chain:
| Parameter | Value | Read it from |
|---|---|---|
| Loan-to-value | 70% | LendingPoolRouter.ltv() |
| Liquidation threshold | 75% | IsHealthy.liquidationThreshold(router) |
| Liquidation bonus | 10% | IsHealthy.liquidationBonus(router) |
| Interest rate model | Two-slope kinked, per-market | InterestRateModel |
| Oracle staleness window | 1 hour — stale prices revert, they never settle | TokenDataStream |
| Protocol fee | 0.1% of borrow | LendingPoolFactory |
cast call <pool> "router()(address)" --rpc-url https://mainnet.hsk.xyz
cast call <router> "ltv()(uint256)" --rpc-url https://mainnet.hsk.xyz # 7e17 = 70%We would rather you read this than discover it.
- Non-custodial. The keeper never holds user funds. It acts only inside a position the user
delegated, and only after an independently-verified HSP
ACCEPT. - Deterministic gates, AI for explanation. The LLM never controls funds — it explains a decision the contracts enforce.
- Dry-run by default. Production execution is a deliberate switch. The demo runs in verify-and-simulate mode.
- Not a solvency guarantee. In an extreme single-block crash the keeper may not prevent liquidation. It reduces avoidable, slow-drift liquidations — it does not promise to eliminate all of them.
Paboxo targets borrowers who keep collateralized positions open but cannot monitor liquidation risk 24/7. Monetization is an opt-in protection fee paid through HSP, per protected position. Because the keeper only acts after verifying an on-chain payment, the protocol needs no off-chain subscription database. The same mechanism extends to tiered protection, market-maker-sponsored protection, or DAO-funded protection for strategic markets.
Everything runs against HashKey Chain mainnet 177 (https://mainnet.hsk.xyz).
| Layer | What we use |
|---|---|
| Language | Solidity ^0.8.30 (a few interfaces on ^0.8.20) |
| Toolchain | Foundry — forge · cast · anvil. Optimizer on, runs = 200 (mandatory: LendingPoolDeployer embeds LendingPool's full creation code) |
| Libraries | OpenZeppelin Contracts + Contracts-Upgradeable — UUPS proxies, AccessControl · forge-std · chainlink-ccip |
| Oracles | TokenDataStream registry with Chainlink-shaped latestRoundData → PushOracleFeed · ConstantPriceFeed · SupraPriceFeed |
| DEX | DODOAdapter → DODO V2 DPP (PMM) pools |
| Cross-chain | Chainlink CCIP — Burn & Mint token pools, Base ↔ HashKey |
| Tests | forge test — 170 passing, CI green. Unit + fork tests (fork gated by RUN_FORK) |
A pnpm workspace monorepo. Shared toolchain: Node ≥ 22 · pnpm 11.6 · TypeScript 5.7
(run directly via tsx, no build step) · Biome 2.5 (lint + format, not ESLint/Prettier) ·
Vitest 2.1.
| Package | Stack |
|---|---|
keeper-core (library) |
viem 2.21 (chain client, reads, guarded writes, simulate-before-send) · zod 3.24 (config validation + secret redaction) · pino 9.5 (logging) · the shared safety.ts guard and on-chain address book |
oracle-cron |
viem · @chainlink/data-streams-sdk 1.2 for the price source · exchange price feeds as fallback · pushes 8-dp USD prices before the 1-hour staleness window closes |
market-maker |
viem · reads TokenDataStream, re-pegs each DODO DPP guide price via resetDODOPrivatePool — price only, zero liquidity moved |
ai-workflow (the Rebalance Agent) |
Mastra @mastra/core 1.50 (7-step Workflow) · DGRID AI gateway for reasoning · Hono 4.12 + @hono/zod-openapi + Swagger UI (public read-only REST API) · better-sqlite3 11.8 (WAL store for cycles / actions / alerts) · Inngest 4.12 (optional durable cron) · @hsp/core + @hsp/sdk (vendored) for the payment gate |
liquidation-bot |
viem · better-sqlite3 (self-indexes borrowers with a block checkpoint) |
| Deployment | GitHub Actions job DAG → tests gate rsync to a VPS → three systemd units (paboxo-oracle, paboxo-market-maker, paboxo-rebalance), all Restart=always |
| Layer | What we use |
|---|---|
| Framework | Ponder 0.16 on Bun |
| Chain access | viem 2.21, round-robin transport across up to 3 RPC endpoints |
| Database | Postgres in production (pg 8) · PGlite in dev |
| API | Ponder GraphQL + SQL-over-HTTP, plus custom REST routes on Hono 4.5 (/pools, /pools/:pool/rate) |
| Coverage | 6 singleton contracts + 5 factory-templated dynamic contracts → 75 entities |
| Layer | What we use |
|---|---|
| Framework | TanStack Start — React 19.2, file-based TanStack Router, Nitro 3 for SSR, Vite 8, TypeScript 6 |
| Web3 | wagmi 3 + viem 2.54 + Reown AppKit 1.8 (WalletConnect). HashKey 177 is the only configured network |
| Data | TanStack Query 5 · GraphQL against paboxo-indexer · ABIs extracted from forge build |
| Payments | @hsp/core + @hsp/sdk (vendored) — HSP payment flow + protection panel |
| UI | Tailwind CSS 4 · hand-rolled component kit (no shadcn) · lucide-react · Recharts 3 for the IRM / rate / liquidity charts |
| Tests | Vitest 4 + Testing Library + jsdom — 428 passing |
| Deployment | Vercel |
| Layer | What we use |
|---|---|
| Framework | TanStack Start · React 19 · Vite 8 · Tailwind 4 |
| 3D & motion | Three.js 0.173 · React Three Fiber 9 · Drei 10 · GSAP 3.12 (scroll-driven) |
| State | Zustand 5 |
| Role | GitHub | |
|---|---|---|
| Ghoza | Architect Engineer | @ghozzza |
| Axel | Integration Engineer | @Lexirieru |
| Wildan | Backend Engineer | @ahmadstiff |
| Ahmad | Frontend Engineer | @wildanre |
Built for the HashKey On-Chain Horizon Hackathon · DeFi + AI track
Live App · BUIDL · Agent API · Explorer
Markets run on Paboxo-issued px assets on HashKey mainnet 177.