CuyFI: shipping a cross-chain yield agent at ETH Global in 36 hours
A postmortem on building CuyFI at ETH Global Argentina — LayerZero bridges, Privy wallets, LangChain agents, and ERC4626 vaults in 36 hours. What worked, what broke, and what I'd do differently.
ETH Global Argentina runs 36 hours. That’s not a lot of time to build something that actually works — not just a demo that passes the judges’ 2-minute slot, but something where the actual cross-chain message goes through, the vault accepts the deposit, and the agent reads the transaction receipt without exploding.
We built CuyFI. A cross-chain AI yield agent. Users send stablecoins once via a Telegram bot, and an LLM agent figures out where the best yield is — even if it’s on a different chain — and moves the funds there automatically.
The stack
| Layer | Technology | Role |
|---|---|---|
| Frontend | Telegram Bot | User interface — send messages, get confirmations |
| AI Agent | Python / LangChain / OpenAI | Parse intent, select yield strategy |
| Yield Data | CaesarAI via x402 | Real-time rate research (micropayment-gated) |
| Wallets | Privy server-side SDK | Non-custodial smart wallets per user |
| Cross-chain | LayerZero OFT + Composer | Bridge USDT Polygon → Arbitrum |
| Hub Contract | Diamond proxy EIP-2535, Arbitrum | Vault management + strategy execution |
| Spoke Contract | Polygon | USDT deposit + bridge initiation |
| Vaults | ERC-4626 (Aave 4.2%, Pendle 6.1%) | Yield-bearing strategy destinations |
| Atomic bridge | Avail Nexus SDK | Bridge-and-execute (partially shipped) |
Hackathon timeline
What shipped vs. what didn’t
Shipped
- Telegram bot UX — full conversation, confirmation step
- LangChain agent with tools:
get_yield_opportunities,deposit_to_vault,bridge_funds - Privy embedded wallets — non-custodial, one per user
- CaesarAI x402 yield data — blew through $20 budget in testing
- LayerZero Polygon → Arbitrum — OFT adapter + Composer receiver
- ERC-4626 vault deposit — Pendle USDC pool at 6.1% selected
Not shipped
- Avail Nexus atomic execute — bridge half worked; execute needed ~4 more hours
- x402 query caching — should have been Day 1 — 180 queries at $0.12 each
The LangChain tool definition
The agent’s tools are what made the natural-language → on-chain execution handoff work. Each tool has a strict typed schema — no hallucinated parameters.
@tool
def deposit_to_vault(
vault_address: str,
amount_usdc: float,
chain: Literal["arbitrum", "polygon"],
user_wallet: str,
) -> dict:
"""
Deposit USDC into an ERC-4626 vault on the specified chain.
Returns transaction hash and share amount received.
Requires explicit user confirmation before calling.
"""
# Privy signs the tx on behalf of the user's smart wallet
tx = privy_client.sign_and_send(
wallet=user_wallet,
to=vault_address,
data=encode_deposit(amount_usdc),
chain_id=CHAIN_IDS[chain],
)
return {"tx_hash": tx.hash, "status": "pending"}
The Literal["arbitrum", "polygon"] constraint is load-bearing — without it the LLM picks arbitrary chain IDs.
Architecture
What I’d do differently
Diamond proxy was the wrong call for a hackathon. We spent 6 hours on the Diamond setup — 6 hours we could have used on the Avail integration. A simple UUPS proxy would have been fine.
Start with the demo path, add features backward. We built the full architecture first, then integrated the demo path. Should have been the reverse.
Budget the x402 micropayments in advance. 180 queries × $0.12 = $21.60 on a $20 budget. The fix — 5-minute yield data cache — should have been built Day 1.
The Telegram UX saved us. When contract deployment broke at hour 28, the working Telegram bot gave judges context. “This is what the user sees” is a powerful frame when the underlying tech is partially broken.
On LayerZero
DVN confirmation time on testnet: 12–15 minutes. Fine for real users, not great for live judging. We pre-ran bridge transactions to show completed receipts.
What CuyFI taught me about agent architecture
The experience that stuck with me most wasn’t the cross-chain engineering — it was how the LangChain agent handled ambiguity.
Users would send “put some money in yield” with no amount. The agent asked a clarifying question. The user replied “maybe $50?” — and the agent proceeded. That handoff between natural language and deterministic financial execution is where most AI DeFi projects fail.
The key: treat the Telegram conversation as stateful (agent remembered prior messages), and require explicit confirmation before any financial parameter. That confirmation step felt like friction in testing. In the live demo, it felt like trustworthiness.
CuyFI was a proof of concept. But it was a working one. That’s what hackathons are for.