Overview
The Folio protocol uses an upgradeable proxy pattern with two contracts:- FolioProxy: ERC1967-compliant transparent proxy
- FolioProxyAdmin: Admin contract managing upgrades with version control
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
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 functionsaddress
All calls are delegated to the implementation contract
Upgrade Process
Step-by-Step Upgrade
-
Deploy New Implementation
-
Register Version (via FolioVersionRegistry)
-
Prepare Upgrade Data (if needed)
-
Execute Upgrade (via ProxyAdmin)
Governance Upgrade Example
Timelock Upgrade
Storage Layout
ERC1967 Storage Slots
The proxy follows ERC1967 standard storage slots:Storage Slots
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