This is Belay's public mechanics documentation. Back to the homepage
Belay
Mechanics · v1.0 · updated 2 September 2026 Robinhood Chain · chain ID 4663 Arbitrum Orbit L2 · gas in ETH Mainnet since July 1, 2026

The oracle is 24/5. The token is 24/7.

Stock Tokens trade all weekend long; their reference price doesn't. Every design choice on this page is built around that gap — because that's exactly where retail loan positions actually die.

Belay is for Stock Token holders who borrow USDG against them on Robinhood Chain. It monitors loan health 24/7 and lowers LTV according to rules you set, before the weekend oracle freeze — not after. Liquidation remains possible.

When the reference price stops moving, New York time

price frozen
price frozen

Friday, T‑90 minutes Last chance to lower LTV. After this there are no new prices for roughly ±2.6 days.

Monday, open Price catches up with reality all at once. Liquidation bots on the 100 ms block move first.

Regular session Pre & post market Overnight, thin liquidity Closed — marketStatus = 5

00Summary

The idea is good and the timing works. But three things will decide whether this lives or dies, and none of them is about “whether the AI is smart.”

  1. The Stock Token oracle is 24/5, while the token itself trades 24/7. Saturday–Sunday the reference price is frozen while the DEX price keeps moving. Every leverage design has to be built around this fact. This isn't a detail — it's the core of the product.
  2. Discretionary portfolio management is a regulated activity in nearly every jurisdiction. Being non-custodial and having a user-signed mandate reduces the risk, but doesn't remove it.
  3. The right wedge isn't an “AI rebalancer.” The right wedge is Belay: the agent that keeps the user from getting liquidated at 3 a.m. on a Sunday. Rebalancing is the second feature, not the first.

How to read this document

Sections 2 and 4 are the core. If time is limited, read those two plus section 11. Everything else follows from those three.

01What already exists on-chain

Know the battlefield before building here.

Live infrastructure

LayerWhat's available
ChainRobinhood Chain, Arbitrum Orbit, chain ID 4663, ~100 ms blocks, gas in ETH, FCFS sequencer (no priority-fee auction)
RPCrpc.mainnet.chain.robinhood.com, Blockscout explorer, sequencer feed via WebSocket
StablecoinUSDG (Paxos Global Dollar) as the liquidity anchor
OracleChainlink — per-ticker feeds, AggregatorV3Interface, plus L2 Sequencer Uptime Feed
DEX & liquidityUniswap (dedicated deployment), Rialto & Pleiades (propAMM), Arcus, 1inch; RFQ via 0x RFQ, 1inch Fusion, LiFi
LendingMorpho (backbone of Robinhood Earn, USDG ~7% APY)
PerpsLighter — non-custodial perps DEX, accessible from inside Robinhood Wallet
Account abstractionERC-4337 first-class and EIP-7702; provider Alchemy (official bundler), ZeroDev, Privy
BridgeCanonical Arbitrum bridge, CCIP, Stargate, Relay, Across

What's already live on-chain

Check all of these before writing a single line of code.

  • Lends (lendspro.com) — CDP: mint leUSD against Stock Tokens. Borrow limit ~60% LTV, +10-point maintenance. Already supports NVDA, AAPL, TSLA.
  • Syndromics — P2P syndicated lending, fixed rate fixed term, 55% LTV tier and 70% liquidation.
  • OpenClaw — already marketing a 24/7 LTV guardian agent, ERC-4337 session keys, approvals via Telegram.
  • r0x — x402 facilitator for agent payments on this chain, plus an MCP plugin.
  • Plenty of sniper bots and memecoin LPs — a signal that retail on this chain is still dominated by degens, not set-and-forget investors.

02Constraints that dictate the design

This is the part people skip most often, and the most expensive to get wrong.

2.1  Stock Tokens are not stocks

Stock Tokens are tokenised debt securities issued by Robinhood Assets (Jersey) Limited (RHJ). They give economic exposure, not legal or beneficial rights to the underlying stock. Concrete consequences for the risk engine:

  • Issuer credit risk. There's a Jersey entity standing between the user and Nvidia. This risk doesn't exist with crypto collateral. The risk model needs an issuer_risk variable that, when triggered, forces a system-wide de-risk — not per-ticker.
  • No voting rights. Irrelevant to the engine, but relevant to marketing claims. Never say the user “owns stock.”
  • Dividends are handled by the issuer, not via token transfer. Don't model dividends as on-chain cashflow.

