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

# Upgradeability

> Proxy pattern implementation and version registry for safe Folio upgrades

## Overview

Reserve Folio uses the ERC1967 proxy pattern to enable upgradeability while maintaining security and decentralization. All upgrades must go through the `FolioVersionRegistry` to ensure only approved implementations can be used.

## Proxy Architecture

### FolioProxy

Each Folio is deployed as a proxy that delegates calls to a shared implementation:

```solidity theme={null}
contract FolioProxy is ERC1967Proxy {
    constructor(address _logic, address _admin) 
        ERC1967Proxy(_logic, "") 
    {
        ERC1967Utils.changeAdmin(_admin);
    }
}
```

**Key characteristics:**

* Uses ERC1967 storage slots to avoid collisions
* Admin can only call `upgradeToAndCall()`
* All other calls are delegated to the implementation
* Follows transparent proxy pattern

### FolioProxyAdmin

The admin contract validates upgrades against the version registry:

```solidity theme={null}
function upgradeToVersion(
    address proxyTarget,
    bytes32 versionHash,
    bytes memory data
) external onlyOwner {
    IFolioVersionRegistry folioRegistry = IFolioVersionRegistry(versionRegistry);
    
    // Verify version is approved and not deprecated
    require(!folioRegistry.isDeprecated(versionHash), VersionDeprecated());
    require(
        address(folioRegistry.deployments(versionHash)) != address(0),
        InvalidVersion()
    );
    
    // Get approved implementation
    address folioImpl = folioRegistry.getImplementationForVersion(versionHash);
    
    // Execute upgrade
    ITransparentUpgradeableProxy(proxyTarget).upgradeToAndCall(folioImpl, data);
}
```

## Version Registry

### Registration

The DAO registers new Folio versions through `FolioVersionRegistry`:

```solidity theme={null}
function registerVersion(IFolioDeployer folioDeployer) external {
    require(roleRegistry.isOwner(msg.sender), InvalidCaller());
    
    string memory version = Versioned(address(folioDeployer)).version();
    bytes32 versionHash = keccak256(abi.encodePacked(version));
    
    require(
        address(deployments[versionHash]) == address(0),
        InvalidRegistration()
    );
    
    deployments[versionHash] = folioDeployer;
    latestVersion = versionHash;
    
    emit VersionRegistered(versionHash, folioDeployer);
}
```

### Deprecation

Versions can be marked deprecated by the DAO or emergency council:

```solidity theme={null}
function deprecateVersion(bytes32 versionHash) external {
    require(
        roleRegistry.isOwnerOrEmergencyCouncil(msg.sender),
        InvalidCaller()
    );
    
    require(!isDeprecated[versionHash], AlreadyDeprecated());
    
    isDeprecated[versionHash] = true;
    
    emit VersionDeprecated(versionHash);
}
```

<Warning>
  Deprecated versions cannot be upgraded to, but existing Folios running deprecated versions continue to function. Folio owners should upgrade to the latest version when deprecations occur.
</Warning>

## Upgrade Process

### 1. DAO Registers New Version

```solidity theme={null}
// Deploy new FolioDeployer with updated implementation
FolioDeployer newDeployer = new FolioDeployer(
    newFolioImpl,
    daoFeeRegistry,
    trustedFillerRegistry,
    roleRegistry
);

// Register through governance
versionRegistry.registerVersion(newDeployer);
```

### 2. Folio Admin Proposes Upgrade

```solidity theme={null}
// Calculate version hash
string memory version = "5.0.0";
bytes32 versionHash = keccak256(abi.encodePacked(version));

// Prepare upgrade data (if needed)
bytes memory upgradeData = "";

// Submit governance proposal
governor.propose(
    targets,    // [proxyAdmin]
    values,     // [0]
    calldatas,  // [upgradeToVersion(folio, versionHash, upgradeData)]
    "Upgrade Folio to v5.0.0"
);
```

### 3. Governance Approval

```solidity theme={null}
// After timelock delay, execute upgrade
proxyAdmin.upgradeToVersion(
    address(folioProxy),
    versionHash,
    upgradeData
);
```

### 4. Post-Upgrade Verification

```solidity theme={null}
// Verify new implementation
address newImpl = ERC1967Utils.getImplementation(address(folioProxy));
assert(newImpl == expectedNewImplementation);

// Verify version string
string memory currentVersion = Versioned(address(folio)).version();
assert(keccak256(bytes(currentVersion)) == versionHash);
```

## Storage Layout

Folio uses OpenZeppelin's upgradeable contracts with careful storage management:

