Protocol documentation

How Locksley works

Locksley is a savings and loan rebuilt as three smart contracts on Robinhood Chain: a treasury-backed savings vault, escrowed standing orders, and stock-collateralised loans. No contract has an owner, a pause switch, a fee, or an upgrade path. This is the technical reference for what they do and, just as importantly, what they cannot.

Chain Robinhood (EVM 4663)Unit USDG · 6 decimalsBacking SGOV · short U.S. treasuriesAdmin none
Overview

A bank with no banker

A bank does three things with your money: holds it and pays you something for the privilege, moves it on your instruction, and lends against what you own. Locksley does the same three, but every one of them is a contract you can read, and the only key that moves your balance is yours. There is no institution in the middle - not even us.

  • Savings - your USDG buys SGOV, a token of short-dated U.S. treasury bills. It earns what the bills earn, in the vault, under your name.
  • Standing orders - escrow USDG once and it pays out on a schedule. Rent, a salary, an allowance. Cancel any time and the remainder comes back.
  • Collateral loans - post a tokenised stock, borrow USDG against up to half its value, never sell it. Lenders supply the reserve and earn the interest.

Everything on this page is enforced by the contracts, not the app. The interface is a window onto state anyone can read or write directly with a wallet.

Vision & mission

Banking that cannot betray you

Vision

Most financial failure is not fraud. It is an institution doing something it was allowed to do: freezing a withdrawal, changing a rate, raising a fee, halting a product, being bought and shut down. The remedy is not a better institution. It is removing the seat the institution sits in. Locksley's vision is ordinary banking - save, pay, borrow - where that seat is empty by construction.

Mission

  • Non-custody as a hard property. No address in any Locksley contract can move a balance that is not its own. This is verified in the source, not promised in a policy.
  • Real yield only. The savings rate is whatever U.S. treasury bills pay. Locksley invents no rate, subsidises nothing, and prints nothing.
  • Honest limits. Where a mechanism has a weakness - spot pricing, a locked term, liquidation - it is documented here, not hidden behind marketing.
  • Immutable. What is deployed is final. A bug is permanent and so is every guarantee. We chose that trade deliberately.
Architecture

Three contracts, zero shared state

The contracts do not know about each other. Each holds only the funds its own users deposited, tracks them per address, and talks to exactly one external system - a Uniswap v3 pool - to price or swap. There is no router, no registry, no shared treasury, and no proxy in front of any of them. If one were to fail, the other two would not notice.

Your walletthe only key that moves fundsSavingsUSDG → SGOV, per-user sharesStandingOrdersescrow, pays on scheduleCollateralLoanreserve + stock-backed debtUSDG / SGOV poolUniswap v3 · fee 0.30%USDG / stock poolsUniswap v3 · spot priceAnyonemay call execute(id)

Three contracts, no shared vault, no owner. Each holds only what its own users put in.

Mechanism

Savings backed by treasuries

deposit(usdgIn, minSgovOut) swaps your USDG for SGOV through the USDG/SGOV Uniswap v3 pool and credits shares[you]with the SGOV received. The vault is a share ledger; the SGOV itself sits in the contract. withdraw(sgovShares, minUsdgOut) reverses it. Both take a minimum-output floor you set, so a moved price reverts rather than fills badly.

1,000 USDGdeposit(usdgIn, minSgovOut)swap on Uniswap v3USDG → SGOV, slippage floor enforced9.91 SGOVshares[you] += 9.91SGOV ≈ $100.92 → the vault holds treasuries, your balance is a share countwithdraw() reverses the swap · locked deposits add an unlockAt timestamp, nothing else

Yield is not paid by Locksley. SGOV appreciates against USDG as the bills it holds accrue; the vault just holds your share of it.

Where the yield comes from

SGOV is a token of an ETF that holds 0-3 month U.S. treasury bills. As those bills accrue, SGOV's price against USDG rises. Your share count never changes; the USDG value of each share does. Locksley pays nothing, takes nothing, and cannot change the rate - the rate is the bill.

Locked deposits

