How a rebalance works
A rebalance replaces your position with a new one in the same pool in one transaction. It reuses the old position’s funds, including earned fees, and you can add funds from your wallet. The new position keeps the owner and withdrawal address and has a new ID. A rebalance does not swap one asset for the other. If the new range needs a different mix, you can add the asset it needs; anything the new position does not use returns to the withdrawal address. Check those amounts in the review before confirming. The reviewed amounts must still match when the transaction executes; there is no slippage setting. If pool activity makes the preview out of date, the rebalance can be rejected. Your old position stays unchanged, though a rejected transaction can still cost a network fee. Refresh the review before trying again.In the app
Before you startYou’ll need: Shield Wallet connected to Shield Swap, and an open position with liquidity in it.Move a position to a new range
- Open Pools, then select the pool. Under Your Positions, select Manage in the position’s row, then Rebalance. The panel on the right switches to Rebalance with Position loaded showing the position’s ID and its current range.
- Select Custom. Choose a preset, drag the handles on the chart, or enter prices in Min and Max. See Choosing a liquidity range for what each preset does.
- Check the two amounts. Each shows how much comes from the current position. Raise an amount to add funds from your wallet at the same time.
- Select Review Rebalance.
- In Review Rebalance, check the New position amounts, the Price range line showing the old and new ranges, and Returns to your wallet, the amount that does not fit the new range. Open Details to see the position funds recovered and the new position’s amounts side by side.
- Select Confirm.
- In the Transaction request in Shield Wallet, check that the request is from swap.shield.fi, then select Confirm.
Troubleshooting
See the trades your position filled
The app does not show per-trade fills for a position. Recent Activity on the pool page lists your position actions, and Your Trades on the Trade page lists your own swaps. Fee earnings appear as Position Funds on the position’s row. Per-trade fill tracking is available through the TypeScript SDK; see the Developers view of this page.Next steps
- Choosing a liquidity range for what each preset does.
- Increasing liquidity to add funds without changing the range.
Plan and submit a rebalance
Prerequisites: Your authenticated mainnetclient for TypeScript or dex for Python from Setup, and an existing position with liquidity. The CLI has no rebalance command.Build the plan immediately before submission and submit it unchanged. The contract checks the amounts at execution, so pool activity can invalidate a plan. These examples recenter the range on the current tick, one spacing below and two above, funded only from what the old position returns.Replace POSITION_TOKEN_ID with the ID of the position you intend to change. Define the confirmation helper for your SDK before running these examples.- TypeScript
- Python
- CLI
Step 1: Read the position and the pool
Step 2: Plan
maxFunding0: 0n, maxFunding1: 0n means reuse only what the old position returns. The planner recovers the principal at the current price plus all fees, including those not yet checkpointed, and sizes the new position from that alone. Nothing is spent.maxFunding0 and maxFunding1 budgets to add funds from your records, or liquidityTarget for an exact size.Step 3: Submit the plan
Track the fills a position takes
A position fill is the change in the two asset amounts backing a position’s liquidity between two consecutive pool prices. Each swap that moves the pool’s price through the position’s range changes that inventory, and the sequence of those changes is the position’s fill history. Fills describe inventory, not fees; fee earnings are separate.The TypeScript examplelp-fill-tracker.ts replays pool trades against a position’s current range and liquidity, then follows live trades. It reads the position on chain, takes prices from REST trade history, uses Aleo blocks to order swaps and route legs, and listens for WebSocket messages to backfill new trades. It reads up to 20 swaps on start; the first establishes a starting price, leaving up to 19 inventory changes to report.Historical replay holds the current range and liquidity fixed. It can include swaps from before the position was minted and does not reconstruct earlier increases or decreases. Treat it as an inventory calculation for that configuration, not a record of fills the position actually received. Live tracking stops if the position’s range or liquidity changes.Run it from a Veil checkout with Node.js 22 or later and pnpm:YOUR_PRIVATE_KEY with the account’s private key and POSITION_TOKEN_ID with the position’s token ID from getOwnedPositions. Mainnet is the default; pass --network testnet to track a testnet position. Each fill it prints carries the trade and transaction IDs, the block and leg order, the position’s liquidity and range, the pool’s tick and square-root price before and after, the swap direction, and the position’s token0 and token1 amounts before and after.The example exports calculatePositionFill, which values a position’s liquidity and range at two prices without reading the network, and trackLiquidityPosition, which runs the full tracker. Import either into your own application. See the fill tracker source for the options it accepts.The Python SDK has no fill tracker.How it works on chain
A rebalance runs throughshield_swap_rebalance_router.aleo and replaces your position in one transaction. It reuses the old position’s principal and fees, adds any planned funding, and pays out the surplus. No swap takes place.What changes
How the position is replaced
- The contract removes all old liquidity and settles pending fees. Recovered funds include the principal, newly settled fees, and any balance already owed.
- It checks the recovered amounts against the plan and closes the old position.
- It mints the successor using the recovered funds plus any planned funding.
- It pays any surplus to the withdrawal address. For each token, recovered funds plus funding must equal the amount used plus the refund.
When the plan no longer matches
Execution checks the recovered amounts and the amounts required for the planned successor liquidity. There is no slippage tolerance: if either token’s recovered or required amount differs from the plan, the transaction is rejected. It must also execute by the plan’s block-height deadline.If rejected, the old position stays unchanged. Check the rejection details and build a fresh plan before retrying. After acceptance, save the successor’s ID and record for later operations.Position accounting, both ranges, and the amounts are public; ownership and the withdrawal address are confidential. See Public data.Next steps
- Choosing a liquidity range for how to pick the new range.
- LP workflow for the full lifecycle and the client state to keep.
- Market maker operations for rebalancing at desk scale.
- The TypeScript rebalance example is the runnable version of the steps above.