2.2  Jurisdiction determines TAM

Stock Tokens are available in 120+ countries, but not for US persons, and are restricted in, among others, Canada, the UK, Switzerland, the UAE, and sanctioned jurisdictions. The official list lives in the Base Prospectus and Final Terms at docs.robinhood.com/rhj.

  • Stock Tokens are not available to US persons — which happens to be Robinhood's largest user base. Any TAM assumption based on “retail users coming in through Robinhood Wallet” must account for that exclusion.
  • Geo-gating and attestation are required on the front end, and ideally an allowlist at the smart-contract level for anything managed.
  • Lighter perps has its own restricted list: US, UK, Canada, Switzerland, UAE, Singapore. The hedging feature has a narrower TAM than the lending feature, so product design needs to be modular per jurisdiction.

2.3  24/5 oracle vs. 24/7 token

This is the mechanic that matters most here. The Chainlink feed for tokenized equities reports Total Return Value = the underlying equity price multiplied by a multiplier read directly from the token contract. The underlying price comes from a 24/5 equity feed covering the regular session, pre-market, post-market, and overnight.

ConditionFeed behaviorWhat the agent must do
Market openUpdates on deviation threshold or heartbeatNormal operation
Overnight sessionStill updates, but liquidity is thin and spreads are wideRaise the haircut, lower max trade size
Weekend, holiday, or closure (marketStatus = 5)Feed holds the last price; updatedAt stops advancingFrozen mode: no new leverage, no action that depends on the liquidation threshold, de-risk only
Corporate action being processedOracle paused — oraclePaused() returns trueTreat as price unavailable. Not zero, not stale-but-fine
Sequencer downSequencer Uptime Feed non-zeroFull halt, plus a grace period before resuming

Danger A — the Monday-morning gap

The oracle price is frozen at Friday's close. Monday's open, NVDA gaps down 12%. Positions whose health factor looked safe all weekend suddenly become liquidatable within seconds, and liquidation bots on a 100 ms-block chain win that race by default.

Mitigation: the agent forces LTV down before Friday's close, rather than reacting on Monday.

Danger B — DEX price vs. oracle divergence

On a weekend, news breaks, the Uniswap price moves, the oracle doesn't. Unwind logic that sizes using the oracle price but executes on the DEX can end up selling far below the assumed level.

Always size using min(oracle, dex_quote) for collateral and max(…) for debt.

2.4  ERC-8056, the corporate-action trap

Stock Tokens implement ERC-8056 (Scaled UI Amount Extension) with a uiMultiplier() function. The multiplier scales the effective amount without changing the raw balance or total supplybalanceOf() and totalSupply() stay the same through a stock split.

If a vault records user positions using raw balanceOf and never reads uiMultiplier(), the accounting will be off by 10× after a 10-for-1 split. That's a bug that wipes out user funds.

Rule

Every balance read used for valuation must be rawBalance × uiMultiplier() / SCALE — check the actual scale in the documentation. Every multiplier change must trigger a full re-index and a temporary pause.

2.5  FCFS sequencer and centralization

Sequencing is first-come-first-served: order is determined by arrival time, not gas price.

  • There's no “pay more” option to win in an emergency. The competition becomes a latency race, not a fee race. Rescuing a position during a gap requires low-latency nodes and RPC to the sequencer, not just a gas bump.
  • The sequencer is operated solely by Robinhood. Downtime means the agent is blind and paralyzed. This is disclosed to users.
  • Withdrawals to L1 via the canonical bridge have a 7-day challenge period. Never promise instant cross-chain exit liquidity.

03System architecture

┌─────────────────────────────────────────────────────────────────┐
│  CLIENT                                                         │
│  Web app / Telegram bot / Robinhood Wallet dApp browser         │
│  - Onboarding, geo-gate, risk questionnaire                     │
│  - Mandate signing (EIP-712)                                    │
│  - Kill switch (one button, always visible)                     │
└───────────────┬─────────────────────────────────────────────────┘
                │