depositLocked(usdgIn, minSgovOut, term) works identically but records unlockAt = now + term and keeps the shares in a separate lockedShares balance.withdrawLocked reverts until that timestamp. The term is capped at MAX_TERM = 730 days. A lock earns exactly what an open deposit earns - it is a commitment device, not a bonus.

# value of your position, in USDG
value = (shares + lockedShares) × sgovPrice
# sgovPrice read from pool sqrtPriceX96, 6-decimal USDG per 18-decimal SGOV
Mechanism

Standing orders

create(token, recipient, amount, interval, payments, startDelay, expiry)pulls amount × payments into escrow and records the schedule. From then on, execute(id) pays one instalment to the recipient if nextDue has passed - and anyone may call it. The recipient can, a bot can, you can. The order does not depend on Locksley being online, because Locksley has no server in the loop.

  • Cancel - only the owner. Every unpaid instalment returns immediately.
  • Expiry - optional. Past it, execute reverts and cancellation is the only exit.
  • Nothing is skipped - if nobody calls execute for two intervals, the next call pays one instalment and advances the clock by one interval. Missed periods queue; they do not vanish.

Because execution is permissionless, a recipient who wants their money on time has every incentive to trigger it themselves. The schedule is a right they hold, not a favour they wait for.

Mechanism

Loans against stock

Two sides share one contract. Lenders call supply(usdg)and receive reserve shares; redeem returns their USDG plus their portion of accrued interest. Borrowers call depositCollateral(token, fee, amount) with a tokenised stock that has a USDG pool, then borrow(usdg) up to MAX_LTV_BPS = 50% of the collateral's value.

How collateral is priced

_value() reads sqrtPriceX96from the stock's own Uniswap v3 pool at call time and converts it to USDG per share. This is the spot price, not a time-weighted average. It is honest about what the market says right now and it is the mechanism's biggest weakness - seeRisks.

Interest

Debt accrues per second at RATE_PER_SEC, about 8% a year, compounded through a global index so the contract never loops over borrowers. Everything a borrower pays in interest goes to the reserve, which is to say to the lenders. There is no spread and no treasury cut.

DEBT AS A SHARE OF COLLATERAL VALUEcan borrow · up to 50%bufferliquidatable · above 60%MAX_LTV 50%LIQ_THRESHOLD 60%Collateral is priced from the stock's own Uniswap v3 pool (sqrtPriceX96) at the moment of the call.Interest accrues per second at RATE_PER_SEC and is owed to the lenders who supplied the reserve.

Borrowing stops at 50%. Between 50% and 60% you cannot borrow more but cannot be liquidated either. Past 60%, anyone may repay half your debt and take collateral at an 8% discount.

Mechanism

Liquidation, by anyone

A position is liquidatable once debt exceeds LIQ_THRESHOLD_BPS = 60%of collateral value. Anyone may then call liquidate(user, repayAmount): they repay up to CLOSE_FACTOR_BPS = 50% of the debt in USDG and receive collateral worth that amount plus an 8% bonus. The bonus is what makes it worth someone's gas to keep the reserve solvent; the close factor stops a single call from emptying a position that could have recovered.

# collateral seized for a repayment r, at stock price p
seized = r × (1 + 0.08) / p
# the borrower keeps everything else and still owes the rest

The 10-point gap between the borrow cap and the liquidation line is deliberate. A borrower at exactly 50% is not one bad tick from liquidation - the stock must fall roughly 17% first.

Trust

Who can move what

The clearest way to state the custody model is as a permission table. Three actors exist: you, everyone else, and Locksley. The last column is empty on purpose.

Your key candeposit · withdrawcreate · cancel orderssupply · borrow · repaypost · pull collateralAnyone canexecute(id) a due paymentliquidate() past 60%read every balancenothing that takes your fundsLocksley can— nothing —no owner · no pauseno fee switch · no upgradeno way to freeze or seize

The third column is the product. There is no address in any contract with more power than yours.

Concretely: no function in any of the three contracts is gated by an owner, admin, guardian or multisig role. There is no Ownable, no Pausable, no upgradeable proxy, no fee recipient variable. The deployer's key was used once, to deploy, and has no standing afterwards. You can confirm this by reading the source on Blockscout - it is short.

Trust

