Smart LP developers

Registry, lens, ABIs, selectors and events for wallets, dashboards and bots.

Smart LP · Volatility Farming

For wallets, dashboards, yield aggregators, and keeper bots wiring deposits, withdrawals, reads, and indexing on the Safety Deposit Box Smart LP vaults. Each vault is an immutable ERC-20 share token over one Uniswap v3 position. Discover vaults from the registry, read the floor through the lens, and never hardcode a vault address.

Guide version 2026-09-28 (rev 3). Robinhood Chain 4663 and Arbitrum One 42161.

Downloads

Full guide with share math, guard behaviour, keeper surface, revert selectors and event topics. ABIs are byte exported from the deployed artifacts.

Two bytecode generations, one of them live

Every listed vault today runs the audited V1 generation on both chains (179 vaults on Robinhood Chain, 22 on Arbitrum One at the time of writing). V2 is the staged remediation of the SB Security review and is not deployed. It ships as new vault addresses on the same registries, so feature probe per vault: an eth_call to canSettle() decodes a bool on V2 and reverts with empty data on V1. V1 vaults keep working forever, withdrawals included.

Live addresses

Robinhood Chain (chainId 4663)179 vaults listed
ContractAddress
SmartLpRegistry (source of truth)0xE874…01460xE8749183Fbf6A657EB58B3a4D3E4B9Cc09560146
SmartLpLens (all reads)0x754B…3D4d0x754Bf8479630bbC22aA7b5E9742156ce89dD3D4d
SmartLpLib (linked library)0x4A2d…E32F0x4A2dA8e70b51595Bf564082A86336AbDDc62E32F
Chainlink ETH/USD0x6091…27210x6091E64eb7138EEF066a80FD3A0d7427B91f2721
Arbitrum One (chainId 42161)22 vaults listed
ContractAddress
SmartLpRegistry (source of truth)0xFB2e…eD5e0xFB2eA53b16C07011d4390A2e449385180A54eD5e
SmartLpLens (all reads)0x1243…887F0x1243c8FB4099568460ba0619aaB24DC15758887F
SmartLpLib (linked library)0x4A2d…E32F0x4A2dA8e70b51595Bf564082A86336AbDDc62E32F
Chainlink ETH/USD0x639F…a6120x639Fe6ab55C921f74e7fac1ee960C0B6293ba612

The registry is the only source of truth for vault addresses on each chain, and vaults never move between chains. Delisting only removes a vault from the UI surface; the vault keeps working, so keep serving positions you already track.

Verifying a vault is genuine

Registry listing is a curation signal. To verify a vault carries the audited bytecode, fetch its runtime code and check all three: code length exactly 23,718 bytes, every linked library slot carries 0x4A2dA8e70b51595Bf564082A86336AbDDc62E32F, and the code with immutables, library slots and the solc metadata hash blanked to zero hashes to 0x1c32f1291fb1038d8c6506800210a217c649195efb2dd0134869d8776d1eb2e3. The same pin passes on both chains; the site applies it to every registry row before rendering (app/lib/smartLpCodePin.ts).

Discovery and reads

solidity
// SmartLpRegistry
count() ? uint256
vaults(index) ? address
all() ? address[]

// SmartLpLens (live)
viewAll(registry) ? VaultView[]           // whole floor in one call
viewVault(vault) ? VaultView
previewWithdraw(vault, shares) ? (out0, out1)   // net of the 10 bps retention

// VaultView: vault, pool, token0, token1, symbol0/1, decimals0/1, mode (0 FR / 1 BB / 2 ASK),
// baseIsToken0, poolFee, tickLower, tickUpper, spotTick, positionId, totalSupply,
// totalValueQuote, tvOk, capQuote, maxCapQuote, perfFeeBps, withdrawFeeBps,
// depositsPaused, settled, allBase, lastRecenterAt, feeManager

Shares are quote denominated (about one quote unit per 1e18 shares at genesis). Never present shares as token amounts; show USD and underlying values from the lens. Treat tvOk == false as value unavailable, never as zero TVL. USDG, USDC and USDT are 6 decimals.

Deposits and withdrawals

solidity
// Deposits (guarded by TWAP band + fresh Chainlink cross check, capped)
deposit(amount0, amount1, minShares, to) payable        // FR, BB pair deposit
zapDeposit(tokenIn, amountIn, minShares, to) payable     // FR, BB single token entry (swaps in the vault pool)
depositSingle(amountBase, minShares, to) payable         // ASK base only, swap free

// Withdrawals (never pausable, never gated, no oracle)
withdraw(shares, min0, min1, unwrapNative, to)           // proportional, in kind
zapWithdraw(shares, tokenOut, minOut, unwrapNative, to)  // single token exit, runs the guard

// Permissionless cranks
compound()                                               // collect fees, skim 10%, reinvest
harvest()                                                // harvest mode vaults only, pays the caller a reward

Every deposit function returns the minted shares, so an eth_call from the depositor is the quote: sign with minShares at 98% of the simulation. Native ETH on WETH quoted vaults is added on top of the declared amount (pass amountIn = 0 with msg.value). Approve the vault for the exact amount. A genesis deposit must be worth at least minFirstDepositQuote(). The 10 bps withdraw retention stays in the vault for remaining holders; show it before signing.

