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
| Contract | Address | |
|---|---|---|
| SmartLpRegistry (source of truth) | 0xE874…01460xE8749183Fbf6A657EB58B3a4D3E4B9Cc09560146 | |
| SmartLpLens (all reads) | 0x754B…3D4d0x754Bf8479630bbC22aA7b5E9742156ce89dD3D4d | |
| SmartLpLib (linked library) | 0x4A2d…E32F0x4A2dA8e70b51595Bf564082A86336AbDDc62E32F | |
| Chainlink ETH/USD | 0x6091…27210x6091E64eb7138EEF066a80FD3A0d7427B91f2721 |
| Contract | Address | |
|---|---|---|
| SmartLpRegistry (source of truth) | 0xFB2e…eD5e0xFB2eA53b16C07011d4390A2e449385180A54eD5e | |
| SmartLpLens (all reads) | 0x1243…887F0x1243c8FB4099568460ba0619aaB24DC15758887F | |
| SmartLpLib (linked library) | 0x4A2d…E32F0x4A2dA8e70b51595Bf564082A86336AbDDc62E32F | |
| Chainlink ETH/USD | 0x639F…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
// 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
// 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
| Selector | Error | Action |
|---|---|---|
0xa4875a49 | CapExceeded | Deposit would push TVL over capQuote. Show vault full. |
0x64a78d82 | TwapDeviation | Spot too far from TWAP. Retry later. |
0xc7f602ab | FeedDeviation | Pool vs fresh Chainlink diverged over 3% (Monday opens). Self heals. |
0x007426cd | FirstDepositTooSmall | Genesis deposit under minFirstDepositQuote(). |
0xdeeb6943 | DepositsPaused | Guardian pause. Withdrawals unaffected. |
0x1a8ade30 | DepositsClosed | ASK vault entered its band or reads settled. |
0x2a580d6d | WrongMode | Wrong entrypoint for the vault mode. |
0x54b8210d | MinShares | Share slippage floor hit. Re quote. |
0x168f8aad | MinOut | Withdraw or zap output floor hit. Re quote. |
0x0a7287b5 | NativeNotSupported | msg.value sent to a vault without a wired WETH side. |
0x15fa6e71 | NotPoolToken | tokenIn or tokenOut is not one of the pool tokens. |
0x1f2a2005 | ZeroAmount | Nothing pulled. |
0x0cb4955b | SwapFloor | Internal swap fill under the TWAP floor. Retry later. |
0xabf0f034 | NoPosition | Keeper action on a vault with no minted position. |
0xb0782df7 | Cooldown | Keeper action inside recenterCooldown. |
0x98248e64 | EthSendFailed | Native payout rejected. Withdraw with unwrapNative false. |
0xb2f71223 | NotSettleable (V2) | settle() before spot and TWAP are both past the band. |
0x560ff900 | AlreadySettled (V2) | settle() on a settled vault. |
0xceee81e7 | DepthGate (V2) | Band vault at capacity for its pool depth. Withdrawals unaffected. |
0x13be252b | USDG InsufficientAllowance | USDG custom allowance error. Raise the approval. |
Events
| Event | Topic0 |
|---|---|
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
| Route | Purpose |
|---|---|
| GET /api/locker/smartlp-activity?chain=robinhood | Per vault automation ledger on Robinhood Chain: compounds, collects, rebalances, lifetime fees, holders. |
| GET /api/locker/smartlp-activity?chain=arbitrum | Same 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.