┌───────────────▼─────────────────────────────────────────────────┐
│  AUTHORIZATION LAYER   (on-chain, non-custodial)                │
│  User smart account (ERC-4337) or EOA + EIP-7702 delegation     │
│  ├── SessionKeyModule  : agent key, expiry, revocable           │
│  └── PolicyGuard       : target+selector allowlist, notional cap │
│                          per-tx & rolling window, max slippage  │
└───────────────┬─────────────────────────────────────────────────┘
                │ userOps
┌───────────────▼─────────────────────────────────────────────────┐
│  EXECUTION LAYER   (off-chain, stateless workers)               │
│  Executor → Bundler (Alchemy) → Sequencer                       │
│  - Mandatory pre-flight simulation (fork / eth_call bundle)     │
│  - Idempotency key per intent, nonce management, retry policy   │
└───────────────▲─────────────────────────────────────────────────┘
                │ signed intent
┌───────────────┴─────────────────────────────────────────────────┐
│  DECISION LAYER                                                 │
│  ┌──────────────┐   ┌──────────────┐   ┌──────────────────────┐ │
│  │ RISK ENGINE  │──▶│ POLICY ENGINE│──▶│ INTENT VALIDATOR     │ │
│  │ deterministic│   │ deterministic│   │ deterministic + sim  │ │
│  └──────▲───────┘   └──────▲───────┘   └──────────────────────┘ │
│         │                  │                                    │
│         │           ┌──────┴───────┐                            │
│         │           │ SIGNAL LAYER │  ← LLM lives HERE ONLY     │
│         │           │ (advisory)   │    output: bounded score   │
│         │           └──────────────┘                            │
└─────────┼───────────────────────────────────────────────────────┘
          │
┌─────────┴───────────────────────────────────────────────────────┐
│  DATA LAYER                                                     │
│  - Chainlink feeds + sequencer uptime + oraclePaused()          │
│  - Position indexer (Blockscout / Alchemy / self-hosted node)   │
│  - DEX depth (Uniswap pools, RFQ quotes 0x/1inch)               │
│  - Market calendar (NYSE/Nasdaq holidays, half-days)            │
│  - Earnings calendar, corporate action feed                     │
│  - Funding rate & mark price Lighter (if V4)                   │
│  - News/sentiment (V4)                                          │
└─────────────────────────────────────────────────────────────────┘

Client

Web app / Telegram bot / Robinhood Wallet dApp browser

  • Onboarding, geo-gate, risk questionnaire
  • Mandate signing (EIP-712)
  • Kill switch (one button, always visible)

Authorization layer (on-chain, non-custodial)

User smart account (ERC-4337) or EOA + EIP-7702 delegation

  • SessionKeyModule — agent key, expiry, revocable
  • PolicyGuard — target+selector allowlist, notional cap per-tx & rolling window, max slippage
↓ userOps

Execution layer (off-chain, stateless workers)

Executor → Bundler (Alchemy) → Sequencer

  • Mandatory pre-flight simulation (fork / eth_call bundle)
  • Idempotency key per intent, nonce management, retry policy
↑ signed intent

Decision layer

  • Risk engine (deterministic) → Policy engine (deterministic) → Intent validator (deterministic + sim)

Signal layer (advisory) — the only place the model lives. Output: a bounded score.

Data layer

  • Chainlink feeds + sequencer uptime + oraclePaused()
  • Position indexer (Blockscout / Alchemy / self-hosted node)
  • DEX depth (Uniswap pools, RFQ quotes 0x/1inch)
  • Market calendar (NYSE/Nasdaq holidays, half-days)
  • Earnings calendar, corporate action feed
  • Funding rate & mark price Lighter (if V4)
  • News/sentiment (V4)

A separation that must never be violated

The Risk Engine, Policy Engine, and Validator must be 100% deterministic and reproducible. Given the same state, all three must produce the same intent. The LLM never generates calldata. The LLM can never raise a cap. The LLM can only shift parameters toward being more conservative, or produce a score consumed by a deterministic engine.

04Risk engine

4.1  Effective collateral value

Never use the raw oracle price.

