Docs

How Afterglow works.

The mechanism, the numbers and the reasoning behind them. Testnet build, unaudited.

View source on GitHub

01

Overview

Afterglow is a fixed-rate USDG lending market for tokenized stocks on Robinhood Chain, an Arbitrum chain. Borrowers pledge stock tokens such as TSLA and borrow USDG at a fixed rate until a fixed maturity.

Lenders deposit USDG and pick a side: Protected, paid first, or Boost, which takes losses first and earns the rest. A market-hours oracle and a gap-risk model keep loans open and safe while stock prices are frozen over the weekend.

02

The weekend problem

Stock tokens move on-chain around the clock, but their price feeds follow the stock market. Chainlink stops printing on Friday 20:00 New York, when 24/5 trading closes, and resumes after Sunday 20:00 New York, when it reopens. For about two days every lender is looking at a stale price.

On-chain stock lenders handle that gap in one of two ways today:

  • Keep lending on Friday's price. Loans open against a number that may be wrong by Monday. A gap down becomes the lenders' bad debt.
  • Freeze everything. Safe for lenders, but borrowers cannot repay or add collateral until the feed returns.

Afterglow does neither. New borrowing stops, exits stay open, and the weekend risk is priced and paid to the lenders who choose to carry it.

Why it matters

$3.14B
tokenized stocks across chains, 4.0M holders
rwa.xyz
$689M
USDG on Robinhood Chain
USDG totalSupply()
$33.4B
Schwab pledged-asset line balances, +59% a year
Schwab 2Q26 8-K

Borrowing against a stock portfolio is a large and growing product in traditional finance. On-chain, the collateral and the cash already exist; what is missing is a loan that survives the weekend.

03

Borrowing

Each market has one collateral token, one maturity and one fixed rate. If you borrow P USDG with t years left to maturity at rate r, you owe a fixed face value at maturity:

face = P × (1 + r × t)

Repaying early costs the face value discounted to today, so you pay interest only for the time used. Any position still unpaid after maturity plus a grace period is in default and can be liquidated in full.

Sessions

The oracle tags every price read with a session. What you can do depends on it:

SessionWhenBorrowWithdraw collateralLiquidate
LiveMarket open and the feed has printedUp to base LTVIf LTV stays under the limitYes
ClosingFinal 4 hours before the weekly closeLimit ramps downIf LTV stays under the ramped limitYes
ClosedWeekend, holiday, or reopened with no new printNoOnly under the weekend LTVNo
HaltedCorporate action, sequencer outage, bad or stale price, USDG depegNoNoNo

Repay and add collateral work in every session. Repay can never be paused, not even by the guardian.

The pre-close ramp

In the four hours before the Friday close the borrow limit glides in a straight line from the weekday level to the weekend level, so nobody can open a maximum loan minutes before a two-day freeze. The ramp limits new risk only; it never liquidates an existing position.

CollateralWeekday LTVWeekend LTVLiquidation LTVLiquidator bonus
Stocks (TSLA, AMZN, NVDA)55%45%65%7%
ETFs (SPY, QQQ)70%60%77%5%

Liquidations wait for a fresh price. Selling collateral against a frozen number is unfair to the borrower and there is no market to sell into until Monday anyway.

04

GapGuard

GapGuard is a small risk model written in Rust and deployed on Arbitrum Stylus. For each stock it records the weekend gap: Monday's first price against Friday's last, taken from Chainlink.

It keeps an exponentially weighted variance of those gaps with λ = 0.90, so recent weekends count most. From that it sets a buffer and a safe weekend limit:

buffer = 3 × σ, clamped to 5%–50%
weekend LTV = liquidation LTV × (1 − buffer)

A position that enters the weekend at that LTV survives a three-sigma gap without becoming liquidatable. Until a stock has eight recorded weekends, the model answers with the maximum 50% buffer.

The market uses the lower of its configured weekend LTV and GapGuard's, so the model can only tighten the limit. If GapGuard fails or is unset, the configured value applies. TSLA's recent gaps are calm (model limit 61.75%), so today its configured 45% holds.

05

The weekend premium

The fixed rate pays for the money. The weekend premium pays for the weekend. Every loan pays it once, upfront, for each weekly close before maturity:

per weekend = 10% of GapGuard σ, clamped to 2–50 bp
premium = amount × per weekend × weekends to maturity

Choppier stocks and longer loans pay more. The premium is kept from the amount sent to the borrower, then earned by lenders evenly until maturity. A deposit made just before a borrow therefore captures none of it. Because Protected's target is fixed, all of the premium ends up with Boost.

TSLA exampleValue
Weekend gap σ0.79%
Premium per weekend7.8 bp
As a yearly rate≈ 4.1%
28-day loan (4 weekends)0.31% of the amount

06

Lender vaults

