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

# Minting and Redeeming

> Learn how to mint new Folio shares and redeem them for underlying assets

## Overview

Folios support permissionless minting and redemption:

* **Minting**: Deposit basket assets to receive Folio shares
* **Redeeming**: Burn Folio shares to receive basket assets

Both operations are proportional to the current basket composition and include fee mechanisms.

<Info>
  Minting and redemption are disabled if the Folio is deprecated. Use `folio.isDeprecated()` to check status.
</Info>

## Understanding Share Accounting

### Total Supply

The total supply includes:

1. Circulating shares (held by users)
2. Pending DAO fee shares (not yet distributed)
3. Pending fee recipient shares (not yet distributed)

```solidity theme={null}
uint256 totalShares = folio.totalSupply();
// Includes all pending fees
```

### Asset Composition

Shares represent proportional ownership of all basket assets:

```solidity theme={null}
(address[] memory assets, uint256[] memory amounts) = folio.totalAssets();

// Example output:
// assets = [USDC, WETH, DAI]
// amounts = [1,000,000e6, 100e18, 500,000e18]
```

<Warning>
  Asset composition may be unreliable during trusted fill execution. Check `folio.stateChangeActive()` before relying on asset data.
</Warning>

## Minting Shares

Minting requires depositing all basket assets proportionally.

<Steps>
  <Step title="Query Required Assets">
    Calculate how many tokens you need for a desired share amount:

    ```solidity theme={null}
    uint256 desiredShares = 100e18; // Want 100 shares

    (address[] memory assets, uint256[] memory amounts) = folio.toAssets(
        desiredShares,
        Math.Rounding.Ceil // Round up to ensure sufficient amounts
    );

    // amounts = [USDC: 1000e6, WETH: 1e18, DAI: 1000e18]
    ```

    <Tip>
      Always use `Math.Rounding.Ceil` when calculating required deposits to avoid "insufficient amount" errors.
    </Tip>
  </Step>

  <Step title="Calculate Fees">
    Understand the fee structure:

    ```solidity theme={null}
    uint256 mintFee = folio.mintFee(); // e.g., 0.01e18 = 1%

    // Shares received = desiredShares * (1 - mintFee) * (1 - daoSplit)
    // Remaining goes to: DAO fee recipient + Folio fee recipients
    ```

    **Fee Distribution:**

    * DAO takes minimum 15bps from all fees
    * Remaining goes to fee recipients (if configured)
    * If no fee recipients, DAO gets everything
  </Step>

  <Step title="Approve Token Transfers">
    Grant allowances for all basket assets:

    ```solidity theme={null}
    for (uint256 i = 0; i < assets.length; i++) {
        IERC20(assets[i]).approve(address(folio), amounts[i]);
    }
    ```

    <Note>
      You can also use permit() for gasless approvals if tokens support ERC-2612.
    </Note>
  </Step>

  <Step title="Execute Mint">
    ```solidity theme={null}
    uint256 minSharesOut = 99e18; // Minimum shares after fees (slippage protection)

    (address[] memory returnedAssets, uint256[] memory returnedAmounts) = folio.mint(
        desiredShares,
        msg.sender,      // Recipient of shares
        minSharesOut     // Revert if you receive less than this
    );

    // You now have shares in your wallet
    uint256 yourBalance = folio.balanceOf(msg.sender);
    ```

    <Check>
      After minting:

      * Your share balance increased
      * Your token balances decreased by `returnedAmounts`
      * Pending fee shares increased (distributed later)
    </Check>
  </Step>

  <Step title="Set Slippage Protection (Optional)">
    Use allowances to limit token spend in case of state changes:

    ```solidity theme={null}
    // Instead of approving exact amounts, approve maximum acceptable amounts
    uint256 maxUSDC = amounts[0] * 1.01e18 / 1e18; // 1% slippage
    IERC20(usdc).approve(address(folio), maxUSDC);
    ```
  </Step>
</Steps>

## Redeeming Shares

Redemption burns shares and returns proportional assets.

