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

# Auction Participation

> Bid on Folio auctions to facilitate rebalancing and earn arbitrage profits

## Overview

Folio auctions use a Dutch auction mechanism where prices move from optimistic to pessimistic over time. All token pairs trade simultaneously, and bidders can participate by:

1. **Direct bidding** - Swap tokens at the current auction price
2. **Callback bidding** - Execute custom logic before transferring tokens
3. **Trusted fills** - Use aggregators like CowSwap for complex routing

<Info>
  Auctions have a 30-second warmup period to ensure fair competition. This is skipped for atomic swaps where start price equals end price.
</Info>

## Understanding Auction Mechanics

### Surplus and Deficit

Auctions only allow trading between:

* **Surplus tokens**: Tokens above the high basket limit
* **Deficit tokens**: Tokens below the low basket limit

```solidity theme={null}
// Example: Check if a pair is tradeable
(uint256 sellAmount, uint256 bidAmount, uint256 price) = folio.getBid(
    auctionId,
    IERC20(weth),  // Must be in surplus
    IERC20(usdc),  // Must be in deficit
    type(uint256).max
);

if (sellAmount == 0) {
    // No surplus/deficit for this pair
}
```

### Price Discovery

Prices follow an exponential decay curve:

* **Start**: Most optimistic prices (favorable to Folio)
* **End**: Most pessimistic prices (favorable to bidders)
* **Current**: Interpolated based on time elapsed

## Direct Bidding

The simplest way to participate in auctions.

<Steps>
  <Step title="Query Available Bids">
    Find profitable opportunities:

    ```solidity theme={null}
    // Get current bid for selling WETH to buy USDC
    (uint256 sellAmount, uint256 bidAmount, uint256 price) = folio.getBid(
        auctionId,
        IERC20(weth),    // Sell token
        IERC20(usdc),    // Buy token
        10e18            // Max WETH you want to receive
    );

    // Price is in D27 format: {buyToken/sellToken}
    // Example: price = 2300e27 means 1 WETH = 2300 USDC
    ```

    <Tip>
      Compare the auction price against external markets (Uniswap, etc.) to identify arbitrage opportunities.
    </Tip>
  </Step>

  <Step title="Approve Tokens">
    The Folio needs allowance to pull buy tokens from you:

    ```solidity theme={null}
    IERC20(usdc).approve(address(folio), bidAmount);
    ```
  </Step>

  <Step title="Execute Bid">
    Submit your bid:

    ```solidity theme={null}
    uint256 actualBidAmount = folio.bid(
        auctionId,
        IERC20(weth),      // Sell token (you receive)
        IERC20(usdc),      // Buy token (you pay)
        sellAmount,        // Exact amount of WETH you want
        bidAmount,         // Max USDC you're willing to pay
        false,             // withCallback = false for direct bid
        ""                 // No callback data needed
    );

    // You now have 'sellAmount' of WETH
    // Folio took 'actualBidAmount' of USDC from you
    ```

    <Check>
      After the bid:

      * Your WETH balance increases by `sellAmount`
      * Your USDC balance decreases by `actualBidAmount`
      * `actualBidAmount` should be ≤ `bidAmount` (your max)
    </Check>
  </Step>

  <Step title="Arbitrage on External Markets">
    Immediately trade your received tokens for profit:

    ```solidity theme={null}
    // Example: Sell WETH on Uniswap for more USDC
    ISwapRouter(uniswapRouter).exactInputSingle(
        ISwapRouter.ExactInputSingleParams({
            tokenIn: address(weth),
            tokenOut: address(usdc),
            fee: 3000,
            recipient: msg.sender,
            deadline: block.timestamp,
            amountIn: sellAmount,
            amountOutMinimum: bidAmount + minProfit,
            sqrtPriceLimitX96: 0
        })
    );
    ```
  </Step>
</Steps>

## Callback Bidding

For advanced strategies, use callbacks to execute custom logic within the bid transaction.

<Steps>
  <Step title="Implement IBidderCallee Interface">
    Your contract must implement the callback interface:

    ```solidity theme={null}
    import { IBidderCallee } from "@interfaces/IBidderCallee.sol";

    contract MyArbitrageur is IBidderCallee {
        function bidderCallback(
            IERC20 sellToken,
            IERC20 buyToken,
            uint256 sellAmount,
            uint256 buyAmount,
            bytes calldata data
        ) external override {
            // 1. Receive sellToken from Folio
            // 2. Execute your strategy (e.g., swap on DEX)
            // 3. Transfer buyToken back to Folio

            // Example: Flash arbitrage
            // Sell received sellToken on Uniswap
            _swapOnUniswap(sellToken, buyToken, sellAmount);

            // Transfer buyAmount back to Folio
            buyToken.transfer(msg.sender, buyAmount);
        }
    }
    ```
  </Step>

  <Step title="Call Bid with Callback">
    ```solidity theme={null}
    bytes memory strategyData = abi.encode(
        uniswapPoolAddress,
        minProfitThreshold
    );

    folio.bid(
        auctionId,
        IERC20(weth),
        IERC20(usdc),
        sellAmount,
        bidAmount,
        true,          // withCallback = true
        strategyData   // Passed to your callback
    );
    ```

    **Callback Flow:**

    1. Folio transfers `sellAmount` of sell token to you
    2. Folio calls `bidderCallback()` on your contract
    3. Your callback executes and transfers `buyAmount` to Folio
    4. Folio verifies it received the tokens
  </Step>
</Steps>

<Warning>
  **Security Considerations:**

  * Always validate `msg.sender` is the Folio in your callback
  * Set slippage limits to protect against sandwich attacks
  * Ensure callback execution is atomic (reverts return everything)
