Docs

Kilter keeps a portfolio of tokenized stocks on the weights you chose for it. This page is the whole mechanism: what it measures, what it decides, and exactly what goes on chain.

What Kilter is

Kilter is a static web page. It deploys no contract, runs no server, holds no tokens and has no account system. Your targets live in your own browser, keyed by your address. Every transaction goes from your wallet straight to Uniswap’s Universal Router, which was on Robinhood Chain long before this site existed.

There is no fee. Kilter adds nothing to a trade and has no contract that could. You pay the chain’s gas and the Uniswap pool fee on each leg; both are already inside the quote you are shown.

The band

A target on its own is not a rule — it does not say when. Kilter uses the 5/25 band:

tolerance = min( absolute , relative x target )
            = min(  5.00%  ,    25%    x target )

A sleeve is left alone while its weight is within that tolerance of its target, and traded when it is not. For a 60% target the absolute limit binds, so it may sit anywhere in 55–65%. For a 5% target the relative limit binds, so it may only sit in 3.75–6.25%. Both numbers are yours to change on the Targets tab, and a target of zero tolerates nothing — anything held without a target is on its way out.

Two modes: only what’s out trades just the sleeves that broke their band, which is cheaper and is the default; everything puts every sleeve back on target regardless.

How a plan is built

All of this is integer arithmetic in js/plan.js. Money is in USDG base units; a price is the pool’s own sqrtPriceX96 converted exactly, never a floating-point number.

value_i  = balance_i x price_i
total    = sum of every value, cash included
want_i   = total x target_i
delta_i  = want_i - value_i        negative: sell    positive: buy

The deltas sum to exactly zero by construction — the rounding left over by flooring each want is given to the largest one — so the sales pay for the purchases. Cash is a sleeve like any other: a cash target below your cash weight means the surplus is spent on stock, and above it means stock is sold and the dollars stay with you.

Each leg is then quoted on every pool that lists it, on both Uniswap v3 and v4, and takes whichever pays more.

What the transaction contains

One call to the Universal Router, in this order:

  1. PERMIT2_PERMIT_BATCH — redeems the single signature covering every token being sold (and USDG, if the plan spends cash).
  2. One V3_SWAP_EXACT_IN or V4_SWAP per sale, each paying out to the router, so the dollars stay inside the transaction.
  3. PERMIT2_TRANSFER_FROM — only if the plan spends cash, pulling exactly that much USDG in.
  4. One swap per purchase, each spending those same dollars and paying the stock to you.
  5. SWEEP — every USDG the purchases did not need, back to you.

Before any of it, one ordinary ERC-20 approval per token that does not already have one to Permit2. Those are the only transactions that ever precede a rebalance, and they are skipped wherever an earlier one still covers the amount.

Guards

  • The purchases can never outspend the sales. What they may spend is the sum of the sales’ minimums — never of their quotes — plus the cash you added. If that does not cover the full distance to target, the purchases are scaled down in proportion and the plan says so. A plan that broke this rule is refused before a signature is asked for, not left to revert.
  • The sweep checks the arithmetic on chain. It asks for at least the amount the plan says must still be in the router, so the transaction verifies its own bookkeeping rather than trusting this page’s.
  • Every leg carries its own minimum. If any one of them would get less, the whole transaction reverts and nothing moves.
  • Thin pools are refused. A leg whose price impact is over 3% stops the plan and names the sleeve.
  • A signature that expires. The Permit2 batch covers exactly what the plan sells, for thirty minutes, and an unused one stops working by itself.
  • Fresh minimums. After you sign, the legs are re-quoted and the minimums recomputed; the amounts spent may not change, and a plan that moved while you were in your wallet is abandoned rather than sent.

Cash

Cash means USDG in your wallet. The Cash tab can put it in Steakhouse USDG, an ERC-4626 vault on Morpho Blue, where it earns — but dollars in the vault are not counted as cash for rebalancing, because a rebalance cannot spend them without withdrawing first. Withdraw what a rebalance needs before you run it.

Addresses

Every address this site uses, and nothing else. They are in js/config.js, and each was read back on chain before it was written there.

How it is tested

The planner and the transaction builder are run against the real contracts on a fresh fork of this chain, by a brand-new random wallet that signs its own Permit2 batch and its own transactions. Three shapes of rebalance are exercised — sales funding purchases with cash on top, sales only, purchases only — with legs deliberately chosen so at least one goes through v3 and one through v4, and every assertion reads balances off the fork afterwards rather than off the planner.

The negative checks run the other way: a stranger replaying the signature, a deadline already passed, a leg asking more than its pool will pay, a permit that does not cover what is sold. Each must revert and move nothing.

Then the suite is checked against itself: fourteen deliberately broken builders are each handed to it on their own fork, and each must be caught by a named failing check, with an unmodified control passing in full. A run that does not complete is retried and then recorded inconclusive — never as a catch, because a crash is a claim about the harness and a catch is a claim about the code.

Limits

  • These are tokenized stocks on somebody else’s chain, priced by pools that can be shallow. Kilter refuses the shallow ones; it cannot make them deep.
  • Rebalancing sells what has gone up to buy what has gone down. That is the point of it, and it is not always comfortable, and it is not always right.
  • Prices are pool mid prices, not an oracle and not an exchange. They are what you could trade at here, which is the number that matters for this, and nothing more.
  • Your targets are in this browser only. Clear it and they are gone — the app can rebuild them from what you hold, or from a preset.
  • Nothing here is advice.