V_eff(token)   = qty_effective × P_conservative × haircut_total

qty_effective  = rawBalance × uiMultiplier / SCALE        # ERC-8056
P_conservative = min(P_oracle, P_dex_executable(size))    # for collateral
haircut_total  = h_vol × h_session × h_liquidity × h_event × h_issuer
FactorTypical rangeBasis
h_vol0.75 – 0.9530-day realized vol plus implied vol when available. Single-name is more aggressive than an ETF.
h_session1.00 open
0.95 pre & post
0.88 overnight
0.80 closed
Underlying market hours
h_liquidity0.70 – 1.00DEX and RFQ depth at position size. Positions above 20% of pool depth get an aggressive haircut.
h_event0.70 if earnings ≤ 2 days
0.85 if ≤ 5 days
Earnings calendar
h_issuer1.00 normalDrops sharply if there's an RHJ stress signal. Manual flag from ops.

4.2  Time-aware health factor

This is what distinguishes it from ordinary LTV monitoring.

HF_now    = V_eff / debt
HF_stress = V_eff × (1 − gap_expected) / debt

gap_expected = z × σ_daily × sqrt(T_untradeable_days)
             + earnings_gap_premium

gap_expected is an estimate of the move up to the next actionable decision point — not until tomorrow.

  • T_untradeable_days — how many days until a position can actually be unwound with decent liquidity. Friday afternoon is about 2.6 days. Wednesday afternoon is about 0.6 days.
  • z is set by the risk profile: Conservative 3.0 · Balanced 2.3 · Growth 1.8.
  • earnings_gap_premium — single-name earnings gaps can be 8–15%. Don't model this with a normal distribution; use empirical per-ticker data.

Operational rules that follow from this

FRIDAY, T-90 minutes before close
    target_LTV_weekend = LLTV × 0.55    (Conservative)
                       = LLTV × 0.65    (Balanced)
                       = LLTV × 0.72    (Growth)
    if LTV_now > target_weekend → unwind down to target.
    Mandatory. Cannot be overridden by the AI.

D-1 EARNINGS, T-60 minutes before close
    target_LTV = LLTV × 0.50 for that ticker, regardless of profile.

MARKET CLOSED (marketStatus = 5)
    forbidden : adding leverage, opening new positions,
                optional rebalancing
    allowed   : repay, add collateral, unwind
                (with a strict slippage cap)

ORACLE PAUSED or STALE > threshold
    halt all actions on that ticker, except a full repay
    using another asset.

SEQUENCER DOWN
    full halt, notify user. Don't queue transactions
    that would execute at an unpredictable price on resume.

4.3  A ladder of actions, not all-or-nothing

HF_stress > 1.60 HealthyNo action.
1.35 – 1.60 WatchTighter monitoring, no new leverage.
1.20 – 1.35 TrimRepay 25% of debt from idle USDG.
1.10 – 1.20 De-riskUnwind until HF_stress returns to 1.45.
< 1.10 EmergencyUnwind until HF_stress reaches 1.80, then notify the user.

Always leave margin above the protocol threshold

On Lends, the borrow limit is 60% and maintenance is +10 points. That means the actual buffer from max borrow to liquidation is only about a 14% drop in collateral. That's one bad day for NVDA. Never let a user sit at max borrow.

4.4  Liquidity-aware execution

Before sending an unwind action:

1. Get quotes from at least 2 sources:
   Uniswap pool + RFQ (0x / 1inch Fusion) + Rialto propAMM

2. If estimated slippage > slippage_cap
   → split into several clips with delays

3. If even the smallest clip > cap
   → DO NOT execute. Escalate to the user.
     Selling into a market with no bid does more damage
     than an orderly liquidation.

4. Log realized slippage.
   Feed it back into h_liquidity for calibration.

05Where the AI is, and its limits

This is the part that's easiest to get architecturally wrong. An “AI agent” that outputs calldata directly is the fastest way to lose user funds.

Two-key architecture

LLM / model  →  structured proposal (JSON, strict schema)
                ↓
Deterministic validator
   · schema valid?
   · within the allowed action space?
   · passes every hard rule (§4.2)?
   · doesn't raise risk above the user's mandate?
                ↓