<Steps>
  <Step title="Calculate Redemption Output">
    ```solidity theme={null}
    uint256 sharesToRedeem = 50e18; // Redeem 50 shares

    (address[] memory assets, uint256[] memory amounts) = folio.toAssets(
        sharesToRedeem,
        Math.Rounding.Floor // Round down (you receive slightly less)
    );

    // amounts = [USDC: 500e6, WETH: 0.5e18, DAI: 500e18]
    ```
  </Step>

  <Step title="Set Minimum Amounts">
    Protect against unfavorable state changes:

    ```solidity theme={null}
    // Set minimum acceptable amounts (99% of expected)
    uint256[] memory minAmountsOut = new uint256[](assets.length);
    for (uint256 i = 0; i < assets.length; i++) {
        minAmountsOut[i] = amounts[i] * 99 / 100;
    }
    ```
  </Step>

  <Step title="Execute Redemption">
    ```solidity theme={null}
    uint256[] memory actualAmounts = folio.redeem(
        sharesToRedeem,
        msg.sender,      // Recipient of assets
        assets,          // Must match basket exactly
        minAmountsOut    // Minimum amounts to receive
    );

    // You now have assets in your wallet
    // Shares were burned from your balance
    ```

    <Warning>
      The `assets` parameter must match the current basket exactly (same order, same tokens). Otherwise, the transaction will revert.
    </Warning>
  </Step>
</Steps>

## Fee Distribution

Fees accumulate as pending shares and are distributed separately.

### Manual Distribution

```solidity theme={null}
// Anyone can call this to distribute accumulated fees
folio.distributeFees();
```

This will:

1. Calculate all pending fee shares from TVL fees and mint fees
2. Mint shares to fee recipients according to their portions
3. Mint remaining shares to DAO fee recipient
4. Reset pending fee counters

### Automatic Distribution

Fees are automatically distributed (via `poke()`) before:

* Minting
* Redemption
* Fee configuration changes
* Any state-changing operation

```solidity theme={null}
// Happens automatically, but can be called directly:
folio.poke();
```

<Info>
  The `poke()` function updates pending fees based on time elapsed since the last update (in full days only).
</Info>

## Fee Types

### TVL Fee (Time-Based)

**Annual demurrage fee on assets under management**

```solidity theme={null}
uint256 tvlFee = folio.tvlFee(); // D18{1/s} fee per second

// Convert to annual percentage:
// annualFee = tvlFee * 365 days / 1e18
// Example: 317097919837645 per second ≈ 1% annual
```

**Calculation:**

* Accrues every full day (24-hour periods)
* Causes supply inflation (new shares minted to fee recipients)
* Max 10% annually

### Mint Fee (One-Time)

**Percentage fee charged on minting**

```solidity theme={null}
uint256 mintFee = folio.mintFee(); // D18{1} e.g., 0.01e18 = 1%

// On a 100 share mint with 1% fee:
// - User receives: ~99 shares
// - Fees: ~1 share (split between DAO and fee recipients)
```

**Characteristics:**

* One-time charge when minting
* Does NOT cause supply inflation (taken from minted shares)
* Max 5%

### Folio Self Fee

**Fraction of fee-recipient shares that are burned**

```solidity theme={null}
uint256 folioFeeForSelf = folio.folioFeeForSelf(); // D18{1}

// Example: 0.1e18 = 10%
// Of the fee recipient shares, 10% are burned instead of minted
```

This creates deflationary pressure on supply.

## Advanced Minting Strategies

### Batch Minting for Multiple Users

```solidity theme={null}
contract BatchMinter {
    function mintForUsers(
        Folio folio,
        address[] memory recipients,
        uint256[] memory shares
    ) external {
        for (uint256 i = 0; i < recipients.length; i++) {
            // Calculate required assets
            (address[] memory assets, uint256[] memory amounts) = folio.toAssets(
                shares[i],
                Math.Rounding.Ceil
            );

            // Transfer assets from users to this contract
            for (uint256 j = 0; j < assets.length; j++) {
                IERC20(assets[j]).transferFrom(recipients[i], address(this), amounts[j]);
                IERC20(assets[j]).approve(address(folio), amounts[j]);
            }

            // Mint to recipient
            folio.mint(shares[i], recipients[i], shares[i] * 99 / 100);
        }
    }
}
```

### Mint with Single Asset

Use a DEX aggregator to convert a single asset into the basket:

