STLNCHR

Robinhood Chain · chain 4663

Contracts

Five contracts. Two of them, the lens and the router, are all most integrations ever touch.

Addresses

The same set, machine readable, is at /.well-known/lnchr.json. ABIs are served at https://lnchr.io/abi/PackLens.json and the same path for each of the five.

PackRegistry

Registers packs and holds the list of stocks a pack can be built from, each with a curated route. register(stocks, prices, deadline, signature) deploys the vault at a CREATE2 address derived from the ordered list, so the same list can never exist twice and the address is knowable in advance. isPack(address) is the one call an integrator needs.

solidity
register(address[] stocks, uint256[] pricesUsd, uint256 deadline, bytes signature) returns (address)
isPack(address) view returns (bool)
predict(address[] stocks) view returns (address)
tickerOf(address[] stocks) view returns (string)
packCount() view returns (uint256)
allPacks(uint256) view returns (address)
routeOf(address stock) view returns (Route)

PackVault

The pack itself, one per registered combination, deployed by the registry. A plain ERC-20 with an immutable ordered stock list and fixed quantities per unit. mint and redeem are open to anyone: redeem hands back the underlying stocks pro rata on the vault's actual balances, which is also how dividends and corporate actions reach holders. No owner, no pause, no proxy.

solidity
stocks() view returns (address[])
unitQty() view returns (uint256[])
composition() view returns (uint256[])
holdings() view returns (uint256[])
required(uint256 units) view returns (uint256[])
mint(uint256 units, address to) returns (uint256)
redeem(uint256 units, address to) returns (uint256[])

PackHook

The Uniswap v4 hook every pack pool runs on. beforeSwap replaces the swap: a buy takes the quote asset in, buys each stock on its own curated route, mints the pack and delivers it; a sell runs backwards. The pools hold no reserves, reject liquidity and need no arbitrage, because every trade moves the underlying. Two pools per pack, against WETH and USDG.

solidity
poolKey(address pack, address quote) view returns (PoolKey)
packOfPool(PoolId) view returns (Pack)

PackLens

The read surface. One call returns everything about a pack, including NAV, so nothing has to reach into registry or vault internals.

solidity
packInfo(address pack) view returns (PackView)
packs(uint256 offset, uint256 limit) view returns (PackView[])
navUsdg(address pack) view returns (uint256)
stocks() view returns (StockView[])
exists(address[] stocks) view returns (bool, address, string)
poolKeyFor(address pack, address quote) view returns (PoolKey)

PackRouter

Buying and selling packs without driving a v4 unlock yourself. Each call is one transaction and returns the amount out, so simulating it is also how you quote it.

solidity
buyWithEth(address pack, uint256 minOut) payable returns (uint256)
buyWithUsdg(address pack, uint256 amountIn, uint256 minOut) returns (uint256)
sellForEth(address pack, uint256 amountIn, uint256 minOut) returns (uint256)
sellForUsdg(address pack, uint256 amountIn, uint256 minOut) returns (uint256)

Verifying a pack yourself

Everything a pack claims is checkable on chain without trusting this site: the vault's stock list and quantities are immutable, its holdings are ERC-20 balances you can read directly, and redeem pays them out pro rata to anyone who asks.