EquiFlowquiFlow
ILLUSTRATIVE · Contract addresses and details are for demonstration only and may not reflect deployed contracts.
Developers · smart contracts · 4 deployed · source open

Four contracts. One vault. Read every line.

The full protocol surface — vault, stable, oracle, account factory — verified on the Robinhood Chain explorer. Every function, every event, every storage slot is below. Audits and source are linked next to each address.

BUILD
a47c2f9
tag v0.4.2 · merged 4 days ago
Chain id
46630
Network
Robinhood Chain Testnet
RPC endpoint
rpc.testnet.chain.robinhood.com
Explorer
explorer.testnet.chain.robinhood.com
Faucet
faucet.testnet.chain.robinhood.com
Browse · 4 contracts
core · borrow + collateral · v0.4.2

EquiFlowVault

VERIFIED
0x9D0d98f3B7483239ebdCb90dc37D548AF5FB6C7f
Audits · 2
All reports →
  • Trail of Bits
    Mar 2026 · TOB-EF-204
    PASS
  • Spearbit
    Apr 2026 · SP-2026-019
    PASS
Bug bounty
Up to $500,000 · Immunefi

Custodies pledged equity tokens, mints USDG against them, enforces LTV bands, and exposes the public liquidate() entrypoint. All accounting denominated in 1e18 USD.

Public interface · 10 entries

Functions

View on GitHub ↗
SignatureDescriptionAccess
pledgeAndBorrow(address token, uint256 amount, uint256 borrowUsd)Locks `amount` of `token` as collateral and mints `borrowUsd` of USDG to msg.sender in a single transaction. Reverts ExceedsLtv if LTV cap breached.EXTERNAL
liquidate(address user, address token, uint256 debtUsdToRepay)Repays up to 50% of `user`'s debt with caller's USDG, seizes `debtUsdToRepay × 1.05` worth of `token` to caller. Reverts PositionHealthy if HF ≥ 1.EXTERNAL
repay(uint256 amountUsd)Burns `amountUsd` USDG from msg.sender and decrements their debt. Use `repayMax()` to settle in full.EXTERNAL
withdraw(address token, uint256 amount)Unpledges collateral. Reverts if withdrawal would push HF below 1.EXTERNAL
register(uint256 amount) · withdrawLp(uint256 shares)LP deposit and redemption. Tokenized as ERC-4626 shares against pooled USDG plus accrued borrow yield.EXTERNAL
positionOf(address user) → (collateralUsd, borrowedUsd, health)Aggregated read used by all UI components. `health` is scaled 1e18 (1e18 = HF 1.000).VIEW
healthFactor(address user) → uint256Same as positionOf().health. Returns type(uint256).max for zero-debt accounts.VIEW
setBorrowRateBps(uint256 newRate)Adjusts the protocol borrow APY in basis points. Caps at 5000 bps (50%).OWNER
setReserveFactorBps(uint256 newBps)Portion of borrow interest routed to protocolReserves. Default 1000 bps.OWNER
claimReserves(uint256 amountUsd)Transfers accrued reserves to the configured treasury address.OWNER
Events · 4 emitted

Events

Pledgedtopic 0xa1c5…7e94
(address indexed user, address indexed token, uint256 amount, uint256 borrowedUsd)
Repaidtopic 0x2f6b…c108
(address indexed user, uint256 amount)
Liquidatedtopic 0x8c44…ab02
(address indexed user, address indexed liquidator, address indexed token, uint256 collateralSeized, uint256 debtRepaid)
InterestAccruedtopic 0xb19e…41ff
(uint256 totalBorrowedUsd, uint256 reserveDeltaUsd)
Storage layout · 7 slots

Storage

SlotLayoutNotes
0mapping(address => Position)Per-user collateral (per token) and outstanding USDG debt.
1mapping(address => Asset)Per-token LTV / liqThreshold / staleAfter / priceFeed.
2address[]listedAssets enumeration.
3uint256totalBorrowedUsd (1e18).
4uint256borrowRateBps (current APR).
5uint256 + uint256reserveFactorBps + protocolReserves.
6addresstreasury sink for reserves.
Deployment timeline · 6 events

From genesis to v0.4.2

BLOCKS 39,241,007 → 42,917,406
2026-01-18
14:02 UTC
Genesis deploy · v0.1.0

Initial vault + USDGStable + Pyth adapter pinned to Robinhood Chain Testnet. 8 stock feeds listed.

Block
#39,241,007
DEPLOY
2026-02-09
09:46 UTC
v0.2.0 — LP shares & ERC-4626 surface

Vault becomes a yield vault: register() / withdrawLp() / sharePriceUsd added. Borrow-rate accrual moved to per-block.

Block
#40,158,223
UPGRADE
2026-02-28
23:11 UTC
EquiSmartAccountFactory v0.2.0 deployed

First batch of EIP-7702 delegations enabled. Pledge flow drops from 3 popups to 1.

Block
#40,874,991
DEPLOY
2026-03-22
18:30 UTC
v0.3.5 — reserves + treasury

reserveFactorBps and protocolReserves accounting introduced. setTreasury() guarded behind 72h timelock.

Block
#41,649,104
UPGRADE
2026-04-12
11:08 UTC
Trail of Bits + Spearbit reports merged

Two fixes shipped: ExceedsLtv now reverts before token pull; liquidator close-factor capped at 50% on-chain.

Block
#42,355,618
UPGRADE
2026-05-04
07:24 UTC
v0.4.2 — current

PythPriceAdapter switched to lastObservation() fallback. Vault default borrow rate adjusted to 4.50% APR.

Block
#42,917,406
PARAM
How to read this codebase

Four files. Read in this order.

01

Start at EquiFlowVault.sol

All state lives here. pledgeAndBorrow() is the canonical entry. Read its preconditions before anything else.

02

Trace USDG mint paths

USDGStable.mint() is unreachable except via the vault. Grep mint() to confirm — there is exactly one call site.

03

Skim PythPriceAdapter for staleness

Every quote is bounded by staleAfter. Liquidators must call updateAndPriceUsd() to refresh before claiming.

04

Account factory is optional

The protocol works with plain EOAs. EquiSmartAccountFactory exists so the UI can bundle approve + pledge into one signature.