> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/reserve-protocol/reserve-index-dtf/llms.txt
> Use this file to discover all available pages before exploring further.

# Rebalancing Mechanism

> Learn how Folios rebalance their holdings through a structured auction process

## Overview

Folios use a semi-permissioned rebalancing mechanism to change their basket composition. The process is designed to work effectively even under timelock delays, with multiple roles coordinating to achieve optimal execution.

## Rebalance Lifecycle

Every rebalance follows a structured lifecycle:

```mermaid theme={null}
graph LR
    A[Start Rebalance] --> B[Restricted Period]
    B --> C[Open Auction]
    C --> D[Bidding]
    D --> E[Auction Ends]
    E --> F{More Auctions?}
    F -->|Yes| C
    F -->|No| G[End Rebalance]
    B --> H[Unrestricted Period]
    H --> C
```

### 1. Start Rebalance

The `REBALANCE_MANAGER` initiates a rebalance with target parameters:

```solidity theme={null}
/// @param tokens The rebalance parameters for each token
/// @param limits D18{BU/share} Target basket limits
/// @param auctionLauncherWindow {s} Time for AUCTION_LAUNCHER to act
/// @param ttl {s} Total time the rebalance is valid
function startRebalance(
    TokenRebalanceParams[] calldata tokens,
    RebalanceLimits calldata limits,
    uint256 auctionLauncherWindow,
    uint256 ttl
) external onlyRole(REBALANCE_MANAGER)
```

### 2. Auction Launcher Window (Restricted Period)

After starting, there's a restricted period where only the `AUCTION_LAUNCHER` can open auctions. This ensures they have first opportunity to provide pricing precision.

<Info>
  The restricted period automatically extends if the `AUCTION_LAUNCHER` is actively using it, with a minimum 120s buffer before unrestricted access.
</Info>

### 3. Unrestricted Period

After the restricted period expires, anyone can open auctions using spot values and initial prices. This prevents single-point-of-failure on the `AUCTION_LAUNCHER`.

### 4. Time-to-Live (TTL)

Rebalances have a TTL (max 4 weeks) that controls how long they can run. Multiple auctions can occur during this time.

<Warning>
  An auction can start at `ttl - 1` and run beyond the rebalance's TTL.
</Warning>

## Rebalance Targets

The `REBALANCE_MANAGER` configures target ranges that define the rebalancing path.

### Rebalance Limits

Define how many Basket Units the Folio should target:

```solidity theme={null}
struct RebalanceLimits {
    uint256 low;  // D18{BU/share} (0, 1e27] to buy assets up to
    uint256 spot; // D18{BU/share} (0, 1e27] point estimate for unrestricted
    uint256 high; // D18{BU/share} (0, 1e27] to sell assets down to
}
```

* **`low`** - Target for buying (minimum BU per share)
* **`spot`** - Point estimate used by unrestricted callers
* **`high`** - Target for selling (maximum BU per share)

### Basket Weights

For each token, weights define the target composition:

```solidity theme={null}
struct WeightRange {
    uint256 low;  // D27{tok/BU} [0, 1e54] lowest possible weight
    uint256 spot; // D27{tok/BU} [0, 1e54] point estimate for unrestricted
    uint256 high; // D27{tok/BU} [0, 1e54] highest possible weight
}
```

<Note>
  If `RebalanceControl.weightControl` is enabled, the `AUCTION_LAUNCHER` can progressively narrow weight ranges to maintain target allocations.
</Note>

### Price Ranges

For each token, governance provides conservative price estimates:

```solidity theme={null}
struct PriceRange {
    uint256 low;  // D27{UoA/tok} (0, 1e45]
    uint256 high; // D27{UoA/tok} (0, 1e45]
}
```

<Warning>
  Prices should be set so the asset's price on secondary markets will likely remain within range even after timelock delays. Maximum allowable range is 100x.
</Warning>

## Weight Control

When `RebalanceControl.weightControl` is enabled, the `AUCTION_LAUNCHER` can adjust basket weights within the governance-approved range.

### Use Cases

**Weight Control Enabled:**

* Folios targeting specific % breakdown at all times
* Dynamic allocation adjustments during rebalancing
* Responsive to market conditions

**Weight Control Disabled:**

* Folios with single monthly/quarterly targets
* Pure rebalance limit-based strategies
* More governance control

### Progressive Narrowing

The `AUCTION_LAUNCHER` can progressively narrow ranges but cannot backtrack:

