Skip to main content

Overview

The Folio protocol uses an upgradeable proxy pattern with two contracts:
  1. FolioProxy: ERC1967-compliant transparent proxy
  2. FolioProxyAdmin: Admin contract managing upgrades with version control
This architecture enables protocol upgrades while maintaining state and user balances.

FolioProxyAdmin

The FolioProxyAdmin contract manages upgrades for Folio proxies with built-in version registry integration.

Features

  • Version-controlled upgrades
  • Ownership-based access control
  • Deprecation protection
  • Single admin per proxy

Constructor

FolioProxy.sol
address
Initial owner of the ProxyAdmin (typically a timelock)
address
FolioVersionRegistry address for version validation

Upgrade to Version

Upgrade a proxy to a specific version from the registry.
address
Address of the FolioProxy to upgrade
bytes32
Hash of the version to upgrade to
bytes
Calldata to execute after upgrade (typically for re-initialization)
FolioProxy.sol
The function will revert if:
  • Version is deprecated in the registry
  • Version doesn’t exist in the registry
  • Caller is not the owner

Version Validation

The upgrade process includes automatic validation:
Upgrade Flow

FolioProxy

The FolioProxy contract is a minimal transparent proxy implementation following ERC1967.

Features

  • Transparent proxy pattern
  • Immutable admin (cannot change after deployment)
  • Restricted admin interface
  • Fallback delegation to implementation

Constructor

FolioProxy.sol
address
Initial implementation address (Folio contract)
address
ProxyAdmin address (immutable after deployment)
The admin is stored in the ERC1967 admin slot and cannot be changed after deployment.

Proxy Behavior

The proxy uses a custom _fallback() implementation:
FolioProxy.sol

Access Control

address
Can only call upgradeToAndCall() - no access to implementation functions
address
All calls are delegated to the implementation contract

Upgrade Process

Step-by-Step Upgrade

  1. Deploy New Implementation
  2. Register Version (via FolioVersionRegistry)
  3. Prepare Upgrade Data (if needed)
  4. Execute Upgrade (via ProxyAdmin)

Governance Upgrade Example

Timelock Upgrade

Storage Layout

ERC1967 Storage Slots

The proxy follows ERC1967 standard storage slots:
Storage Slots
Never use these slots in the implementation contract to avoid storage collisions.

Security Considerations

Transparent Proxy Pattern

The transparent proxy ensures:
  • Admin cannot call implementation functions
  • Users cannot call admin functions
  • No function selector collisions

Admin Immutability

The admin address is set once during deployment and cannot be changed. This ensures:
  • Predictable upgrade permissions
  • No admin takeover attacks
  • Clear governance structure

Version Control

Integration with FolioVersionRegistry provides:
  • Deprecation Protection: Prevents upgrades to deprecated versions
  • Version Validation: Ensures implementation exists before upgrade
  • Audit Trail: All versions registered on-chain

Events

The proxy emits standard ERC1967 events:
event
Emitted when implementation is upgradedParameters:
  • implementation - New implementation address
event
Emitted when admin changes (only during deployment)Parameters:
  • previousAdmin - Previous admin (address(0) initially)
  • newAdmin - New admin address

Errors

error
Thrown when admin tries to call non-upgrade functions
error
Thrown when trying to upgrade to a deprecated version
error
Thrown when version doesn’t exist in registry

Best Practices

Upgrade Safety
  • Always test upgrades on testnet first
  • Use initialization functions for new storage variables
  • Follow the upgrade pattern for storage layout
  • Verify version registration before upgrade proposals
Admin Management
  • Use timelock contracts as ProxyAdmin owner
  • Implement multi-sig or governance for upgrade decisions
  • Monitor version registry for deprecations
  • Keep upgrade proposals transparent