Stock vaults carry a Chainlink cross check that only runs while the feed is fresh. Equity feeds pause from Friday close to Monday 00:00 UTC, which widens the TWAP band instead of blocking; on Monday open a drifted pool briefly reverts FeedDeviation on deposits until arbitrage converges it. Probe availability with a 1 wei simulated deposit and gate the form with plain copy. Plain withdraw is never affected.

Revert selectors

Selectorsidentical on both chains
SelectorErrorAction
0xa4875a49CapExceededDeposit would push TVL over capQuote. Show vault full.
0x64a78d82TwapDeviationSpot too far from TWAP. Retry later.
0xc7f602abFeedDeviationPool vs fresh Chainlink diverged over 3% (Monday opens). Self heals.
0x007426cdFirstDepositTooSmallGenesis deposit under minFirstDepositQuote().
0xdeeb6943DepositsPausedGuardian pause. Withdrawals unaffected.
0x1a8ade30DepositsClosedASK vault entered its band or reads settled.
0x2a580d6dWrongModeWrong entrypoint for the vault mode.
0x54b8210dMinSharesShare slippage floor hit. Re quote.
0x168f8aadMinOutWithdraw or zap output floor hit. Re quote.
0x0a7287b5NativeNotSupportedmsg.value sent to a vault without a wired WETH side.
0x15fa6e71NotPoolTokentokenIn or tokenOut is not one of the pool tokens.
0x1f2a2005ZeroAmountNothing pulled.
0x0cb4955bSwapFloorInternal swap fill under the TWAP floor. Retry later.
0xabf0f034NoPositionKeeper action on a vault with no minted position.
0xb0782df7CooldownKeeper action inside recenterCooldown.
0x98248e64EthSendFailedNative payout rejected. Withdraw with unwrapNative false.
0xb2f71223NotSettleable (V2)settle() before spot and TWAP are both past the band.
0x560ff900AlreadySettled (V2)settle() on a settled vault.
0xceee81e7DepthGate (V2)Band vault at capacity for its pool depth. Withdrawals unaffected.
0x13be252bUSDG InsufficientAllowanceUSDG custom allowance error. Raise the approval.

Events

Topic0logs land on the vault address; registry rows on the registry
EventTopic0
Deposited(address indexed sender, address indexed recipient, uint256 amount0, uint256 amount1, uint256 shares)0x8bab6aed5a508937051a144e61d6e61336834a66aaee250a00613ae6f744c422
Withdrawn(address indexed sender, address indexed recipient, uint256 amount0, uint256 amount1, uint256 shares)0x3cae9923fd3c2f468aa25a8ef687923e37f957459557c0380fd06526c0b8cdbc
Compounded(uint256 added0, uint256 added1)0x8082b0dab6d73a8025e5f15e4fdd54b68197a613e361810d4a2446c634b98ada
FeesCollected(uint256 fees0, uint256 fees1, uint256 skim0, uint256 skim1)0xf5d590414d56d256b8c16b850d0b57f2f5d2ed90686166e150b48a96f0dbdd61
Recentered(int24 tickLower, int24 tickUpper)0xf50915569476905e05b4ef6c338d995bc8bf49e89258202b9709c6dd6504e3d7
Trailed(int24 tickLower, int24 tickUpper)0xd606fe2b531f0b729332a3ba354a4acddcdc86720901401c7bbdd72af6556931
CapRaised(uint256 newCap)0xe0c76087275a8c4223be123d025629c6693fd33f20c0f0f6bf632708bda4329b
VaultListed(address indexed vault, address indexed pool, uint8 mode) [registry]0x3dd1a36f073a1702b0ea7db13a70123c0e21753a1571eaf80acacea471618152
VaultDelisted(address indexed vault) [registry]0x1e50537a8984b347abcf90ec072a917d874c1737aaca4e13ae66aa499977aab1
Settled(...) [V2]0x7823e479a1a4ebe2418874847436f8a1680c5ee5b17f38bb59dbff28e1b45552
DepositRefund(address indexed to, uint256 amount0, uint256 amount1) [V2]0x67b1105972f389118797e8b84acfdd40581567974b584258e34ff63c296eec46

Scan floors: Robinhood Chain block 53,800,000, Arbitrum One block 505,449,619.

HTTP activity feed

Smart LP HTTP
RoutePurpose
GET /api/locker/smartlp-activity?chain=robinhoodPer vault automation ledger on Robinhood Chain: compounds, collects, rebalances, lifetime fees, holders.
GET /api/locker/smartlp-activity?chain=arbitrumSame ledger for the Arbitrum One fleet.

Convenience only; the chain is the source of truth. Poll no more than every 30 seconds.

Staged V2 generation

V2 prices deposits on the vault basket instead of the TWAP, refunds the unused leg of a pair deposit, adds a permissionless settle() for single sided vaults, a depth gate on band vaults, and an exact previewWithdraw. Its ABIs are published so you can prepare; the guide tags every V2 row.

Smart accounts and ERC-6551 wallets are first class depositors (no EOA gate). Preflight the inner call from the account address so real selectors surface; gas comes from the signer. Questions and listings: simple@clutch.market.