```solidity theme={null}
// Initial range set by governance
WeightRange memory initial = WeightRange({
    low: 0.3e27,   // 30%
    spot: 0.5e27,  // 50%
    high: 0.7e27   // 70%
});

// AUCTION_LAUNCHER can narrow to:
WeightRange memory narrowed = WeightRange({
    low: 0.4e27,   // 40% (increased from 30%)
    spot: 0.5e27,  // 50% (same)
    high: 0.6e27   // 60% (decreased from 70%)
});
```

## Rebalance Completion

A rebalance is considered "completed" when all range deltas reach zero:

```solidity theme={null}
// Completed state
limits.low == limits.spot == limits.high
weights.low == weights.spot == weights.high
```

<Info>
  The `AUCTION_LAUNCHER` should end the rebalance when completion is achieved or when continuing would leak value.
</Info>

## Starting a Rebalance

<CodeGroup>
  ```solidity Full Example theme={null}
  // Define tokens in the rebalance
  TokenRebalanceParams[] memory tokens = new TokenRebalanceParams[](2);

  tokens[0] = TokenRebalanceParams({
      token: address(token1),
      weight: WeightRange({
          low: 0.4e27,   // 40% minimum
          spot: 0.5e27,  // 50% target
          high: 0.6e27   // 60% maximum
      }),
      price: PriceRange({
          low: 0.95e27,  // $0.95
          high: 1.05e27  // $1.05
      }),
      maxAuctionSize: 1000000e18, // 1M tokens per auction
      inRebalance: true
  });

  tokens[1] = TokenRebalanceParams({
      token: address(token2),
      weight: WeightRange({
          low: 0.4e27,
          spot: 0.5e27,
          high: 0.6e27
      }),
      price: PriceRange({
          low: 1.9e27,   // $1.90
          high: 2.1e27   // $2.10
      }),
      maxAuctionSize: 500000e18, // 500K tokens per auction
      inRebalance: true
  });

  // Define BU limits
  RebalanceLimits memory limits = RebalanceLimits({
      low: 0.95e18,   // Buy up to 0.95 BU per share
      spot: 1.0e18,   // 1 BU per share target
      high: 1.05e18   // Sell down to 1.05 BU per share
  });

  // Start rebalance
  folio.startRebalance(
      tokens,
      limits,
      3600,    // 1 hour auction launcher window
      604800   // 1 week TTL
  );
  ```
</CodeGroup>

## Querying Active Rebalance

Check if a rebalance is ongoing and view its parameters:

```solidity theme={null}
function getRebalance() external view returns (
    uint256 nonce,
    PriceControl priceControl,
    TokenRebalanceParams[] memory tokens,
    RebalanceLimits memory limits,
    RebalanceTimestamps memory timestamps,
    bool bidsEnabled_
)
```

<CodeGroup>
  ```solidity Example: Check Rebalance Status theme={null}
  (
      uint256 nonce,
      PriceControl priceControl,
      TokenRebalanceParams[] memory tokens,
      RebalanceLimits memory limits,
      RebalanceTimestamps memory timestamps,
      bool bidsEnabled
  ) = folio.getRebalance();

  // Check if rebalance is active
  if (block.timestamp < timestamps.availableUntil) {
      // Rebalance is ongoing
      bool isRestricted = block.timestamp < timestamps.restrictedUntil;
  }
  ```
</CodeGroup>

## Ending a Rebalance

The `REBALANCE_MANAGER`, `AUCTION_LAUNCHER`, or `DEFAULT_ADMIN_ROLE` can end a rebalance early:

```solidity theme={null}
/// End the current rebalance WITHOUT impacting any ongoing auction
function endRebalance() external
```

<Warning>
  End the rebalance if prices move outside approved ranges to prevent value leakage.
</Warning>

## Best Practices

<AccordionGroup>
  <Accordion title="Price Range Selection">
    Set price ranges wide enough to account for:

    * Timelock delay execution
    * Expected volatility
    * Block-to-block price movement
    * Slippage on secondary markets

    Avoid ranges that are too wide (approaching 100x) as this increases MEV risk.
  </Accordion>

  <Accordion title="TTL Configuration">
    Choose TTL based on:

    * Expected number of auctions needed
    * Individual auction lengths
    * Buffer for unexpected delays
    * Governance response time

    Typical range: 1-4 weeks
  </Accordion>

  <Accordion title="Auction Launcher Window">
    Set the window to:

    * Give sufficient time for AUCTION\_LAUNCHER to act
    * Account for network conditions
    * Balance between control and permissionlessness

    Typical range: 1-24 hours
  </Accordion>
</AccordionGroup>
