Docs
How Afterglow works.
The mechanism, the numbers and the reasoning behind them. Testnet build, unaudited.
View source on GitHub01
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
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:
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:
| Session | When | Borrow | Withdraw collateral | Liquidate |
|---|---|---|---|---|
| Live | Market open and the feed has printed | Up to base LTV | If LTV stays under the limit | Yes |
| Closing | Final 4 hours before the weekly close | Limit ramps down | If LTV stays under the ramped limit | Yes |
| Closed | Weekend, holiday, or reopened with no new print | No | Only under the weekend LTV | No |
| Halted | Corporate action, sequencer outage, bad or stale price, USDG depeg | No | No | No |
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.
| Collateral | Weekday LTV | Weekend LTV | Liquidation LTV | Liquidator 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:
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.
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:
| Protected | Boost | |
|---|---|---|
| Paid | First, up to a 5% target | Everything left, incl. all premiums |
| Losses | Only after Boost is gone | First |
| Size | Up to 80% of the vault | At 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.
Example vault of 100,000 USDG, 25,000 in Boost earning 25% before losses.
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:
| Session | Kept as cash | Why |
|---|---|---|
| Live / Closing | 20% | Borrowers can draw at any moment |
| Closed | 5% | No borrowing until the reopen |
| Halted, paused, matured | 100% | 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.
| Contract | Role | Address |
|---|---|---|
| Phaselock oracle | Prices and market session | 0xf9E4…03Bc |
| GapGuard (Stylus) | Weekend gap model | 0x5D3D…49bB |
| Savings vault | Weekend sweep target | 0x1aE8…44f2 |
| USDG | Loan asset (testnet) | 0x7E95…802F |
| USDG / USD feed | Depeg circuit breaker | 0x1931…9eC8 |
AMZN market
| Contract | Address |
|---|---|
| Market (ERC-4626) | 0xFD6F…F253 |
| Tranches | 0x4048…9395 |
| Protected share token | 0x1E71…c1F7 |
| Boost share token | 0x84da…F1Dc |
| AMZN stock token | 0x5884…9E02 |
| AMZN price feed | 0xCAae…87c0 |
TSLA market
| Contract | Address |
|---|---|
| Market (ERC-4626) | 0xC1c0…Af65 |
| Tranches | 0x16F5…38a0 |
| Protected share token | 0x6F91…7ba8 |
| Boost share token | 0xcbDB…91Dd |
| TSLA stock token | 0xC9f9…Bd4E |
| TSLA price feed | 0x3313…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.