Whitepaper · v1.0
Bezalt: fixed-fee private credit for tokenized assets.
A protocol that lets holders of tokenized stocks and real-world assets draw a USD stablecoin against what they own, without selling it, without interest, and without disclosing the portfolio behind the proof, backed by a stability pool that earns from outcomes instead of time.
Abstract
Tokenized securities put real-world value on-chain, but the holder who needs liquidity still faces a bad choice: sell the position, or reveal it wholesale to a lender. Bezalt separates what must be true from what must be seen. An attester verifies ownership, valuation, eligibility and liabilities off-chain and signs a collateral passport: an EIP-712 attestation carrying only an eligibility outcome, a capacity bound and an expiry. The borrower pledges collateral into the protocol and draws USDG from a stability pool for a single origination fee; nothing accrues while the line is open. Positions that fall to the maintenance loan-to-value are liquidated into the pool at a bonus, which, together with fee income and partner revenue, is the pool's entire return. The design is implemented in six immutable contracts governed through a timelock, with bounded parameters that make the pool whole by construction on every sufficiently collateralised liquidation.
1. Introduction
Robinhood Chain brings tokenized equities and other real-world assets (RWAs) to an EVM-equivalent L2. These tokens are transfer-restricted, issuer-controlled ERC-20s whose holders are, by construction, verified. What they lack is credit: a way to convert a position into working capital without exiting it.
Existing DeFi money markets assume permissionless, fungible, continuously traded collateral and price it with an interest-rate curve. Neither assumption fits RWAs. Positions are often illiquid, valued periodically rather than tick by tick, and their holders are accountable parties who care about what a lending venue learns about them. A borrower who must reveal an entire brokerage-style portfolio to draw against one line of it will not draw at all.
Bezalt is built for this setting. It makes three commitments: the borrower keeps ownership of the asset for the life of the position; the borrower pays once, a fixed origination fee, and never an accruing rate; and the borrower proves privately, the chain and the venue see an eligibility outcome and a capacity bound, never holdings.
2. Design principles
Minimal disclosure
Every on-chain artefact carries the least information that makes the loan safe: a signed outcome, a capacity, a time window. Holdings stay with the borrower and the attester's transient check.
Bounded by construction
Risk parameters are validated on-chain against hard bounds. A misconfiguration cannot create a liquidation that under-compensates the pool.
Outcome-based returns
Pool participants earn when something happens (a draw, a liquidation, a partner payment) not while time passes. There is no interest anywhere in the system.
Never trap the user
Pausing halts new exposure only. Repayment, adding collateral, closing, pool withdrawals and collateral sales stay open in every state.
Fresh prices or nothing
Borrowing, withdrawing and liquidating all require a price younger than the asset's maximum age. Stale data blocks action rather than misprices it.
Immutable logic
No proxies, no upgrade paths. Change happens by parameter within bounds, or by a new deployment after a timelock.
3. Protocol overview
Six contracts implement the protocol. Borrowers interact with CreditLine; liquidity providers with StabilityPool; everything else is infrastructure the two consult.
CreditLine holds CREDIT_LINE_ROLE on the pool; the registries are read-only from the credit line's point of view.Actors: the borrower pledges collateral and draws USDG; the liquidity provider deposits USDG into the pool for shares; the keeper triggers liquidations for a fee; the attester signs passports after private verification; the valuation signer posts prices for assets without a public feed; governance (a timelock with a multisig proposer) sets bounded parameters and holds the pause switches.
4. Collateral passports
A passport is a typed, signed statement that a borrower's position in a given asset passed verification and may carry up to a stated amount of debt until a stated time.
Verification on-chain is deliberately shallow: signature recovery, attester role membership, time window, a global minIssuedAt cut-off for mass invalidation after a key rotation, and a per-passport revocation flag. What the attester checked (ownership records, valuation sources, liabilities elsewhere) never appears on-chain; the checksHash lets the attester prove later which procedure produced the outcome without revealing its inputs.
Capacity binding. The credit line attributes every unit of debt to the passport that authorised it. Draws under a passport are cumulative: passportDebt[id] + amount ≤ capacity. Repayment frees capacity; presenting a newer passport re-attributes existing debt to it. A passport can therefore back several draws over its window without a fresh verification each time, and its revocation stops new draws immediately without touching existing debt, maintenance still applies.
| Fact | Borrower | Attester | Chain / venues |
|---|---|---|---|
| Which assets are held | Yes | Check only | No |
| Quantities and wallets | Yes | Check only | No |
| Liabilities elsewhere | Yes | Check only | Pass/fail, implicitly |
| Eligibility outcome | Yes | Yes | Yes (signed) |
| Capacity bound | Yes | Yes | Yes (bounded) |
| Pledged amount and debt | Yes | - | Yes, per position |
5. Credit lines
A position holds one collateral asset in escrow inside CreditLine and a USDG debt. Its life cycle is open → draw / repay / add / withdraw → close, or → liquidate.
On every draw the loan-to-value must not exceed the class maximum, checked by cross-multiplication so no precision is lost:
value18 = collateral × price18 / 10decimals
The only cost is the origination fee, deducted from the draw:
net to borrower = amount − fee
poolFee = fee × poolFeeShareBps / 10 000
treasuryFee = fee − poolFee
Repayment is permissionless (anyone may repay any position) and transfers USDG directly to the pool. A dust floor (minDebt, 100 USDG by default) prevents positions too small to liquidate economically. Collateral withdrawals re-check the maximum LTV; closing requires zero debt and returns the full escrow.
6. Valuation
The CollateralRegistry is the single valuation surface. It returns valueOf(asset, amount) in USD with 18 decimals and reverts if the underlying price is older than the asset's maxPriceAge, is zero, or is dated in the future. Two price sources are provided:
- ChainlinkPriceOracle adapts standard USD feeds, normalising any feed decimals to 1e18. On an L2 it can be bound to the chain's sequencer-uptime feed: when the sequencer is down, or has been back for less than a grace period, prices are refused, which prevents liquidations on prices the market could not react to.
- AttestedPriceOracle serves assets with periodic marks (fund units, receivables, real estate). Valuations are EIP-712 attestations from a
VALUATION_ROLEkey; anyone may relay them. Posts must be newer than the last one, carry a fresh nonce, and, when a deviation band is configured, stay within it. The risk admin can force a legitimate re-mark through.
Because every borrowing path reads the registry, an asset can be moved from one source to another, or disabled for new exposure, without touching positions.
7. Liquidation
A position becomes liquidatable when its LTV reaches the class maintenance threshold under a fresh price. Anyone may call liquidate. The pool absorbs the whole debt and receives collateral worth the debt plus a bonus; the caller earns a keeper fee out of the seized amount; whatever remains returns to the owner.
toKeeper = seize × keeperFeeBps / 10 000
toPool = seize − toKeeper
returned = collateral − seize
test_liquidate_partialSeizure).The registry refuses parameter sets where (1 + bonus)(1 − keeper) < 1, so whenever the collateral is sufficient the pool receives at least the debt's worth after the keeper's cut; the pool is made whole by construction. Liquidations have their own switch (liquidationsPaused) independent of the protocol pause, so a guardian can halt them during an oracle incident without freezing repayments.
8. Stability pool
The pool is an ERC-4626 vault denominated in USDG. It is the protocol's only source of principal and its liquidation backstop. Share value is the sum of three components:
Loans are carried at face value; with a fixed fee there is nothing else to accrue. Seized collateral is marked at oracle value; if a seized asset's price goes stale, that asset counts as zero rather than blocking the vault, and unpricedSeizedAssets() exposes the list for the risk admin.
Liquidity. Withdrawals can only be served from idle USDG; maxWithdraw and maxRedeem report the binding limit so integrators never see a surprise revert. A reserve (reserveBps, 10 % by default, ≤ 50 %) keeps part of total assets unlent so ordinary withdrawals clear. Seized collateral is converted back to USDG by open sale: anyone may buy it at oracle value minus saleDiscountBps (2 % by default, ≤ 10 %).
Return sources. Origination-fee share on every draw; liquidation gains (collateral received above the debt replaced, less the later sale discount); partner revenue or any voluntary contribution via donate. Losses arrive the same way, through share value, when a liquidation is short of collateral.
Inflation resistance. The vault uses a virtual-share offset of six decimals. A first-depositor attack costs the attacker more than a thousand times what it can extract from a victim; the test suite asserts this.
9. Risk parameters
Each listed asset carries the following parameters, validated on-chain against fixed bounds whenever they are set.
| Parameter | Meaning | Bound | Example |
|---|---|---|---|
| maxLtvBps | Max debt / value on open, draw, withdraw | > 0 and < maintenance | 60 % |
| maintenanceBps | LTV at which liquidation opens | ≤ 98 % | 75 % |
| originationFeeBps | One-time fee on each draw | ≤ 10 % | 1.5 % |
| liquidationBonusBps | Extra collateral value the pool receives | ≤ 20 % | 8 % |
| keeperFeeBps | Share of seized collateral paid to the liquidator | ≤ 5 % and (1+bonus)(1−keeper) ≥ 1 | 0.5 % |
| maxPriceAge | Oldest acceptable price | 60 s – 7 d | 24 h |
| supplyCap | Max collateral of this asset in escrow | any | per listing |
| minDebt (global) | Dust floor for open positions | any | 100 USDG |
| poolFeeShareBps (global) | Fee share retained by the pool | ≤ 100 % | 70 % |
| reserveBps (pool) | Unlent fraction of total assets | ≤ 50 % | 10 % |
| saleDiscountBps (pool) | Discount on seized-collateral sales | ≤ 10 % | 2 % |
10. Governance & security
Administration is split into narrow roles held by different keys. The default admin of every contract is a TimelockController (48-hour minimum delay on mainnet) whose proposer is the governor multisig; the deployer renounces its admin role at the end of deployment, and the deployment script asserts that it did.
| Role | Holder | Can |
|---|---|---|
| Default admin | Timelock | Grant roles, unpause, set treasury, invalidate passports en masse, sweep untracked tokens |
| Risk admin | Governor multisig | List assets, set bounded parameters, feeds, reserve, discounts, fee share, dust floor |
| Guardian | Guardian key / multisig | Pause new exposure; pause liquidations |
| Attester | Verification service | Sign and revoke passports |
| Valuation | Valuation service | Sign valuations |
| Credit line | The contract | Move principal in and out of the pool |
Pause semantics. A pause stops opens, draws, collateral withdrawals, pool deposits and pool funding. It never stops repayment, adding collateral, closing a debt-free position, pool withdrawals, collateral sales, or, unless separately halted, liquidations. Unpausing goes through the timelock.
Assurance. The implementation ships with 87 tests (unit, fuzz at 4,096 runs per property, and nine system invariants exercised over 24,576 randomised calls), 100 % line coverage of the protocol sources, a Slither pass with no high-severity findings, and a scripted end-to-end dry run on a local chain configured with Robinhood Chain's chain id. It has not yet been audited by a third party; that is a hard prerequisite for mainnet in the roadmap below.
11. Robinhood Chain
Bezalt targets Robinhood Chain, an Arbitrum Orbit L2 that settles to Ethereum, pays gas in ETH and posts data as EIP-4844 blobs. Its native asset class (issuer-controlled, transfer-restricted stock tokens) is exactly the collateral the passport model was designed for.
| Mainnet | Testnet | |
|---|---|---|
| Chain ID | 4663 | 46630 |
| Gas token | ETH | ETH |
| Explorer | robinhoodchain.blockscout.com | explorer.testnet.chain.robinhood.com |
| Stack | Arbitrum Nitro (Orbit), EVM-equivalent, Cancun opcodes | |
Three integration dependencies are external to the protocol and must be settled before mainnet: the USDG contract address on the chain (or an alternative USD stablecoin, since the pool reads the asset's decimals), allow-listing of the CreditLine and StabilityPool addresses by each stock-token issuer so escrow transfers succeed, and the availability of Chainlink feeds and a sequencer-uptime feed for the chain. Assets without feeds launch on the attested oracle.
12. Economics
Bezalt's revenue is fee volume, not balance. A borrower who holds a line for a day pays the same as one who holds it for a year, which makes the protocol attractive for short, opportunistic liquidity and neutral about duration. The pool's economics therefore depend on three flows the team must size: draw volume × fee share; liquidation frequency × (bonus − sale discount); and partner revenue from venues that route credit through the protocol.
Worked example
- Collateral pledged
- 100 tokenized shares @ $100 = $10,000
- Draw (60 % LTV)
- 6,000 USDG
- Origination fee (1.5 %)
- 90 USDG: 63 to the pool, 27 to the treasury
- Net proceeds
- 5,910 USDG
- Liquidation eligible below
- $80 per share (LTV 75 %)
- Amount to repay, any time
- 6,000 USDG
Against an 8 % APR facility, the fixed fee is more expensive for the first ~2.3 months and cheaper thereafter; the terminal computes this comparison for any inputs.
12.1 Fee routing
The fee is split atomically in CreditLine.draw: poolFee = fee × poolFeeShareBps / 10 000 stays in the stability pool and is recognised immediately in share value; treasuryFee = fee − poolFee is transferred to the treasury. Both parameters are bounded and timelocked. Because the split happens in the same transaction as the draw, there is no accrued-fee balance to claim, distribute or misreport.
12.2 Treasury share → BEZALT buyback
The treasury share is committed to a programmatic buyback of BEZALT (ticker $BEZALT), the protocol token, executed by BuybackRouter. The router is designed so that its behaviour is fully determined by on-chain state and a small set of bounded parameters:
- Permissionless, rate-limited execution.
execute()may be called by anyone at most once perepochLength(initially 24 h) and pays the callerkeeperTipBpsof the spend, so no privileged operator is required. - Spend cap tied to pool depth.
spend = min(balance, totalAssets × maxSpendBps / 10 000), withmaxSpendBps ≤ 200. Accumulated USDG is worked down over several epochs rather than in one block. - Price bound. The execution price must lie within
maxDeviationBpsof the venue's 30-minute TWAP; otherwise the call reverts. This removes the incentive to move the market ahead of a known buy. - Deterministic settlement. Purchased BEZALT is split by
burnBpsbetweenaddress(0)and a staking reserve in the same transaction. The router holds no BEZALT between executions and has no sell path. - Single, allow-listed venue. The swap route is one BEZALT/USDG pool on Robinhood Chain; changing it, like every other parameter, is a timelocked governance action.
require | pexec − TWAP30m | / TWAP30m ≤ maxDeviationBps / 10 000
burned = bought × burnBps / 10 000; reserved = bought − burned
The buyback is a use of treasury revenue, not a promise about token price, and it never draws on the stability pool's share of fees or on pool principal. Pool depositors' return is unchanged whether or not a buyback executes.
BuybackRouter and the BEZALT token are specified for v1.1 (§14) and are not part of the audited v1 contract set.13. Risks
- Borrowers: liquidation. Tokenized equities move with their underlying; a position at the maximum LTV has a 20-percentage-point buffer to maintenance in the example class. Add collateral or repay to widen it.
- Pool participants: bad debt and liquidity. A gap move can leave collateral worth less than the debt it secures; the pool realises that loss. Withdrawals are limited to idle liquidity and seized collateral must be sold before it becomes withdrawable.
- Oracle risk. Attested valuations depend on the signer's integrity; deviation bands, staleness limits and the liquidation pause bound the damage of a bad mark but do not eliminate it.
- Attester risk. A compromised attester key can issue passports for ineligible positions until rotated; capacity bounds, supply caps and LTV limits cap the exposure of any single passport.
setMinIssuedAtinvalidates all passports from before a rotation in one transaction. - Issuer risk. Stock tokens are issuer-controlled; freezes or forced transfers by the issuer are outside the protocol's control.
- Smart-contract risk. The code is tested and analysed but unaudited; see §10.
14. Roadmap
Testnet (chain id 46630)
Deploy with mock USDG and a mock feed, run at least one full passport cycle and one forced liquidation, exercise the timelock.
External audit
Independent review of the six contracts and deployment scripts; findings closed and re-tested.
Integration prerequisites
USDG address, issuer allow-listing of protocol addresses, Chainlink feeds and sequencer-uptime feed on Robinhood Chain.
Mainnet (chain id 4663)
Conservative supply caps and reserve, guardian rota, public keeper documentation.
v1.1. BEZALT and the buyback
Token contract,
BuybackRouterwith the bounds in §12.2, the BEZALT/USDG venue on Robinhood Chain, and a staking reserve; audited together before the treasury share is routed to the router.After launch
ERC-1271 attesters, cross-venue passport verification library, additional collateral classes on the attested oracle.