```solidity theme={null}
contract Folio is
    Initializable,
    ERC20Upgradeable,
    AccessControlEnumerableUpgradeable,
    ReentrancyGuardUpgradeable,
    Versioned
{
    // Storage slots follow upgrade-safe patterns:
    
    // === 1.0.0 ===
    IFolioDAOFeeRegistry public daoFeeRegistry;
    string public mandate;
    EnumerableSet.AddressSet private basket;
    // ...
    
    // === 2.0.0 ===
    mapping(uint256 => AuctionDetails) private auctionDetails;
    // ...
    
    // === 3.0.0 ===
    ITrustedFillerRegistry public trustedFillerRegistry;
    bool public trustedFillerEnabled;
    // ...
    
    // === 4.0.0 ===
    RebalanceControl public rebalanceControl;
    Rebalance private rebalance;
    // ...
    
    // === 5.0.0 ===
    bool public bidsEnabled;
    
    // === 6.0.0 ===
    bool public tradeAllowlistEnabled;
    EnumerableSet.AddressSet private tradeTokenAllowlist;
    uint256 public folioFeeForSelf;
}
```

**Storage safety rules:**

* Never remove or reorder existing storage variables
* Only append new variables at the end
* Use storage gaps for future expansion (if needed)
* Mark deprecated storage with `_DEPRECATED` suffix

## Version Strings

Folio versions follow semantic versioning:

```solidity theme={null}
abstract contract Versioned {
    function version() external pure virtual returns (string memory) {
        return "6.0.0";  // major.minor.patch
    }
}
```

**Version components:**

* **Major**: Breaking storage layout changes
* **Minor**: New features, backward compatible
* **Patch**: Bug fixes, no storage changes

## Querying Version Information

### Current Folio Version

```solidity theme={null}
string memory currentVersion = Versioned(address(folio)).version();
// Returns: "6.0.0"
```

### Latest Available Version

```solidity theme={null}
(
    bytes32 versionHash,
    string memory version,
    IFolioDeployer deployer,
    bool deprecated
) = versionRegistry.getLatestVersion();

if (!deprecated) {
    // Safe to upgrade to this version
}
```

### Check Version Status

```solidity theme={null}
bytes32 versionHash = keccak256(abi.encodePacked("5.0.0"));

// Check if deprecated
bool isDeprecated = versionRegistry.isDeprecated(versionHash);

// Get deployer for version
IFolioDeployer deployer = versionRegistry.deployments(versionHash);
if (address(deployer) != address(0)) {
    // Version exists
}
```

## Security Considerations

### Access Control

* **Version registration**: Only DAO owner
* **Version deprecation**: DAO owner or emergency council
* **Folio upgrades**: Folio's `DEFAULT_ADMIN_ROLE` (typically governance timelock)

### Upgrade Validation

```solidity theme={null}
// ProxyAdmin enforces:
1. Version must be registered in version registry
2. Version must not be deprecated
3. Implementation address must be non-zero
4. Caller must be proxy admin owner
```

### Time Delays

Upgrades typically go through governance timelocks:

```solidity theme={null}
// Example: 2-day minimum delay
timelock.queueTransaction(
    target: proxyAdmin,
    value: 0,
    signature: "upgradeToVersion(address,bytes32,bytes)",
    data: abi.encode(folio, versionHash, upgradeData),
    eta: block.timestamp + 2 days
);
```

<Warning>
  Never skip timelock delays for upgrades. This gives users time to exit if they disagree with the upgrade.
</Warning>

## Deployment Architecture

```
FolioVersionRegistry
    ↓ (registers)
FolioDeployer (per version)
    ↓ (deploys)
[FolioProxy → FolioImplementation]
    ↑
    | (upgrades via)
    |
FolioProxyAdmin
    ↑
    | (validates with)
    |
FolioVersionRegistry
```

### Components

1. **FolioVersionRegistry**: Central registry of approved versions (1 per ecosystem)
2. **FolioDeployer**: Version-specific deployer (1 per version)
3. **FolioImplementation**: Shared logic contract (1 per version)
4. **FolioProxy**: Individual Folio proxy (1 per Folio)
5. **FolioProxyAdmin**: Upgrade executor with registry validation (1 per Folio)

## Example: Full Upgrade Flow

```solidity theme={null}
// 1. DAO deploys new version
Folio newImpl = new Folio();
FolioDeployer newDeployer = new FolioDeployer(
    address(newImpl),
    daoFeeRegistry,
    trustedFillerRegistry,
    roleRegistry
);

// 2. Register version
versionRegistry.registerVersion(newDeployer);

// 3. Folio governance proposes upgrade
string memory version = newImpl.version();
bytes32 versionHash = keccak256(abi.encodePacked(version));

governor.propose(
    [address(proxyAdmin)],
    [0],
    [abi.encodeCall(
        proxyAdmin.upgradeToVersion,
        (address(folio), versionHash, "")
    )],
    "Upgrade to 7.0.0: Add feature X"
);

// 4. After voting + timelock, execute
governor.execute(proposalId);

// 5. Verify upgrade
assert(keccak256(bytes(folio.version())) == versionHash);
```

## Related

* [Governance](/concepts/governance)
* [Security Considerations](/advanced/security)
* [Deployment Guide](/guides/deploying-folio)
