> ## 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.

# Price Control Modes

> Configure AUCTION_LAUNCHER control over auction pricing with NONE, PARTIAL, and ATOMIC_SWAP modes

## Overview

Price control determines how much authority the `AUCTION_LAUNCHER` has over auction pricing within the bounds set by the `REBALANCE_MANAGER`. The three modes provide different tradeoffs between decentralization, execution quality, and MEV risk.

## Price Control Modes

```solidity theme={null}
enum PriceControl {
    NONE,         // Cannot change prices
    PARTIAL,      // Can set auction prices within bounds
    ATOMIC_SWAP   // PARTIAL + ability to set startPrice = endPrice
}
```

## NONE: Governance-Only Pricing

### Behavior

* `AUCTION_LAUNCHER` **cannot** modify price ranges
* All auctions use the initial price ranges set by `REBALANCE_MANAGER`
* Auction length is fixed to `maxAuctionLength`
* Most decentralized but least flexible

### Configuration

```solidity theme={null}
RebalanceControl memory control = RebalanceControl({
    weightControl: false,
    priceControl: PriceControl.NONE
});

folio.setRebalanceControl(control);
```

### Use Case

Ideal for Folios that:

* Prioritize maximum decentralization
* Can tolerate wider price ranges set via governance
* Have long timelock delays where precision matters less
* Rebalance infrequently (e.g., quarterly)

### Example: Opening Auction with NONE

```solidity theme={null}
// REBALANCE_MANAGER sets wide price ranges
PriceRange[] memory prices = new PriceRange[](2);
prices[0] = PriceRange(0.99e27, 1.01e27);  // USDC: 1% range
prices[1] = PriceRange(2900e27, 3100e27);  // WETH: ~7% range

rebalanceManager.startRebalance(tokens, limits, 3 days, 7 days);

// AUCTION_LAUNCHER must use exact prices from rebalance
// auctionLength must equal maxAuctionLength
auctionLauncher.openAuction(
    rebalanceNonce,
    tokens,
    newWeights,
    prices,  // Must match initial prices exactly
    newLimits,
    maxAuctionLength  // Fixed length
);
```

<Warning>
  With `PriceControl.NONE`, the `AUCTION_LAUNCHER` cannot adapt to market movements. If prices move outside the governance-approved range, value leakage to MEV searchers is possible. The `AUCTION_LAUNCHER` should monitor markets and end the rebalance if necessary.
</Warning>

## PARTIAL: Subset Price Control

### Behavior

* `AUCTION_LAUNCHER` can narrow price ranges within initial bounds
* Cannot expand ranges beyond what governance approved
* Can set auction length between `MIN_AUCTION_LENGTH` and `maxAuctionLength`
* Enables better execution but introduces MEV risk

### Configuration

```solidity theme={null}
RebalanceControl memory control = RebalanceControl({
    weightControl: true,   // Often paired with weight control
    priceControl: PriceControl.PARTIAL
});

folio.setRebalanceControl(control);
```

### Use Case

Ideal for Folios that:

* Want to balance decentralization and execution quality
* Have a semi-trusted `AUCTION_LAUNCHER` (multisig)
* Need to adapt to market conditions within approved bounds
* Prioritize better pricing over absolute trustlessness

### Example: Narrowing Price Ranges

```solidity theme={null}
// REBALANCE_MANAGER sets outer bounds
PriceRange memory usdcPrice = PriceRange(0.98e27, 1.02e27);  // 4% range

// AUCTION_LAUNCHER can narrow to improve execution
PriceRange memory narrowedPrice = PriceRange(0.995e27, 1.005e27);  // 1% range

// But cannot expand:
PriceRange memory invalid = PriceRange(0.97e27, 1.03e27);  // ❌ Reverts
```

### Calculating Start and End Prices

For a token pair, auction prices are calculated from individual token ranges:

```solidity theme={null}
// D27{buyTok/sellTok}
// startPrice = most optimistic (highest sell value / lowest buy value)
// endPrice = most pessimistic (lowest sell value / highest buy value)

startPrice = (sellToken.high * D27) / buyToken.low;
endPrice = (sellToken.low * D27) / buyToken.high;
```

### MEV Risk

<Warning>
  With `PARTIAL` control, a dishonest `AUCTION_LAUNCHER` can:

  * Set auction start prices that leak value to MEV searchers
  * Cause immediate value extraction when auctions begin
  * **Cannot guarantee they receive the leaked value** (goes to MEV bots)

  The `AUCTION_LAUNCHER` should act in good faith and price auctions to clear near the efficient market price.