Every market splits its lenders into two tranches that share the same borrowers and the same fixed rate. What differs is the order of payment:

ProtectedBoost
PaidFirst, up to a 5% targetEverything left, incl. all premiums
LossesOnly after Boost is goneFirst
SizeUp to 80% of the vaultAt least 20% of the vault

Example: a fully lent vault with 25% in Boost earns the 6% base rate plus TSLA's premium, about 10% in total. Protected takes its 5%. Boost earns about 25%, of which about 16 points are weekend premium.

The honest caveat: those figures assume the vault is fully lent. When little is lent, interest is thin, and Boost tops up Protected's target from its own share. Boost's yield moves with utilisation; Protected's does not, until Boost runs out.

Who pays for a Monday gap

Say a stock gaps down on Monday so hard that a loan's collateral no longer covers it. Drag the size of that loss: Boost absorbs it first, and Protected is only touched once Boost is gone.

12.0% of the vault
12,000 USDG
0Boost gone at 25,00040,000
BoostBoost absorbs
13,000 / 25,000
52.0% of principal left
ProtectedProtected untouched
75,000 / 75,000
100.0% of principal left

Example vault of 100,000 USDG, 25,000 in Boost earning 25% before losses.

Loss
12,000
Boost
13,000
Protected
75,000

07

Weekend sweep

USDG that is not lent does not sit idle. Each market can park it in an ERC-4626 USDG savings vault, and the cash it keeps on hand follows the same market clock:

SessionKept as cashWhy
Live / Closing20%Borrowers can draw at any moment
Closed5%No borrowing until the reopen
Halted, paused, matured100%Everything comes back

Anyone can call rebalance(); the target comes from the oracle, not the caller. Borrows and withdrawals pull any shortfall from the vault in the same transaction, so nobody waits on a keeper. On testnet the vault is a demo that pays a fixed 3.6%.

08

Oracle and USDG

The Phaselock oracle reads Chainlink stock feeds and quotes them in USDG through Chainlink's USDG/USD feed. It takes the session from the market calendar, because feed freshness alone cannot tell an open market from a closed one.

If USDG moves more than ±2% from $1, every market halts: no new loans and no liquidations through a depeg.

Chainlink publishes equity feeds on Robinhood Chain mainnet only. On testnet, a keeper copies every new mainnet Chainlink print for TSLA, AMZN and USDG into Chainlink-compatible feeds every 30 minutes, so the demo trades on real prices and freezes when mainnet does.

09

Safety and testing

  • Repay can never be paused.
  • No liquidation on a frozen price.
  • ERC-4626 virtual shares against inflation attacks, and internal cash accounting so donations cannot move the share price.
  • OpenZeppelin contracts in Solidity and in Stylus; reentrancy guards on every state change.
  • 97 unit and fuzz tests, plus 5 fork tests against Robinhood Chain mainnet state.

Afterglow is unaudited and runs on testnet only. Do not use it with real funds.

10

Contracts

Robinhood Chain testnet (chain 46630). Current maturity: 29 Oct 2026, 20:00 UTC. Hover an address to see it in full.

ContractRoleAddress
Phaselock oraclePrices and market session0xf9E4…03Bc
GapGuard (Stylus)Weekend gap model0x5D3D…49bB
Savings vaultWeekend sweep target0x1aE8…44f2
USDGLoan asset (testnet)0x7E95…802F
USDG / USD feedDepeg circuit breaker0x1931…9eC8

AMZN market

ContractAddress
Market (ERC-4626)0xFD6F…F253
Tranches0x4048…9395
Protected share token0x1E71…c1F7
Boost share token0x84da…F1Dc
AMZN stock token0x5884…9E02
AMZN price feed0xCAae…87c0

TSLA market

ContractAddress
Market (ERC-4626)0xC1c0…Af65
Tranches0x16F5…38a0
Protected share token0x6F91…7ba8
Boost share token0xcbDB…91Dd
TSLA stock token0xC9f9…Bd4E
TSLA price feed0x3313…c097

11

FAQ

Why a fixed rate?

Borrowers know the exact cost on day one, and lenders know their return for the term. Every loan in a market shares one rate and one maturity, which keeps the accounting simple and cheap.

Why 6% plus a premium?

The 6% pays for the money. The premium pays for the weekend gap risk, which differs by stock, so it is priced per stock from measured gaps and paid to the tranche that carries it.

Who buys liquidated stock?

Liquidators repay the debt and receive the collateral plus a bonus (7% for stocks), then sell during market hours. On-chain liquidity for stock tokens is still thin, so liquidators need their own route to sell. This is a known limit.

What happens if nobody borrows?

Unlent USDG earns the savings-vault yield through the sweep. Protected still gets topped up from Boost, so Boost may earn less than the headline example.

Is it audited?

No. It is a hackathon build on testnet.