Simulator (fork of current state)
   · does the simulation result match the prediction?
   · does post-state HF improve?
   · no unexpected transfers?
                ↓
On-chain PolicyGuard
   last line of defense, cannot be bypassed off-chain
                ↓
Execution

Action space the model is allowed to touch

{
  "risk_bias": -1.0 .. 0.0,        // ONLY negative: reduces risk
  "ticker_flags": {
    "NVDA": { "elevated_event_risk": true, "reason": "..." }
  },
  "rebalance_urgency": "low | normal | high",
  "narrative": "explanation for the user, not consumed by the machine"
}

Why risk_bias can never be positive

The model can never make the system more aggressive. If the model hallucinates, the worst case is the user becomes too conservative — not liquidated.

Where the LLM is genuinely valuable here

  1. Structured event extraction from news. “Is there a guidance cut, an SEC investigation, a CEO resignation, M&A, or delisting risk?” The output is a flag, not a trade signal.
  2. Classifying corporate actions from filings, to trigger a pause and re-index before the multiplier changes.
  3. Explaining things to the user. This is underrated. “I reduced your NVDA exposure by 18% on Friday afternoon because of Tuesday's earnings and weekend gap risk” is worth far more for retention than 30 bps of alpha.
  4. Onboarding — translating questionnaire answers into risk-profile parameters, with a deterministic sanity check.

Roles the model is never given

  • Predicting price direction as a basis for leverage.
  • Position sizing.
  • Setting the slippage cap or the liquidation threshold.
  • Anything that picks the target contract to call.

06Smart contracts

Keep it thin. Every line of Solidity is a liability.

PolicyGuard.sol

The security core. Installed as a module or validator on the user's smart account.

struct Policy {
    uint64  expiry;                // session key expiration
    uint128 maxNotionalPerTx;      // USD, via oracle
    uint128 maxNotionalPerWindow;  // rolling 24 hours
    uint32  windowStart;
    uint128 spentInWindow;
    uint16  maxSlippageBps;
    uint16  minHealthFactorBps;    // minimum post-state HF
    bool    allowLeverageIncrease; // default FALSE
}

mapping(address target => mapping(bytes4 selector => bool)) allowedCalls;

function validate(address target, bytes4 sel, uint256 notional) external;
// reverts if: target/selector isn't allowlisted, the cap is exceeded,
// expiry has passed, or the agent tries to raise leverage when not permitted

Invariants that must hold and be formally verified

  • The agent can never call transfer to an address outside the user's own account.
  • The agent can never modify the Policy. Only the user can, via a direct signature.
  • A user revoke takes effect within one block, unconditionally.
  • Post-state health factor must be ≥ minHealthFactorBps, checked on-chain at the end of execution.

OracleReader.sol

Safe price reads, used by every other contract.

function readPrice(address token) public view returns (uint256 price) {
    // 1. sequencer uptime
    (, int256 seq, uint256 startedAt,,) = sequencerUptimeFeed.latestRoundData();
    require(seq == 0, "sequencer down");
    require(block.timestamp - startedAt > GRACE_PERIOD, "grace period");

    // 2. corporate action pause (advisory; staleness is still checked separately)
    require(!IStockToken(token).oraclePaused(), "oracle paused");

    // 3. read the feed + staleness
    (, int256 answer,, uint256 updatedAt,) = feeds[token].latestRoundData();
    require(answer > 0, "bad price");
    require(block.timestamp - updatedAt <= maxStaleness[token], "stale");

    return uint256(answer);
}

function effectiveBalance(address token, address user)
    public view returns (uint256)
{
    return IERC20(token).balanceOf(user)
         * IStockToken(token).uiMultiplier() / MULTIPLIER_SCALE;  // ERC-8056
}

maxStaleness is not a constant

When the market is open, 1 hour of staleness means something is wrong. On a weekend, 60 hours of staleness is normal. So maxStaleness is a function of the market calendar pushed on-chain by a keeper — or the system accepts a frozen price but forbids every action that increases risk. The second option is simpler and safer.

The remaining two contracts

  • ExecutionRouter.sol — safe batching: check pre-state, run the step, check post-state, revert if HF worsens.
  • MandateRegistry.sol — stores the hash of the EIP-712 mandate signed by the user. This is both a legal and a technical artifact: on-chain proof that the user authorized a specific action space, at a specific time.