</Warning>

## ATOMIC\_SWAP: Full Price Control

### Behavior

* All capabilities of `PARTIAL` mode
* **Additionally** can set `startPrice == endPrice` (flat price)
* Enables atomic swaps without the 30-second warmup period
* Allows `AUCTION_LAUNCHER` to internalize MEV

### Configuration

```solidity theme={null}
RebalanceControl memory control = RebalanceControl({
    weightControl: true,
    priceControl: PriceControl.ATOMIC_SWAP
});

folio.setRebalanceControl(control);
```

### Use Case

Ideal for Folios that:

* Fully trust the `AUCTION_LAUNCHER` to execute at fair prices
* Want to eliminate MEV leakage entirely
* Can verify fair execution through other means (e.g., bundle inspection)
* Prioritize execution quality above all else

### Example: Atomic Swap Execution

```solidity theme={null}
// Set fixed price (no price curve)
PriceRange memory fixedPrice = PriceRange(1.0e27, 1.0e27);

// Open auction with atomic swap
folio.openAuction(
    rebalanceNonce,
    tokens,
    newWeights,
    [fixedPrice, fixedPrice],  // startPrice == endPrice
    newLimits,
    0  // Can use very short auction length
);

// Fill immediately in same transaction
folio.bid(
    auctionId,
    sellToken,
    buyToken,
    sellAmount,
    maxBuyAmount,
    true,   // Use callback
    data
);

// End rebalance to prevent further exploitation
folio.endRebalance();
```

### Best Practices for ATOMIC\_SWAP

<Warning>
  When using `ATOMIC_SWAP`, the `AUCTION_LAUNCHER` **MUST**:

  1. Fill the auction atomically in the same transaction as opening it
  2. End the rebalance immediately after all fills complete
  3. Execute as a bundle to prevent frontrunning

  Failure to follow this pattern allows the `AUCTION_LAUNCHER` to extract value AND benefit from it directly.
</Warning>

## Choosing a Price Control Mode

| Mode             | Decentralization | Execution Quality | MEV Risk | Best For                                 |
| ---------------- | ---------------- | ----------------- | -------- | ---------------------------------------- |
| **NONE**         | Highest          | Lowest            | Low      | Infrequent rebalances, long timelocks    |
| **PARTIAL**      | Medium           | Medium            | Medium   | Balanced approach, semi-trusted launcher |
| **ATOMIC\_SWAP** | Lowest           | Highest           | High\*   | Fully trusted launcher, MEV elimination  |

\*Risk is high if misused, but can be mitigated with proper execution

## Validation Rules

### NONE Mode

```solidity theme={null}
// Auction length must equal maxAuctionLength
require(auctionLength == maxAuctionLength, "Invalid length");

// Prices must match initial ranges exactly
require(
    newPrices[i].low == rebalance.details[token].initialPrices.low &&
    newPrices[i].high == rebalance.details[token].initialPrices.high,
    "Prices must match"
);
```

### PARTIAL Mode

```solidity theme={null}
// Auction length has flexibility
require(
    auctionLength >= MIN_AUCTION_LENGTH &&
    auctionLength <= maxAuctionLength,
    "Invalid length"
);

// Prices must be within initial bounds
require(
    newPrices[i].low >= rebalance.details[token].initialPrices.low &&
    newPrices[i].high <= rebalance.details[token].initialPrices.high,
    "Price out of bounds"
);

// startPrice cannot equal endPrice
require(startPrice != endPrice, "Use ATOMIC_SWAP for fixed prices");
```

### ATOMIC\_SWAP Mode

```solidity theme={null}
// All PARTIAL validations apply
// Plus: startPrice CAN equal endPrice
if (startPrice == endPrice) {
    // Warmup period bypassed for atomic execution
}
```

## RebalanceControl Structure

```solidity theme={null}
struct RebalanceControl {
    bool weightControl;           // If AUCTION_LAUNCHER can adjust weights
    PriceControl priceControl;   // Price control mode
}
```

The `weightControl` flag is independent and can be combined with any price control mode. See [Basket Weights](/advanced/basket-weights) for details.

## Governance Considerations

* Price control mode cannot be changed during an active rebalance
* Set via `setRebalanceControl()` which requires `DEFAULT_ADMIN_ROLE`
* Should align with the trust level of your `AUCTION_LAUNCHER`
* Can be different for different Folios in the same ecosystem

## Related

* [Basket Weight Ranges](/advanced/basket-weights)
* [Trusted Fillers](/advanced/trusted-fillers)
* [Security Considerations](/advanced/security)
