Matador Docs
DeFi Automation

Recipe - Uniswap Delta Rebalance

A policy to keep a Uniswap V3 position delta-neutral.

Recipe: Uniswap Delta Rebalance

This policy allows a Keeper to rebalance a Uniswap V3 position to maintain Delta Neutrality, but prevents them from draining funds or executing bad trades.

The Strategy

Trigger: Price moves, causing the position's ratio of Asset A / Asset B to drift.

Action: Swap the excess asset for the deficit asset.

Safety: Ensure the swap recipient is the vault itself, and slippage is bounded.

Slippage controls are mandatory

Keeper Rails require explicit bounds. Always set sqrtPriceLimitX96 to prevent unbounded price impact.

The Policy

import "abis/UniswapV3Router.json" as Uniswap;

permission UniDeltaRebalance -> 1.0.0 {
    metadata: {
        description: "Restricts Uniswap V3 swaps to safe parameters",
        author: "Protocol DAO"
    }

    parameters: {
        router: address,
        tokenA: address,
        tokenB: address
    }

    when: {
        // 1. Target Guard: Only allow calls to Router
        context.target == parameters.router,

        // 2. Function Guard: Only allow 'exactInputSingle'
        Uniswap.exactInputSingle(params: tuple),

        // 3. Argument Guards
        // Recipient must be SELF (the account)
        calldata.params.recipient == context.account,

        // Target pool must be authorized one (Token A -> B or B -> A)
        any {
            all {
                calldata.params.tokenIn == parameters.tokenA,
                calldata.params.tokenOut == parameters.tokenB
            },
            all {
                calldata.params.tokenIn == parameters.tokenB,
                calldata.params.tokenOut == parameters.tokenA
            }
        },

        // Economic: SqrtPriceLimitX96 must be set (non-zero) to protect against infinite slippage
        calldata.params.sqrtPriceLimitX96 != 0
    }
}

How it Protects You

Attack VectorRail Defense
TheftThe Keeper tries to set recipient to their own wallet. Blocked by recipient == context.account.
Bad RoutingThe Keeper tries to route through a low-liquidity pool to manipulate price. Blocked by token pair checks.
SandwichingThe Keeper submits a swap with 0 slippage protection. Blocked by requiring sqrtPriceLimit.

Integration Steps

  1. Compile: Run matador compile uni-rebalance.matador.
  2. Deploy: Upload the bytecode to your Safe/Kernel.
  3. Authorize: Add your Keeper bot address as a permissioned caller for this policy.

On this page