What not to write

A lending pool, a custom oracle, an AMM, or a bridge. All of these already exist and have already been audited.

07Tech stack

ComponentChoiceWhy
Smart accountERC-4337 via Alchemy (the chain's official bundler) or ZeroDev; EIP-7702 for users who already have an EOAEIP-7702 matters: Robinhood Wallet users don't need to migrate addresses
Embedded walletPrivyAlready used in the Robinhood stack, so it's familiar
RPC / nodeDedicated Alchemy plus a self-hosted node for redundancyFCFS means latency is decisive; public RPC gets rate-limited
Sequencer feedDirect WebSocket sequencer feedSee transactions before execution, early detection of stress conditions
IndexerPonder or Subsquid, self-hostedNeeds real-time positions and lending-protocol events
BackendTypeScript (viem + permissionless.js), or Rust for the hot pathviem has the most mature account-abstraction support
QueueRedis + BullMQ, with a dead-letter queueIdempotency and retries are mandatory
DatabasePostgres + TimescaleDB for price and HF time-seriesA full audit trail is a legal requirement, not optional
SimulationLocal fork (anvil) refreshed every block, or TenderlyPre-flight is mandatory for every intent
MonitoringPrometheus + Grafana + PagerDutyUser health factor is the SLA metric
NotificationsTelegram bot and pushTelegram is already proven for approval flows on this chain
SecretsAWS KMS or an HSM for the agent's session key, on a scheduled rotationNever put a plaintext key in an environment variable

Latency budget for emergency de-risking

Detect price update Risk-engine decision Simulation Sign & submit to bundler

On a chain with 100 ms blocks and FCFS sequencing, a sub-one-second target is realistic — and it's what separates this from a five-minute cron job.

08Rebalancing engine (V2)

Risk profile to parameters

ProfileTarget annual volMax leverageMax single-nameNo-trade bandz
Conservative8%1.0× (no borrow)15%±5% absolute3.0
Balanced14%1.3×25%±4%2.3
Growth22%1.8×35%±3%1.8

Hard limits that apply across every profile: max leverage 2.0×, max single-name 40%, a minimum of 4 positions, and a minimum 5% USDG cash buffer for gas and emergency repayment.

Cost-aware rebalancing rule

Don't rebalance on a calendar. Rebalance when drift exceeds the band and the expected benefit exceeds the cost.

trade if     |w_actual − w_target| > band
      AND    expected_benefit > (fee + slippage_est + gas) × 2.5

expected_benefit ≈ 0.5 × λ × (drift² × σ²)   # mean-variance approximation

The 2.5 factor is a safety margin against estimation error. This will hold back around 70% of trades that weren't actually necessary — and that's a good thing, because churn is what kills retail returns.

Vol targeting

leverage_target = min(
    target_vol / realized_vol_portfolio_20d,
    max_leverage_profile,
    leverage_allowed_by_session      # weekend → forced down
)

Raise leverage gradually, at most +0.1× per day. Lower it immediately, with no rate limit on the way down. This asymmetry is intentional.

09Hedging with perps (V3/V4)

Before building this, it's worth understanding exactly what's involved.

What's available: Lighter, a non-custodial perps DEX integrated with Robinhood Wallet. In the EU, Robinhood also offers perps for commodities, ETFs, and FX — GOLD, SILVER, QQQ, EUR/USD, WTI, Brent — up to 10×. Single-name equity perps are generally not available.

The consequence

NVDA cannot be hedged with an NVDA perp — only with a proxy, such as a QQQ perp or a basket. This creates basis risk that can be larger than the risk being hedged, especially during idiosyncratic earnings events — exactly when the hedge matters most.

Rules that apply if this is built anyway

  • Hedge market beta only, not single-name risk. Sell QQQ perps sized at β_portfolio × notional × hedge_ratio.
  • Calculate funding costs explicitly. Sustained negative funding can eat returns within months. If funding_annualized exceeds the expected risk-reduction value, don't hedge.
  • Margin on Lighter is separate from collateral on the lending protocol, creating two places that can liquidate the user. This requires cross-venue margin management, and buffers on both.
  • Perps TAM is narrower. The feature must be switchable off per user based on jurisdiction.

My recommendation: delay hedging until after V3. Even then, offer it only as an explicit opt-in for users who pass a knowledge check.

10Security

Threat model

ThreatMitigation
Agent session key leakedNotional cap, selector allowlist, short 7-day expiry, instant revoke. Maximum loss is bounded by design, not by trust.
Backend compromisedOn-chain PolicyGuard is a defense the backend can't bypass. Assume the backend will fall.
Oracle manipulationChainlink is push-based, hard to manipulate. The real risk isn't manipulation but staleness or pausing — handle it explicitly (section 4).
Sandwich / MEV during unwindFCFS means no priority auction, but the sequencer feed is public. Use RFQ with locked-in pricing for large trades, not AMM. Split into clips. Randomize timing within the window.
Bad debt in a lending protocol in useDiversify venues. Monitor utilization and bad debt. Have an automatic exit trigger for a stressed venue.
USDG depegMonitor continuously. Prepare an emergency conversion route. Never assume its value is 1.00.
RHJ issuer failureCannot be technically mitigated. Must be in the disclosure, with a total exposure cap per user.
Bug in Belay's own contractsAudit by two firms, formal verification for PolicyGuard, bug bounty, staged TVL caps, timelock for upgrades.

Circuit breaker — mandatory before mainnet

Automatic halt if:
  · sequencer uptime feed is abnormal
  · more than 3 consecutive failed transactions within 60 seconds
  · realized slippage > 3× the estimate on any trade
  · aggregate portfolio drawdown > 8% within 1 hour
  · unexpected oracle staleness while the market should be open
  · oracle vs. DEX divergence > 5% while the market is open

On halt: stop all new actions, notify every user,
enter read-only mode.

Resuming requires human approval. Always.

User kill switch

One button, always visible, no layered confirmations: revoke the session key and stop the agent. Must work even if the backend is down — a transaction goes straight from the user's wallet to PolicyGuard. This isn't a nice-to-have feature; it's what makes the product trustworthy.

11Legal & regulatory

None of this is legal advice. But these are issues that must go to a lawyer before onboarding the first user.

Core issues

  1. Discretionary portfolio management is a licensed activity. In the EU that's MiFID II. The fact that execution happens via smart contract and is non-custodial weakens part of the argument, but deciding what gets bought or sold on the user's behalf is likely to be viewed by many regulators as investment management. The strongest defense: the user sets the rules, Belay merely executes them mechanically. This is another reason V1 is far safer than V4.
  2. The underlying asset is a security. Stock Tokens are tokenised debt securities. Building a service on top of them is categorically different from building on top of a DeFi token.
  3. Entity and jurisdiction. Stock Tokens are issued by Robinhood Assets (Jersey) Limited (RHJ) — the issuing entity and its jurisdiction are stated plainly wherever the product is described. Belay's own operating entity and home jurisdiction get the same treatment: a clear local legal opinion, obtained before marketing begins in a given jurisdiction, not after.
  4. Restricted jurisdictions. Stock Tokens are unavailable to US persons and restricted in Canada, the UK, Switzerland, and the UAE. None of these are served or marketed to. Geo-blocking, IP screening, attestation, and clear language in the ToS are required. US regulators in particular have a history of cracking down on half-hearted “we don't target the US” claims.
  5. Taxes. Never give tax advice. Provide a complete transaction export so users can handle it themselves.

A structure that reduces risk

  • Non-custodial, no exceptions. User assets or keys are never held. This isn't just a technical decision — it's the foundation of the legal argument.
  • Explicit on-chain mandate. The user signs an EIP-712 message specifying the action space, cap, and expiry, stored in MandateRegistry.
  • Rules the user can read. If a user can read and understand every rule the agent runs, the product is a tool, not a manager. Publish the rule set.
  • No pooling. Every user has their own smart account. No shared vault. Pooling funds would put this squarely in collective-investment-scheme territory.
  • Honest, unburied disclosure. Including RHJ issuer risk, sequencer centralization, the 24/5 oracle, the possibility the agent fails or errs, and that liquidation can still happen.

Marketing language to avoid

  • “Set-and-forget”
  • “Guaranteed,” “definitely safe”
  • “Automatic profit”
  • “Liquidation-free”

The phrase “set-and-forget” should never appear in marketing copy. “24/7 monitoring under rules you define” is the honest version, and it's easier to defend.

12Current status and limitations

What runs today

No position is being monitored. The position source is a fixture; not one RPC call is made anywhere in the service. Signups are still open — an address can be stored and a Telegram chat linked — but such a subscription is registered, not active: nothing is read from the chain for it, and neither an alert nor the daily heartbeat is ever sent to it. A heartbeat asserting that monitoring is running while nothing is being read would be a scheduled untruth, which is why the rule is enforced in code and asserted by test rather than left to copy. When a live indexer is confirmed reading the chain, every registered subscription becomes active and receives one message saying so; if that confirmation is later lost, they fall back and receive the degraded notice.

What is written and tested is the read-only half of the loop: scoring a position with the time-aware model in section 4, composing an alert, a degraded-mode notice or a daily heartbeat, and delivering it over Telegram. A subscription is a wallet address plus the Telegram chat id that results from pressing Start on the bot — the bot cannot message a username, only a chat that has opened it. Belay holds no keys, signs nothing, and builds no transactions; the user executes from their own wallet. Stages 3 and 4 of the design (the three gates and automated execution) are not built.

Alerts are best-effort. They can be delayed or missed if a data feed, Telegram, or the service's own infrastructure fails, and responsibility for the position remains entirely with the user. Alerts are rate-limited per address per day; the heartbeat is exempt from that budget so a quiet day is still distinguishable from an outage.

Caps

Caps apply to the execution product, which is not live. When it ships it opens with a $5,000 cap per position and a $100k total TVL cap, raised in stages only after each tier survives 30 days incident-free: $100k → $500k → $2M → $10M. Read-only monitoring has no TVL cap because it holds no value.

Audit status

Not yet complete. PolicyGuard is not written; it requires formal verification and at least two independent audits before any execution path handles user funds. A bug bounty runs alongside the audit process. Nothing in the read-only release touches funds.

Integrations

  • Lending venues: Lends, Syndromics, and Morpho.
  • Price and uptime data: Chainlink price feeds and the L2 Sequencer Uptime Feed.
  • Execution venues: Uniswap, RFQ (0x, 1inch Fusion), and Rialto.
  • Account infrastructure: ERC-4337 via Alchemy, EIP-7702 delegation.

Known limitations today

  • Belay reports; it does not act. Every action is executed by the user, from their own wallet.
  • Alerts depend on external feeds and notification channels, so they are best-effort rather than assured delivery.
  • The buffer parameters have been calibrated and backtested against two years of daily data, and over that sample the policy is net negative against doing nothing — about −0.4% a year — even though it prevented every liquidation that occurred. The sample contains no gap large enough for the protection to pay for itself. That regime is the case for Belay, and it is not in the data.
  • Hedging (perps) is not available in this version — see section 9.
  • Rebalancing beyond the core liquidation-guardian action space is not yet live — see section 8.
  • Coverage is limited to the lending venues listed above; a position on an unlisted venue isn't monitored.

13Recap

What it does

Belay is a non-custodial agent for Stock Token holders borrowing USDG on Robinhood Chain. It runs a time-aware risk engine that accounts for the gap between a 24/5 oracle and a 24/7 token, and holds three possible actions on a position: repay debt, add collateral, or unwind — ranked by the ladder in section 4.3.

Order of operations

Risk engine → policy engine → intent validator → on-chain PolicyGuard → execution. Every stage is deterministic except the advisory signal layer, which can only move risk_bias downward and never generates calldata (section 6).

Constraints

Non-custodial with a revocable session key. No pooled funds — one smart account per user. No leverage increase without explicit user action. Liquidation remains possible; the system reduces the odds, it doesn't remove the outcome.

This document is technical and product documentation, not legal, financial, or investment advice. The risk parameters mentioned are a starting point for calibration, not a recommendation. Verify all protocol details and parameters directly from official documentation before implementation — these things change fast. Version 1.0, updated September 2, 2026.