The problem
KALE holders on Stellar had no way to borrow against their tokens. KaleFi is a single-market lending contract: deposit KALE, borrow USDC up to a loan-to-value limit, and repay.
How it works
One Soroban contract in Rust:
deposit(KALE) ─► collateral[user] += amount
borrow(USDC) ─► health factor after the borrow must stay ≥ 1
withdraw ─► health factor after the withdrawal must stay ≥ 1
repay ─► debt[user] -= amount (can't exceed the debt)The health factor is collateral value × LTV ÷ debt, read by the frontend so users see how close they are to the limit.
Design decisions
- Isolated market. One collateral, one debt asset, one contract. A bad price in this market can't spread to another.
- Health checked after the change.
borrowandwithdrawcompute the position as it would be afterwards, so the check can't be bypassed by ordering. - Every state change needs
require_auth()from the user whose position it touches.
What could go wrong
| Vector | Status |
|---|---|
Admin takeover through init | Fixed: init could be called again by anyone with their own address as admin; it now runs once |
| Admin-set price with no age | Partly fixed: the price carries a timestamp and borrowing, withdrawing and liquidating refuse it after an hour. It's still set by the admin, not an oracle |
| No liquidations | Fixed: anyone can repay up to half of an unhealthy position's debt for the same value in KALE plus 5% |
| Unbounded instance storage | Fixed: each position lives in persistent storage with its own TTL |
| Zero and negative amounts | Fixed: rejected with typed errors instead of relying on the token contract to panic |
| Frontend showed fake data | Fixed: every value is read from the contract; the UI claimed an 80% LTV the contract never had |
Where it stands
Redeployed to Stellar testnet with demo KALE and USDC assets, 8 contract tests, and a frontend that signs real transactions through Freighter. The demo faucet is capped per account and by total supply, so free KALE can't be used to borrow the market's USDC dry. The next step is a Reflector price feed for KALE.