Documentation
How Plumb works
Everything the engine does, and everything it cannot do. The numbers on this page are read directly from the running code — if the engine changes, this page changes with it.
What this is
Plumb moves USDC between lending vaults on Base. It does not trade, use leverage, or take directional positions. Your deposit earns the interest those vaults pay to lenders, minus the gas spent moving between them.
The engine runs once a day. It reads each vault's recent yield and size, scores them, computes a target allocation, and moves money only when the gap is large enough to be worth the gas.
This is not a savings account. The capital is deposited into third-party smart contracts. Losing part or all of it is a real outcome, and no part of this system prevents that. Section 06 is the honest list.
Which vaults are eligible
The engine only ever touches an explicit list of contract addresses. A vault enters that list by hand, after a human has read it — never automatically.
A screener runs daily and looks for vaults that might deserve a place. To be flagged, a candidate must hold at least $20M, have 60+ days of history, not be bleeding size, and — the important one — reconcile against the chain: its asset() must be native USDC and its totalAssets() must match the TVL the data provider reports.
That last check exists because of a real incident. A vault named Sirloin was reported at $246.8M by DefiLlama. The contract held $10,097 — the figure was wrong by a factor of roughly 24,000, and an earlier version of the engine was allocating 12% of the portfolio to it, which was more than the vault's entire size. It is still declared in the code, disabled, with that reason attached, so the mistake cannot quietly return.
Flagging is not admission. A flagged vault sends a notification and waits. It receives money only once its address is added both to the allocation list and to the signing policy — and the policy refuses to sign toward any address it does not know, so a mistake in one place is caught by the other.
Excluded, and why
- Sirloin USDC — TVL DefiLlama irréconciliable avec la chaîne (246,8 M$ annoncés, 10 097 $ réels)
How vaults are scored
The engine reads slow signals only. It does not try to detect an exploit or a depeg in progress: those happen in a single block, and nobody escapes them by being fast. What it can see is gradual decay — yield eroding, depositors leaving, a return that is suspiciously high — and reduce exposure before that becomes expensive.
A vault is marked for full exit when either:
- its TVL falls 50% or more over 7 days — other depositors are leaving and you should not be last out;
- its yield collapses 60% or more against its own 30-day average.
It is put on watch — half weight — when:
- its TVL falls 25% or more over 7 days;
- its yield swings by 3 points of standard deviation or more over 14 days;
- its yield exceeds 2× the median of its peers.
That last rule is worth stating plainly: an unusually high yield lowers a vault's score rather than raising it. The excess is also capped out of the score entirely, so chasing it earns nothing. On-chain, a return far above everyone else's is usually compensation for a risk that has not shown up yet.
How capital is allocated
Scores become target weights proportionally, raised to a power of 1.5 so better vaults get meaningfully more without the allocation collapsing into a single name. Three limits sit on top.
A cap per vault. No vault can exceed its share, whatever its score. This is the main defence: no single accident can erase the portfolio. Overflow from a capped vault is redistributed to the others.
| Vault | Curator | Max share |
|---|---|---|
| Aave v3 USDC | Aave DAO | 30% |
| Gauntlet USDC Prime | Gauntlet | 25% |
| Fluid USDC | Fluid | 25% |
| Steakhouse Prime USDC | Steakhouse Financial | 20% |
| Steakhouse USDC | Steakhouse Financial | 20% |
| Moonwell Flagship USDC | Moonwell | 15% |
| Spark USDC Vault | Spark | 12% |
The caps sum to 147%, well above 100% — they are individual ceilings, not a plan. In practice the allocation is spread across whichever vaults score well on the day.
A liquidity buffer. 10% of the portfolio is never invested. It sits as idle USDC in your wallet so a withdrawal can be honoured without waiting for a vault to have room — including on the day everyone wants out at once, which is exactly the day vaults do not.
Hysteresis. The engine only moves when a position drifts 8% or more from its target. Chasing a two-point yield difference costs more in gas and execution risk than it returns. Most days, the correct action is to do nothing, and the engine does nothing.
How your money actually moves
When you sign up, a wallet is created for you. You are the only beneficiary of it; the engine holds the ability to sign transactions from it, within strict limits.
Those limits are enforced outside our code, by the wallet provider. A policy lists the contract addresses this wallet may sign toward, and the single outside address it may send USDC or ETH to: the withdrawal address you register yourself. Anything else — a transfer to any other address, an unknown contract, a token approval outside the list — is refused before it reaches the chain. A bug in our engine cannot move your funds somewhere they should not go.
Getting your money out. You register a withdrawal address — a wallet you connect, or an address you paste — and that address is written into the policy. You can then withdraw any amount, or everything, at any time. If the amount is larger than the idle buffer, the engine unwinds vault positions first, largest position first so it touches as few vaults as possible, and transfers only once the USDC has actually landed. The amount sent is read from the chain at that moment rather than estimated in advance.
The ETH you sent for gas comes back the same way, to the same address. While you still hold USDC, 0.002 ETH stays on the account: that ETH is what pays for unwinding your positions, and a wallet with no gas cannot sign its own withdrawal. Once your USDC balance is empty there is nothing left to unwind, and you can take all of the ETH out.
Withdrawal does not wait for the daily run, and it is not affected by the switch that pauses the engine. The day we stop the engine is the day you are most likely to want out.
Stopping without leaving. Your dashboard has a switch that suspends the engine on your account alone. While it is off, your free USDC is left where it is and nothing is rebalanced. It does not sell anything: positions you already hold stay in their vaults and keep earning until you exit them. Your account is still measured every day, so the value curve does not break while you are paused.
Exiting is the other half, and it is separate on purpose. Each position has its own exit, and there is one for all of them at once. Exiting unwinds the vault and leaves the USDC free on your account — it does not send anything outside, so it costs one set of fees instead of the two a withdraw-and-return would. If the engine is still switched on, it will put that money back to work at the next run; switching off first is what makes an exit stick.
Each day the engine takes a snapshot of your balances, computes the plan, and executes withdrawals before deposits so it never tries to spend money it has not received yet. Every movement is recorded with what the chain answered — confirmed or failed; if the run is interrupted, replaying it skips what already confirmed rather than doing it twice.
Gas is yours. Transactions on Base cost ETH, paid from your own wallet. If it runs out, the engine skips your account that day and records why — it does not silently fail. Your dashboard shows the balance and warns you before it becomes a problem.
What can go wrong
This is the section to read twice. It is written to be complete rather than reassuring.
Risk
Smart contract failure. Your USDC sits in third-party contracts. A bug or exploit in any of them can lose the funds allocated to it. The per-vault cap bounds how much, but does not prevent it. The engine reads yield and size — it cannot read a vulnerability.
Risk
Bad debt in the lending market. These vaults lend against collateral. If a collateral asset crashes faster than liquidators can act, the loss is borne by depositors. This is not hypothetical and it does not require anyone to be malicious.
Risk
Curator risk.Most vaults here are curated: a team decides which markets the vault lends into, and can change that. A curator can add a risky market, and your exposure changes without any transaction on your side. Reading the curator's past decisions is part of why admission is manual.
Risk
USDC depeg. Everything here is denominated in USDC. If USDC loses its peg, the whole portfolio loses value at once, and diversifying across vaults does nothing about it.
Risk
The engine is deliberately slow. It runs once a day on slow signals. An exploit, a depeg, or a sudden collapse happens between two runs, and the engine will react after the fact or not at all. It reduces exposure to decay, not to catastrophe. Nothing in this product is a stop-loss.
Risk
Withdrawal is not instant. The buffer covers ordinary withdrawals. Beyond it, exiting requires the vault to have liquidity — and a vault under stress is precisely the one that will not. A withdrawal that has to unwind positions is several transactions; if one of them fails, the engine stops rather than paying you part of what you asked for, and the rest stays invested until you try again.
Risk
The withdrawal address is yours to get right. If you register an address you do not control — a typo, a clipboard swap, an exchange account that does not accept USDC on Base — the funds sent there are gone. No one can reverse it, and we cannot recover it. The policy guarantees your money can only go to the address you declared; it cannot know whether that address is really yours. The same address receives both your USDC and your ETH, so an address that only handles one of the two loses the other.
Risk
Custody and key risk. Your wallet's keys are held by our infrastructure provider, not by you. A compromise there, or the loss of our authorization key, is a risk you are taking. The signing policy limits what a compromise can do; it does not eliminate the dependency. And the policy itself is ours to write: registering your withdrawal address rewrites it. Whoever controls our credentials can therefore change where your funds are allowed to go. The policy protects you from our bugs, not from us.
Risk
Exporting your key.Your account can hand you the wallet's private key, and that is the answer to the paragraph above: it is the one way to stop depending on us. It is also the one action here that cannot be undone. The key is decrypted in your browser and our servers never see it in the clear, but once you hold it, the signing policy no longer constrains that wallet — anyone who obtains the key can send its funds anywhere, and we would have no way to tell that apart from you doing it. Nobody from this project will ever ask you for it. Every export is logged.
Risk
Data and infrastructure. The engine reads a third-party yield API. Wrong data has already produced a wrong allocation once — see section 02. On-chain reconciliation is the defence, and it is not a proof of correctness.
Risk
This is unaudited software written by a very small team, running with real money. Deposit an amount you can afford to lose entirely.
What the engine does not do
- It does not predict yields. It reacts to what has happened.
- It does not trade, use leverage, or short anything.
- It does not guarantee a return, and past results are a backtest, not a promise.
- It cannot exit a position faster than the vault allows.
- It cannot see a smart contract vulnerability.
- It does not move funds anywhere except the listed vaults — the signing policy makes that structural rather than a promise.
Verifying any of this
Every claim on this page is checkable. Your positions are on-chain and readable by anyone with your wallet address, which the dashboard shows. Every decision the engine takes about your account is written to your activity journal, including the days it decided to do nothing and the days it skipped you for lack of gas.
The simulation runs the same engine over historical data, with no knowledge of the future at any point in the simulation — that is what makes the backtest worth looking at, and it is still a backtest.
Three things about how that chart is built, because they change how it reads.
It only ever holds vaults this engine would accept. A vault enters the simulation on the day it would have cleared the admission rules of section 02 — the same $20M floor and 60 days of history the screener applies today, not a looser version written for the backtest. The chart then starts on the first day enough of them had cleared it for the engine to deploy the 90% it targets. Earlier history exists in the data and is deliberately left out: back then a $100,000 deposit was a large share of the vaults on offer, and it would have moved the very rate the chart claims to measure. The record is shorter this way. It is also the only version the engine could have actually delivered.
The benchmarks carry the same constraint. Each dashed line holds back the same 10% cash buffer as the strategy, so the gap between them is about picking, not about staying liquid. They keep one advantage: none of them pays gas. The gas the strategy paid is shown next to the curve.
One of them is named with hindsight. The largest Morpho vault existed well before the chart starts — but it was then the smallest on the list, and it has grown several hundredfold since. Picking it on day one meant betting everything on the smallest vault available. It is drawn as a ceiling, to show what refusing to concentrate costs, not as a fair opponent. The even split is the fair one: it needs no knowledge of what came next.
Nothing here is financial advice. Plumb does not hold your funds, does not guarantee returns, and cannot recover losses caused by a protocol it allocates to.