</Warning>

## Trusted Filler Integration

Trusted fillers enable async execution using specialized solvers like CowSwap.

<Steps>
  <Step title="Create Trusted Fill">
    Instead of bidding directly, create a trusted fill order:

    ```solidity theme={null}
    IBaseTrustedFiller filler = folio.createTrustedFill(
        auctionId,
        IERC20(weth),        // Sell token
        IERC20(usdc),        // Buy token
        cowSwapFillerAddr,   // Target filler (e.g., CowSwapFiller)
        keccak256(abi.encode(msg.sender, block.timestamp)) // Unique salt
    );

    // Folio has approved the filler to spend sellToken
    // Filler now has entire block to execute the swap
    ```

    <Info>
      The Folio will automatically close and claim tokens from the trusted filler at the next state-changing call.
    </Info>
  </Step>

  <Step title="Execute Fill (Solver Side)">
    The trusted filler contract handles the actual swap:

    ```solidity theme={null}
    // CowSwap example: Create order on CoW Protocol
    GPv2Order.Data memory order = GPv2Order.Data({
        sellToken: weth,
        buyToken: usdc,
        sellAmount: sellAmount,
        buyAmount: buyAmount,
        // ... other CowSwap parameters
    });

    // Submit to CowSwap for async settlement
    cowSettlement.settle(orders, ...);
    ```
  </Step>

  <Step title="Monitor Fill Status">
    Check if the async swap is still active:

    ```solidity theme={null}
    (bool syncActive, bool asyncActive) = folio.stateChangeActive();

    if (asyncActive) {
        // Trusted fill is still executing
        // Wait before performing state-dependent operations
    }
    ```
  </Step>
</Steps>

## Bidding Requirements

<AccordionGroup>
  <Accordion title="Permissionless Bids Enabled">
    If `bidsEnabled` is `true` for the rebalance, anyone can bid on auctions.

    ```solidity theme={null}
    (, , , , , bool bidsEnabled) = folio.getRebalance();
    require(bidsEnabled, "Permissionless bids disabled");
    ```
  </Accordion>

  <Accordion title="Deprecation Status">
    Bids cannot be placed on deprecated Folios:

    ```solidity theme={null}
    require(!folio.isDeprecated(), "Folio deprecated");
    ```
  </Accordion>

  <Accordion title="Auction Timing">
    Bids are only valid during the auction's active period:

    * After warmup period (30 seconds, or 0 for atomic swaps)
    * Before end time

    ```solidity theme={null}
    // getBid() will revert if auction is not ongoing
    (uint256 sellAmt, , ) = folio.getBid(...);
    require(sellAmt > 0, "No surplus/deficit");
    ```
  </Accordion>

  <Accordion title="Token Pairs">
    You can only trade pairs where:

    * Sell token is in surplus (above high limit)
    * Buy token is in deficit (below low limit)

    Not all tokens in an auction can be traded together at all times.
  </Accordion>
</AccordionGroup>

## Advanced Strategies

### Multi-Hop Arbitrage

Bid on multiple pairs in sequence:

```solidity theme={null}
// 1. Get WETH from Folio auction (pay USDC)
folio.bid(auctionId, IERC20(weth), IERC20(usdc), ...);

// 2. Trade WETH for DAI on Uniswap
uniswapRouter.swap(weth, dai, ...);

// 3. Get more USDC from Folio auction (pay DAI)
folio.bid(auctionId, IERC20(usdc), IERC20(dai), ...);

// Net: Started with X USDC, ended with X + profit USDC
```

### Flash Loan Arbitrage

Use flash loans to amplify profits:

```solidity theme={null}
function executeFlashArbitrage() external {
    // 1. Flash borrow USDC from Aave
    aaveLendingPool.flashLoan(
        address(this),
        [address(usdc)],
        [borrowAmount],
        ...
    );
}

function executeOperation(
    address[] calldata assets,
    uint256[] calldata amounts,
    uint256[] calldata premiums,
    ...
) external override returns (bool) {
    // 2. Bid on Folio auction
    folio.bid(..., IERC20(weth), IERC20(usdc), ...);

    // 3. Sell WETH on external market
    _swapWETHForUSDC(...);

    // 4. Repay flash loan + premium
    IERC20(usdc).approve(address(aaveLendingPool), amounts[0] + premiums[0]);

    return true;
}
```

## Monitoring Events

Listen to auction events for opportunities:

```solidity theme={null}
event AuctionOpened(
    uint256 indexed rebalanceNonce,
    uint256 indexed auctionId,
    address[] tokens,
    WeightRange[] weights,
    PriceRange[] prices,
    RebalanceLimits limits,
    uint256 startTime,
    uint256 endTime
);

event AuctionBid(
    uint256 indexed auctionId,
    address indexed sellToken,
    address indexed buyToken,
    uint256 sellAmount,
    uint256 buyAmount
);
```

## Code Reference

* Bid execution: `contracts/Folio.sol:794-813`
* Get bid parameters: `contracts/Folio.sol:776-783`
* Trusted fill creation: `contracts/Folio.sol:816-847`
* Bid callback interface: `contracts/interfaces/IBidderCallee.sol`

## Next Steps

<CardGroup cols={2}>
  <Card title="Managing Rebalances" icon="scale-balanced" href="/guides/managing-rebalances">
    Learn how to start and configure rebalances
  </Card>

  <Card title="Minting & Redeeming" icon="coins" href="/guides/minting-redeeming">
    Understand how to mint and redeem Folio shares
  </Card>
</CardGroup>
