AI agents that earn, borrow, and pay — without selling their assets.
BorrowBot uses Chainlink CRE to give AI agents their own on-chain treasuries on Aave V3. An agent deposits collateral (WETH + cbBTC), earns yield automatically, and borrows USDC to pay for services — all verified by a decentralized oracle network. No single point of trust.
Live on Base mainnet. Try the interactive demo: borrowbot.app/demo
┌─────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Agent Wallet │────>│ Treasury Vault │────>│ Service Provider │
│ (USDC) │ │ (Aave V3) │ │ (Payee) │
└─────────────┘ └──────────────────┘ └──────────────────┘
│ │
deposit│ │borrow & pay
│ │
┌──────┴────┴──────┐
│ Chainlink CRE │
│ (verification) │
└──────────────────┘
- Deposit — Agent deposits USDC, swapped 50/50 into WETH + cbBTC, supplied to Aave V3 as collateral.
- Earn — Collateral earns yield automatically. The treasury grows while the agent operates.
- Propose — Agent submits a spend plan (payee, amount, reason). The owner approves.
- Verify — CRE's decentralized network independently verifies: allowlisted payee, amount within limits, correct nonce, safe health factor.
- Pay — Vault borrows USDC from Aave and pays the service provider. Collateral keeps earning.
The agent never has direct access to the funds. Every spend is proposed, approved, and verified before execution.
borrowbot/
├── apps/
│ ├── web/ # Next.js demo UI + API routes
│ └── agent/ # Minimal agent HTTP server
├── packages/
│ └── contracts/ # Solidity contracts (Hardhat)
│ ├── BorrowVault.sol # Core vault — Aave V3 supply, borrow, policy guards
│ └── BorrowBotReceiver.sol # CRE receiver — decodes reports, calls vault
├── cre/
│ └── workflows/
│ └── borrowbot-borrow-and-pay/
│ ├── main.ts # CRE workflow (HTTP trigger, EVM reads, EVM write)
│ ├── workflow.yaml # Target mapping
│ └── config.mainnet.json # Runtime config
└── docs/ # Product documentation
Monorepo managed with Yarn workspaces.
All files that use Chainlink CRE:
| File | Role |
|---|---|
cre/project.yaml |
CRE project config + RPC targets |
cre/workflows/borrowbot-borrow-and-pay/workflow.yaml |
Workflow target mapping |
cre/workflows/borrowbot-borrow-and-pay/main.ts |
Workflow code: HTTP trigger, agent call, EVM reads, EVM writeReport |
cre/workflows/borrowbot-borrow-and-pay/config.mainnet.json |
Mainnet runtime config |
packages/contracts/contracts/BorrowBotReceiver.sol |
CRE onchain write receiver/consumer |
packages/contracts/contracts/cre/ReceiverTemplate.sol |
Forwarder validation + metadata decoding |
packages/contracts/contracts/cre/IReceiver.sol |
CRE receiver interface |
packages/contracts/scripts/deployBorrowBotBase.ts |
Deployment with CRE forwarder config |
- Node.js 18+
- Yarn 1.x
- CRE CLI (for workflow simulation)
- A funded wallet on Base mainnet (ETH for gas + USDC for collateral)
git clone https://github.com/YOUR_USERNAME/borrowbot.git
cd borrowbot
yarn install
cp .env.example .env
# Edit .env with your keys (see .env.example for details)yarn contracts:compileyarn contracts:deploy:base
yarn contracts:configure:baseThis deploys BorrowVault + BorrowBotReceiver and configures policy guards (allowlisted payees, borrow limits).
DEPOSIT_AMOUNT_HUMAN=10 yarn contracts:deposit:base# Terminal 1: agent server
yarn agent:dev
# Terminal 2: web app
yarn web:devOne-time setup (TypeScript to WASM compilation):
cd cre/workflows/borrowbot-borrow-and-pay
bun --bun node_modules/@chainlink/cre-sdk-javy-plugin/bin/setup.ts
cd ../../..Simulate with broadcast:
~/.cre/bin/cre workflow simulate ./workflows/borrowbot-borrow-and-pay \
-R ./cre \
-T mainnet-settings \
--broadcast \
--non-interactive \
--trigger-index 0 \
--http-payload '{"payee":"YOUR_PAYEE_ADDRESS","amount":"1000000"}'BORROW_AMOUNT_HUMAN=1 yarn contracts:repay:base
yarn contracts:reset-aave:baseCopy .env.example to .env and fill in your values. See the file for descriptions of each variable.
Required for deployment:
DEPLOYER_PRIVATE_KEY— Wallet private key (funds the vault, deploys contracts)BASE_RPC_URL— Base mainnet RPC (defaults tohttps://base.drpc.org)
Required for CRE:
CRE_ETH_PRIVATE_KEY— Separate key for CRE workflow broadcasts (gas-only wallet)
Required for web UI:
NEXT_PUBLIC_PRIVY_APP_ID— Privy app ID for wallet connect
Security: Use separate keys for deployer and CRE broadcaster. Keep ENABLE_DEMO_RUNNER and ENABLE_RESET_RUNNER disabled in production.
| Contract | Address |
|---|---|
| Aave V3 PoolAddressesProvider | 0xe20fCBdBfFC4Dd138cE8b2E6FBb6CB49777ad64D |
| cbBTC | 0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf |
| USDC | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 |
| CRE Mock Forwarder (simulation) | 0x5e342a8438b4f5D39E72875FcEE6F76B39CCe548 |
| CRE Production Forwarder | 0xF8344CFd5c43616a4366C34E3EEE75af79a74482 |
All scripts are in packages/contracts/scripts/ and run via root package.json:
| Command | What it does |
|---|---|
yarn contracts:deploy:base |
Deploy BorrowVault + BorrowBotReceiver |
yarn contracts:configure:base |
Post-deploy policy configuration |
yarn contracts:deposit:base |
Deposit USDC (swap to WETH+cbBTC, supply to Aave) |
yarn contracts:supply:base |
Supply existing cbBTC to Aave |
yarn contracts:repay:base |
Repay a specific borrow amount |
yarn contracts:withdraw:base |
Withdraw collateral from Aave |
yarn contracts:reset-aave:base |
Full reset (repay all debt, withdraw all collateral) |
yarn contracts:swap-to-usdc:base |
Swap collateral tokens back to USDC |
MIT
Built by Miguel Sanchez — miguel@stackit.ai