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

# What are Folios

> Learn about Folios, basket composition, and how minting and redemption work

## Overview

Folios are backed ERC20 tokens that represent portfolios of ERC20-compliant assets managed entirely onchain. They serve as a single source of truth for asset allocations, enabling composability of complex, multi-asset portfolios.

<Note>
  Folios are designed to be used in DeFi protocols as composable building blocks for multi-asset strategies.
</Note>

## What is a Folio?

A Folio is:

* **An ERC20 token** - Fully composable with other DeFi protocols
* **Backed by a basket** - Represents ownership of multiple underlying assets
* **Permissionlessly mintable/redeemable** - Anyone can mint or redeem at any time
* **Semi-permissioned rebalancing** - Governance controls rebalancing within timelock constraints

## Basket Composition

Every Folio maintains a basket of ERC20 tokens. The basket defines:

1. **Which tokens** are included in the portfolio
2. **How many of each token** back each Folio share
3. **Target allocations** during rebalancing

### Basket Units (BU)

Basket Units are the fundamental unit of account for a Folio. They define the target composition:

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

### Basket Weights

Each token in the basket has an associated weight that determines its proportion:

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

<Info>
  A typical usage defines BUs 1:1 with shares (1e18), though they can range from 0 to 1e27.
</Info>

## Minting Folios

Minting creates new Folio shares by depositing the required basket tokens.

### How Minting Works

1. **Calculate required assets** - Based on the current basket composition
2. **Transfer assets** - Caller transfers all required tokens to the Folio
3. **Mint shares** - Folio issues shares proportional to the deposit
4. **Apply fees** - Mint fee is deducted from shares issued

### Mint Function

```solidity theme={null}
/// @param shares {share} Amount of shares to mint
/// @param receiver Address to receive the minted shares
/// @param minSharesOut {share} Minimum shares after fees (slippage protection)
function mint(
    uint256 shares,
    address receiver,
    uint256 minSharesOut
) external returns (address[] memory _assets, uint256[] memory _amounts)
```

### Fee Distribution

Minting has three share portions:

1. **Receiver shares** - Goes to the minter
2. **DAO fee shares** - Goes to the protocol DAO (minimum 15 bps)
3. **Fee recipient shares** - Goes to Folio fee recipients

<CodeGroup>
  ```solidity Example: Mint 1000 Shares theme={null}
  // Approve tokens first
  token1.approve(address(folio), amount1);
  token2.approve(address(folio), amount2);

  // Mint with 1% slippage tolerance
  folio.mint(
      1000e18,           // shares to mint
      msg.sender,        // receiver
      990e18             // min shares out (1% slippage)
  );
  ```
</CodeGroup>

## Redeeming Folios

Redemption burns Folio shares and returns the proportional basket assets.

### How Redemption Works

1. **Burn shares** - Caller's shares are destroyed
2. **Calculate proportional assets** - Based on share percentage of total supply
3. **Transfer assets** - All basket tokens transferred to receiver

### Redeem Function

```solidity theme={null}
/// @param shares {share} Amount of shares to redeem
/// @param receiver Address to receive the assets
/// @param assets Assets to receive (must match basket exactly)
/// @param minAmountsOut {tok} Minimum amounts of each asset (slippage protection)
function redeem(
    uint256 shares,
    address receiver,
    address[] calldata assets,
    uint256[] calldata minAmountsOut
) external returns (uint256[] memory _amounts)
```

<Warning>
  The assets array must match the current basket exactly, in the same order.
</Warning>

<CodeGroup>
  ```solidity Example: Redeem 500 Shares theme={null}
  // Get current basket
  (address[] memory assets, ) = folio.totalAssets();

  // Set minimum amounts (slippage tolerance)
  uint256[] memory minAmounts = new uint256[](assets.length);
  minAmounts[0] = 95e18;  // minimum token1
  minAmounts[1] = 190e18; // minimum token2

  // Redeem shares
  folio.redeem(
      500e18,      // shares to redeem
      msg.sender,  // receiver
      assets,      // current basket
      minAmounts   // min amounts out
  );
  ```
</CodeGroup>

## Viewing Basket Assets

You can query the current basket composition at any time:

```solidity theme={null}
/// Get total assets in the Folio
/// @return _assets Array of token addresses
/// @return _amounts {tok} Array of token balances
function totalAssets() external view 
    returns (address[] memory _assets, uint256[] memory _amounts)

/// Convert shares to underlying assets
/// @param shares {share} Amount of shares
/// @param rounding Math.Rounding.Floor or Math.Rounding.Ceil
function toAssets(
    uint256 shares,
    Math.Rounding rounding
) external view 
    returns (address[] memory _assets, uint256[] memory _amounts)
```

## State Change Safety

<Warning>
  During trusted fill execution or reentrant calls, basket data may be unreliable.
</Warning>

Before relying on Folio state in external protocols, check:

```solidity theme={null}
/// @return syncStateChangeActive True if reentrant
/// @return asyncStateChangeActive True if async swap active
function stateChangeActive() external view 
    returns (bool syncStateChangeActive, bool asyncStateChangeActive)
```

Consumer protocols SHOULD call this and ensure both values are `false` before strongly relying on Folio state.

## Weird ERC20 Support

Folios support most ERC20 tokens but have restrictions:

| Token Type                     | Supported |
| ------------------------------ | --------- |
| Multiple Entrypoints           | ❌         |
| Pausable / Blocklist           | ❌         |
| Fee-on-transfer                | ❌         |
| ERC777 / Callback              | ❌         |
| Upward-rebasing                | ✅         |
| Downward-rebasing              | ✅         |
| Revert on zero-value transfers | ✅         |
| Flash mint                     | ✅         |
| Missing return values          | ✅         |
| No revert on failure           | ✅         |

<Info>
  Rebasing tokens are supported but may cause accounting discrepancies if rebasing is non-incremental.
</Info>