```solidity theme={null}
function mintWithSingleAsset(
    Folio folio,
    IERC20 inputToken,
    uint256 inputAmount,
    uint256 desiredShares
) external {
    // 1. Calculate required basket assets
    (address[] memory assets, uint256[] memory amounts) = folio.toAssets(
        desiredShares,
        Math.Rounding.Ceil
    );

    // 2. Swap input token for each basket asset
    for (uint256 i = 0; i < assets.length; i++) {
        if (address(inputToken) != assets[i]) {
            // Swap on Uniswap/1inch/etc.
            _swapExactOutput(inputToken, IERC20(assets[i]), amounts[i]);
        }
    }

    // 3. Approve and mint
    for (uint256 i = 0; i < assets.length; i++) {
        IERC20(assets[i]).approve(address(folio), amounts[i]);
    }

    folio.mint(desiredShares, msg.sender, desiredShares * 99 / 100);
}
```

## Handling Edge Cases

<AccordionGroup>
  <Accordion title="Rebalancing in Progress">
    During rebalances, the basket composition may change:

    ```solidity theme={null}
    // Check if a rebalance is active
    (, , , , IFolio.RebalanceTimestamps memory timestamps, ) = folio.getRebalance();

    if (block.timestamp < timestamps.availableUntil) {
        // Rebalance active - basket may change
        // Consider waiting or using larger slippage
    }
    ```
  </Accordion>

  <Accordion title="Folio Deprecation">
    Deprecated Folios can only be redeemed:

    ```solidity theme={null}
    if (folio.isDeprecated()) {
        // Minting is disabled
        // Auctions are disabled
        // Only redemption is available
        folio.redeem(...);
    }
    ```
  </Accordion>

  <Accordion title="Zero Balance Assets">
    Basket tokens with zero balance are still part of the basket:

    ```solidity theme={null}
    (address[] memory assets, uint256[] memory amounts) = folio.totalAssets();

    // Some amounts[i] may be 0
    // Still required to approve these tokens for minting
    // But actual transfer amount will be 0
    ```
  </Accordion>

  <Accordion title="Fee Accrual Timing">
    TVL fees accrue in full days only:

    ```solidity theme={null}
    uint256 lastPoke = folio.lastPoke();
    uint256 nextAccrual = ((lastPoke / 1 days) + 1) * 1 days;

    // Fees will next accrue at nextAccrual timestamp
    ```
  </Accordion>
</AccordionGroup>

## Querying Fee Information

```solidity theme={null}
// Get pending fee shares
uint256 pendingFees = folio.getPendingFeeShares();

// Get fee recipients
for (uint256 i = 0; i < recipientCount; i++) {
    (address recipient, uint96 portion) = folio.feeRecipients(i);
    // portion is in D18 format (1e18 = 100%)
}

// Get DAO fee configuration
(address daoRecipient, uint256 minFeeBps, uint256 maxFeeBps, uint256 daoSplit) = 
    folio.daoFeeRegistry().getFeeDetails(address(folio));
```

## Gas Optimization Tips

<AccordionGroup>
  <Accordion title="Batch Approvals">
    If you'll be minting multiple times, approve max once:

    ```solidity theme={null}
    IERC20(token).approve(address(folio), type(uint256).max);
    ```
  </Accordion>

  <Accordion title="Avoid Small Mints">
    Minting has fixed gas costs. Mint larger amounts less frequently:

    ```solidity theme={null}
    // Expensive: 10 mints of 1 share
    // Better: 1 mint of 10 shares
    ```
  </Accordion>

  <Accordion title="Combine with Fee Distribution">
    If fees are pending, `mint()` will trigger distribution automatically. Consider timing mints after fee accrual periods.
  </Accordion>
</AccordionGroup>

## Code Reference

* Mint function: `contracts/Folio.sol:441-476`
* Redeem function: `contracts/Folio.sol:482-508`
* Asset calculation: `contracts/Folio.sol:420-433`
* Fee distribution: `contracts/Folio.sol:521-551`

## Next Steps

<CardGroup cols={2}>
  <Card title="Auction Participation" icon="gavel" href="/guides/auction-participation">
    Provide liquidity by bidding on rebalancing auctions
  </Card>

  <Card title="Deploying Folio" icon="rocket" href="/guides/deploying-folio">
    Create your own Folio with custom parameters
  </Card>
</CardGroup>