What the cryptography actually guarantees

Locksley adds no cryptography of its own. It rests entirely on the primitives of the chain, and it is worth being precise about which ones do what.

Authorisation: ECDSA over secp256k1

Every state change is a transaction signed by an Ethereum account. The contract checks msg.sender - the address recovered from that signature - against the ledger it keeps. Only the address that deposited can withdraw; only the order's owner can cancel; only the borrower can pull their collateral. Nobody, including us, can forge a signature for your key.

Integrity: the chain's consensus

Balances are storage slots in a contract whose bytecode is fixed at deployment and hashed into every block that follows. Altering a balance would mean altering Robinhood Chain's history. This is the same guarantee that protects USDG itself.

Re-entrancy and token safety

All three contracts inherit OpenZeppelin's ReentrancyGuardand every external state-changing function is marked nonReentrant, so a malicious token or pool callback cannot re-enter mid-operation. Token transfers go through SafeERC20, which reverts on the non-standard tokens that return nothing instead of true.

Price arithmetic

Uniswap v3 encodes price as sqrtPriceX96, a Q64.96 fixed-point square root. The contracts square it with Math.mulDiv (full 512-bit intermediate, no overflow) and rescale between USDG's 6 decimals and the stock's 18. Mixing those decimals is the classic way a vault silently misprices by 10¹²; the tests pin the conversion.

There is no zero-knowledge, no encryption, no off-chain signing service. What you see on-chain is the whole system. Anything that sounds more clever than that would be a place to hide something.

Trust

Risks and limits

These are the things that can go wrong. They are real, and knowing them is the price of using a system nobody can pause.

  • Spot-price collateral. CollateralLoan prices collateral from the pool's current tick, not a TWAP. A large enough flash-loan swap can move that price within one block. The 50% cap, the 60% threshold and the 50% close factor limit the damage, but a manipulated liquidation is possible. Do not put your only copy of something in as collateral.
  • SGOV is an ETF token. It carries the issuer's risk and the peg of the wrapper that brought it on-chain. Locksley cannot see or fix either.
  • Pool liquidity. Deposits and withdrawals swap through Uniswap. Thin liquidity means slippage; your minOut floor is the only protection. Set it.
  • Immutability cuts both ways. A bug found after deployment stays. The tests are thorough - 22 passing, including boundary and liquidation cases - but tests prove what was imagined.
  • Not a bank. No deposit insurance, no regulator, no recourse. That is the design.

The loan contract is the highest-risk of the three by construction. Treat it as an experiment until it has been independently audited, and size positions accordingly.

Protocol

Reference

Deployed contracts - Robinhood Chain

ContractRoleAddress
SavingsUSDG ⇄ SGOV vault, open + locked terms0xF28571Da91c7A8d3511A57f81b57098f9d1970b8
StandingOrdersEscrowed scheduled payments0x9188572646DCa8460360267CCE10cB88a764743E
CollateralLoanLender reserve + stock-backed borrowing0x4b5181c539954b28cF69a05b9eC45161c6eC587A

Protocol constants

ConstantValueMeaning
MAX_TERM730 daysLongest lock a savings deposit can choose
SGOV_FEE3000 (0.30%)Uniswap v3 pool tier the vault swaps through
MAX_LTV_BPS5000 (50%)Most you can borrow against collateral value
LIQ_THRESHOLD_BPS6000 (60%)Debt-to-collateral at which a position can be liquidated
LIQ_BONUS_BPS800 (8%)Discount a liquidator receives on seized collateral
CLOSE_FACTOR_BPS5000 (50%)Share of debt one liquidation may repay
RATE_PER_SEC2,535,100,000 (1e18 scale)Borrow interest, ≈ 8% APR, accrued per second

Shared addresses

NameRoleAddress
USDGQuote asset, 6 decimals0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168
SGOVSavings backing, 18 decimals0x92FD66527192E3e61d4DDd13322Aa222DE86F9B5
Uniswap v3 FactoryPool lookup0x1f7d7550B1b028f7571E69A784071F0205FD2EfA
SwapRouter02Savings swaps0xCaf681a66D020601342297493863E78C959E5cb2